From f364b956fcfacfb23badd77f5899ff9c42e1d2d2 Mon Sep 17 00:00:00 2001 From: Bryan Smith Date: Mon, 4 Feb 2019 18:55:06 -0500 Subject: [PATCH 01/82] Add [total_toolchanges] placeholder for filename and custom gcode sections. --- src/libslic3r/GCode.cpp | 8 ++++++++ src/libslic3r/Print.cpp | 3 ++- src/libslic3r/Print.hpp | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c42669de0d..6dc63c2497 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -726,6 +726,12 @@ void GCode::_do_export(Print &print, FILE *file) _writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag); } + //Hold total number of print toolchanges + int m_total_toolchanges = 1; + m_total_toolchanges = print.wipe_tower_data().number_of_toolchanges; + //Check for negative toolchanges (probably single extruder mode) and set to 1. + m_total_toolchanges = (print.wipe_tower_data().number_of_toolchanges < 0) ? 1 : print.wipe_tower_data().number_of_toolchanges; + // Prepare the helper object for replacing placeholders in custom G-code and output filename. m_placeholder_parser = print.placeholder_parser(); m_placeholder_parser.update_timestamp(); @@ -788,6 +794,7 @@ void GCode::_do_export(Print &print, FILE *file) // For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided. m_placeholder_parser.set("has_wipe_tower", has_wipe_tower); m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming); + m_placeholder_parser.set("total_toolchanges", m_total_toolchanges); std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id); // Set bed temperature if the start G-code does not contain any bed temp control G-codes. this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true); @@ -1057,6 +1064,7 @@ void GCode::_do_export(Print &print, FILE *file) print.m_print_statistics.clear(); print.m_print_statistics.estimated_normal_print_time = m_normal_time_estimator.get_time_dhms(); print.m_print_statistics.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A"; + print.m_print_statistics.total_toolchanges = m_total_toolchanges; std::vector extruders = m_writer.extruders(); if (! extruders.empty()) { std::pair out_filament_used_mm ("; filament used [mm] = ", 0); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index f9129f15a1..69b4d8129d 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1956,6 +1956,7 @@ DynamicConfig PrintStatistics::config() const config.set_key_value("used_filament", new ConfigOptionFloat (this->total_used_filament / 1000.)); config.set_key_value("extruded_volume", new ConfigOptionFloat (this->total_extruded_volume)); config.set_key_value("total_cost", new ConfigOptionFloat (this->total_cost)); + config.set_key_value("total_toolchanges", new ConfigOptionInt(this->total_toolchanges)); config.set_key_value("total_weight", new ConfigOptionFloat (this->total_weight)); config.set_key_value("total_wipe_tower_cost", new ConfigOptionFloat (this->total_wipe_tower_cost)); config.set_key_value("total_wipe_tower_filament", new ConfigOptionFloat (this->total_wipe_tower_filament)); @@ -1968,7 +1969,7 @@ DynamicConfig PrintStatistics::placeholders() for (const std::string &key : { "print_time", "normal_print_time", "silent_print_time", "used_filament", "extruded_volume", "total_cost", "total_weight", - "total_wipe_tower_cost", "total_wipe_tower_filament"}) + "total_toolchanges", "total_wipe_tower_cost", "total_wipe_tower_filament"}) config.set_key_value(key, new ConfigOptionString(std::string("{") + key + "}")); return config; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 53d6d692db..2326366a0f 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -241,6 +241,7 @@ struct PrintStatistics double total_used_filament; double total_extruded_volume; double total_cost; + int total_toolchanges; double total_weight; double total_wipe_tower_cost; double total_wipe_tower_filament; @@ -259,6 +260,7 @@ struct PrintStatistics total_used_filament = 0.; total_extruded_volume = 0.; total_cost = 0.; + total_toolchanges = 0; total_weight = 0.; total_wipe_tower_cost = 0.; total_wipe_tower_filament = 0.; From 0ea6f895c5edcd1da1e7a5c6baaecf74f9b9890c Mon Sep 17 00:00:00 2001 From: Bryan Smith Date: Mon, 4 Feb 2019 20:52:38 -0500 Subject: [PATCH 02/82] Write the total toolchanges statistic to the end of the GCODE file like the other statistics. --- src/libslic3r/GCode.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6dc63c2497..00a4e801af 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1114,6 +1114,7 @@ void GCode::_do_export(Print &print, FILE *file) } _write_format(file, "; total filament used [g] = %.1lf\n", print.m_print_statistics.total_weight); _write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost); + _write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges); _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str()); if (m_silent_time_estimator_enabled) _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str()); From bd15efd17ace02d61b2e5b03af4291a32adf3fb3 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 22 Oct 2019 09:58:32 +0200 Subject: [PATCH 03/82] Fix qhull compilation on Mac --- deps/deps-unix-common.cmake | 6 +- deps/deps-windows.cmake | 6 +- deps/{igl-fixes.patch => igl-mods.patch} | 0 deps/qhull-mods.patch | 144 ++++++----------------- 4 files changed, 42 insertions(+), 114 deletions(-) rename deps/{igl-fixes.patch => igl-mods.patch} (100%) diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index 6e559d05a3..8f3af38511 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -53,8 +53,8 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz" - URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78 + URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -87,6 +87,6 @@ ExternalProject_Add(dep_libigl -DLIBIGL_WITH_TETGEN=OFF -DLIBIGL_WITH_TRIANGLE=OFF -DLIBIGL_WITH_XML=OFF - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch + PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch ) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 85013fbddd..6ecd5c0df6 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -238,8 +238,8 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz" - URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78 + URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -300,7 +300,7 @@ ExternalProject_Add(dep_libigl -DLIBIGL_WITH_XML=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_DEBUG_POSTFIX=d - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch + PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) diff --git a/deps/igl-fixes.patch b/deps/igl-mods.patch similarity index 100% rename from deps/igl-fixes.patch rename to deps/igl-mods.patch diff --git a/deps/qhull-mods.patch b/deps/qhull-mods.patch index 94aeeca2f5..70f7be6a74 100644 --- a/deps/qhull-mods.patch +++ b/deps/qhull-mods.patch @@ -1,121 +1,49 @@ -From a31ae4781a4afa60e21c70e5b4ae784bcd447c8a Mon Sep 17 00:00:00 2001 +From 7f55a56b3d112f4dffbf21b1722f400c64bf03b1 Mon Sep 17 00:00:00 2001 From: tamasmeszaros -Date: Thu, 6 Jun 2019 15:41:43 +0200 -Subject: [PATCH] prusa-slicer changes +Date: Mon, 21 Oct 2019 16:52:04 +0200 +Subject: [PATCH] Fix the build on macOS --- - CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++--- - Config.cmake.in | 2 ++ - src/libqhull_r/qhull_r-exports.def | 2 ++ - src/libqhull_r/user_r.h | 2 +- - 4 files changed, 46 insertions(+), 4 deletions(-) - create mode 100644 Config.cmake.in + CMakeLists.txt | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt -index 59dff41..20c2ec5 100644 +index 07d3da2..14df8e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -61,7 +61,7 @@ - # $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $ +@@ -626,18 +626,18 @@ install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets + include(CMakePackageConfigHelpers) - project(qhull) --cmake_minimum_required(VERSION 2.6) -+cmake_minimum_required(VERSION 3.0) + write_basic_package_version_file( +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake" + VERSION ${qhull_VERSION} + COMPATIBILITY AnyNewerVersion + ) - # Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri - set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c -@@ -610,10 +610,48 @@ add_test(NAME user_eg3 - # Define install - # --------------------------------------- + export(EXPORT QhullTargets +- FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake" ++ FILE "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullTargets.cmake" + NAMESPACE Qhull:: + ) --install(TARGETS ${qhull_TARGETS_INSTALL} -+install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} -- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) -+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -+ INCLUDES DESTINATION include) -+ -+include(CMakePackageConfigHelpers) -+ -+write_basic_package_version_file( -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" -+ VERSION ${qhull_VERSION} -+ COMPATIBILITY AnyNewerVersion -+) -+ -+export(EXPORT QhullTargets -+ FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake" -+ NAMESPACE Qhull:: -+) -+ -+configure_file(Config.cmake.in -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" -+ @ONLY -+) -+ -+set(ConfigPackageLocation lib/cmake/Qhull) -+install(EXPORT QhullTargets -+ FILE -+ QhullTargets.cmake -+ NAMESPACE -+ Qhull:: -+ DESTINATION -+ ${ConfigPackageLocation} -+) -+install( -+ FILES -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" -+ DESTINATION -+ ${ConfigPackageLocation} -+ COMPONENT -+ Devel -+) + configure_file(${PROJECT_SOURCE_DIR}/build/config.cmake.in +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake" + @ONLY + ) - install(FILES ${libqhull_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull) - install(FILES ${libqhull_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull) -diff --git a/Config.cmake.in b/Config.cmake.in -new file mode 100644 -index 0000000..bc92bfe ---- /dev/null -+++ b/Config.cmake.in -@@ -0,0 +1,2 @@ -+include("${CMAKE_CURRENT_LIST_DIR}/QhullTargets.cmake") -+ -diff --git a/src/libqhull_r/qhull_r-exports.def b/src/libqhull_r/qhull_r-exports.def -index 325d57c..72f6ad0 100644 ---- a/src/libqhull_r/qhull_r-exports.def -+++ b/src/libqhull_r/qhull_r-exports.def -@@ -185,6 +185,7 @@ qh_memsetup - qh_memsize - qh_memstatistics - qh_memtotal -+qh_memcheck - qh_merge_degenredundant - qh_merge_nonconvex - qh_mergecycle -@@ -372,6 +373,7 @@ qh_settruncate - qh_setunique - qh_setvoronoi_all - qh_setzero -+qh_setendpointer - qh_sharpnewfacets - qh_skipfacet - qh_skipfilename -diff --git a/src/libqhull_r/user_r.h b/src/libqhull_r/user_r.h -index fc105b9..7cca65a 100644 ---- a/src/libqhull_r/user_r.h -+++ b/src/libqhull_r/user_r.h -@@ -139,7 +139,7 @@ Code flags -- - REALfloat = 1 all numbers are 'float' type - = 0 all numbers are 'double' type - */ --#define REALfloat 0 -+#define REALfloat 1 - - #if (REALfloat == 1) - #define realT float +@@ -652,8 +652,8 @@ install(EXPORT QhullTargets + ) + install( + FILES +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake" + DESTINATION + ${ConfigPackageLocation} + COMPONENT -- -2.16.2.windows.1 +2.17.1 From 0d89fd84db41e582381a310904765b4f37aacfdb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 22 Oct 2019 10:26:51 +0200 Subject: [PATCH 04/82] Fixed a case when (under OSX) after some manipulation with an object or a part and then add some setting from 3dScene, "Revert button(s)" are still appear(s) in right panel --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 0b3f2b098d..4ecab8a0f1 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -632,7 +632,11 @@ void ObjectManipulation::update_reset_buttons_visibility() show_drop_to_bed = (std::abs(min_z) > EPSILON); } - wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed]{ + wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed] { + // There is a case (under OSX), when this function is called after the Manipulation panel is hidden + // So, let check if Manipulation panel is still shown for this moment + if (!this->IsShown()) + return; m_reset_rotation_button->Show(show_rotation); m_reset_scale_button->Show(show_scale); m_drop_to_bed_button->Show(show_drop_to_bed); From 8dea6c2fd8fb31502a6c5ab38298a046c436b8d9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 22 Oct 2019 12:39:22 +0200 Subject: [PATCH 05/82] Fixed a crash with the following repro: 1) Start PrusaSlicer 2) Select printer: Original Prusa i3 MK2.5 3) Load any stl file 4) In Printer Settings turn on "Support stealth mode" 5) Press "Slice now" -> crash All the "machine_XXXXX" vectors in the print config contain a single value instead of two leading to a vector subscript out of range when read into GCode::_do_export() --- src/libslic3r/GCode.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3a72657c30..26d9c90f8a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -778,22 +778,26 @@ void GCode::_do_export(Print &print, FILE *file) { m_silent_time_estimator.reset(); m_silent_time_estimator.set_dialect(print.config().gcode_flavor); - m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values[1]); - m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values[1]); - m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values[1]); - m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values[1]); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values[1]); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values[1]); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values[1]); - m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values[1]); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values[1]); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values[1]); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values[1]); - m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values[1]); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values[1]); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values[1]); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values[1]); - m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values[1]); + /* "Stealth mode" values can be just a copy of "normal mode" values + * (when they aren't input for a printer preset). + * Thus, use back value from values, instead of second one, which could be absent + */ + m_silent_time_estimator.set_max_acceleration((float)print.config().machine_max_acceleration_extruding.values.back()); + m_silent_time_estimator.set_retract_acceleration((float)print.config().machine_max_acceleration_retracting.values.back()); + m_silent_time_estimator.set_minimum_feedrate((float)print.config().machine_min_extruding_rate.values.back()); + m_silent_time_estimator.set_minimum_travel_feedrate((float)print.config().machine_min_travel_rate.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, (float)print.config().machine_max_acceleration_x.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, (float)print.config().machine_max_acceleration_y.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, (float)print.config().machine_max_acceleration_z.values.back()); + m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, (float)print.config().machine_max_acceleration_e.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, (float)print.config().machine_max_feedrate_x.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, (float)print.config().machine_max_feedrate_y.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, (float)print.config().machine_max_feedrate_z.values.back()); + m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, (float)print.config().machine_max_feedrate_e.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, (float)print.config().machine_max_jerk_x.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, (float)print.config().machine_max_jerk_y.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, (float)print.config().machine_max_jerk_z.values.back()); + m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, (float)print.config().machine_max_jerk_e.values.back()); if (print.config().single_extruder_multi_material) { // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they // are considered to be active for the single extruder multi-material printers only. From 32a42f28088edd6663379f0bcde8fcb50d6016f5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 22 Oct 2019 16:02:31 +0200 Subject: [PATCH 06/82] Added tech ENABLE_THUMBNAIL_GENERATOR -> 1st installment of generation of thumbnail from plater (WIP) --- src/libslic3r/CMakeLists.txt | 2 + src/libslic3r/GCode.cpp | 5 ++ src/libslic3r/GCode/ThumbnailData.cpp | 31 +++++++++ src/libslic3r/GCode/ThumbnailData.hpp | 25 +++++++ src/libslic3r/Technologies.hpp | 10 +++ src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/GLCanvas3D.hpp | 7 ++ src/slic3r/GUI/Plater.cpp | 15 +++++ src/slic3r/GUI/ThumbnailGenerator.cpp | 97 +++++++++++++++++++++++++++ src/slic3r/GUI/ThumbnailGenerator.hpp | 37 ++++++++++ 10 files changed, 231 insertions(+) create mode 100644 src/libslic3r/GCode/ThumbnailData.cpp create mode 100644 src/libslic3r/GCode/ThumbnailData.hpp create mode 100644 src/slic3r/GUI/ThumbnailGenerator.cpp create mode 100644 src/slic3r/GUI/ThumbnailGenerator.hpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index cbaa24e9ca..f7881e5aca 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -71,6 +71,8 @@ add_library(libslic3r STATIC Format/STL.hpp GCode/Analyzer.cpp GCode/Analyzer.hpp + GCode/ThumbnailData.cpp + GCode/ThumbnailData.hpp GCode/CoolingBuffer.cpp GCode/CoolingBuffer.hpp GCode/PostProcessor.cpp diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3a72657c30..fa71ac7969 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -945,6 +945,11 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Write some terse information on the slicing parameters. const PrintObject *first_object = print.objects().front(); const double layer_height = first_object->config().layer_height.value; diff --git a/src/libslic3r/GCode/ThumbnailData.cpp b/src/libslic3r/GCode/ThumbnailData.cpp new file mode 100644 index 0000000000..17ccbdeb6e --- /dev/null +++ b/src/libslic3r/GCode/ThumbnailData.cpp @@ -0,0 +1,31 @@ +#include "libslic3r/libslic3r.h" +#include "ThumbnailData.hpp" + +#if ENABLE_THUMBNAIL_GENERATOR + +namespace Slic3r { + +void ThumbnailData::set(unsigned int w, unsigned int h) +{ + if (!pixels.empty()) + reset(); + + if ((w == 0) || (h == 0)) + return; + + width = w; + height = h; + // defaults to white texture + pixels = std::vector(width * height * 4, 255); +} + +void ThumbnailData::reset() +{ + width = 0; + height = 0; + pixels.clear(); +} + +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR \ No newline at end of file diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp new file mode 100644 index 0000000000..193068ebe7 --- /dev/null +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -0,0 +1,25 @@ +#ifndef slic3r_ThumbnailData_hpp_ +#define slic3r_ThumbnailData_hpp_ + +#if ENABLE_THUMBNAIL_GENERATOR + +#include + +namespace Slic3r { + +struct ThumbnailData +{ + unsigned int width; + unsigned int height; + std::vector pixels; + + ThumbnailData() { reset(); } + void set(unsigned int w, unsigned int h); + void reset(); +}; + +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR + +#endif // slic3r_ThumbnailData_hpp_ \ No newline at end of file diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 51d0920946..40e989bb2b 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -32,4 +32,14 @@ #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING (0 && ENABLE_1_42_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//==================== +// 2.2.0.alpha1 techs +//==================== +#define ENABLE_2_2_0_ALPHA1 1 + +// Enable thumbnail generator +#define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #endif // _technologies_h_ diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 17b76e6296..0b2dd67020 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -136,6 +136,8 @@ set(SLIC3R_GUI_SOURCES GUI/ProgressStatusBar.cpp GUI/PrintHostDialogs.cpp GUI/PrintHostDialogs.hpp + GUI/ThumbnailGenerator.cpp + GUI/ThumbnailGenerator.hpp Utils/Http.cpp Utils/Http.hpp Utils/FixModelByWin10.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2c2676ae77..2e7fc2d772 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -446,6 +446,13 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + const GLVolumeCollection& get_volumes() const { return m_volumes; } +// GLVolumeCollection& get_volumes() { return m_volumes; } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool init(); void post_event(wxEvent &&event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cca164ca30..4c44cce753 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -62,6 +62,11 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "ThumbnailGenerator.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -1373,6 +1378,11 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + ThumbnailGenerator thumbnail_generator; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -3060,6 +3070,11 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) return; if (! output_path.empty()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + thumbnail_generator.render_to_png_file(*view3D->get_canvas3d(), "C:/prusa/test/test.png", 256, 256, false); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.schedule_export(output_path.string()); } else { background_process.schedule_upload(std::move(upload_job)); diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp new file mode 100644 index 0000000000..db823cc0b5 --- /dev/null +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -0,0 +1,97 @@ +#include "libslic3r/libslic3r.h" +#include "ThumbnailGenerator.hpp" + +#if ENABLE_THUMBNAIL_GENERATOR + +#include "GLCanvas3D.hpp" +#include "3DScene.hpp" + +#include + +namespace Slic3r { +namespace GUI { + +void ThumbnailGenerator::reset() +{ + m_data.reset(); +} + +bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only) +{ + m_data.set(w, h); + render(canvas, printable_only); + + wxImage image(m_data.width, m_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < m_data.height; ++r) + { + unsigned int rr = (m_data.height - 1 - r) * m_data.width; + for (unsigned int c = 0; c < m_data.width; ++c) + { + unsigned char* px = m_data.pixels.data() + 4 * (rr + c); +// unsigned char* px = m_data.pixels.data() + 4 * (r * m_data.width + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile(filename, wxBITMAP_TYPE_PNG); + + return true; +} + +void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) +{ + const GLVolumeCollection& volumes = canvas.get_volumes(); + + std::vector visible_volumes; + + for (const GLVolume* vol : volumes.volumes) + { + if (!printable_only || vol->printable) + visible_volumes.push_back(vol); + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, m_data.width, m_data.height); + camera.apply_viewport(0, 0, m_data.width, m_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + render_objects(visible_volumes); + glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); +} + +void ThumbnailGenerator::render_objects(const std::vector& volumes) const +{ + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : volumes) + { + glsafe(::glColor3fv(vol->printable ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); +} + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp new file mode 100644 index 0000000000..1c3aef76cb --- /dev/null +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -0,0 +1,37 @@ +#ifndef slic3r_GUI_ThumbnailGenerator_hpp_ +#define slic3r_GUI_ThumbnailGenerator_hpp_ + +#if ENABLE_THUMBNAIL_GENERATOR + +#include "../libslic3r/GCode/ThumbnailData.hpp" + +#include + +namespace Slic3r { + class GLVolume; +namespace GUI { + class GLCanvas3D; + + class ThumbnailGenerator + { + ThumbnailData m_data; + + public: + ThumbnailGenerator() { reset(); } + + void reset(); + + bool render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only); + + private: + void render(const GLCanvas3D& canvas, bool printable_only); + void render_objects(const std::vector& volumes) const; + }; + +} // namespace GUI +} // namespace Slic3r + +#endif // ENABLE_THUMBNAIL_GENERATOR + +#endif // slic3r_GUI_ThumbnailGenerator_hpp_ + From 9f9a40100f13a0b8e8b0703a9b034184c47244ed Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 22 Oct 2019 16:32:21 +0200 Subject: [PATCH 07/82] Solve build fail in RelWithDebInfo config with several imported targets. --- CMakeLists.txt | 27 ++++++++++++++++++++------- src/qhull/CMakeLists.txt | 4 +++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96752abb87..2d620f8693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -255,7 +255,8 @@ if(NOT WIN32) # boost::process was introduced first in version 1.64.0 set(MINIMUM_BOOST_VERSION "1.64.0") endif() -find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS system filesystem thread log locale regex) +set(_boost_components "system;filesystem;thread;log;locale;regex") +find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) add_library(boost_libs INTERFACE) add_library(boost_headeronly INTERFACE) @@ -269,23 +270,35 @@ if(NOT SLIC3R_STATIC) target_compile_definitions(boost_headeronly INTERFACE BOOST_LOG_DYN_LINK) endif() +function(slic3r_remap_configs targets from_Cfg to_Cfg) + string(TOUPPER ${from_Cfg} from_CFG) + string(TOLOWER ${from_Cfg} from_cfg) + + message(STATUS "remapping targets: ${targets}") + foreach(tgt ${targets}) + if(TARGET ${tgt}) + set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) + message(STATUS "remap ${tgt} from ${from_Cfg} to ${to_Cfg}") + endif() + endforeach() +endfunction() + if(TARGET Boost::system) message(STATUS "Boost::boost exists") target_link_libraries(boost_headeronly INTERFACE Boost::boost) + list(TRANSFORM _boost_components PREPEND Boost:: OUTPUT_VARIABLE _boost_targets) target_link_libraries(boost_libs INTERFACE boost_headeronly # includes the custom compile definitions as well - Boost::system - Boost::filesystem - Boost::thread - Boost::log - Boost::locale - Boost::regex + ${_boost_targets} ) + slic3r_remap_configs("${_boost_targets}" RelWithDebInfo Release) else() target_include_directories(boost_headeronly INTERFACE ${Boost_INCLUDE_DIRS}) target_link_libraries(boost_libs INTERFACE boost_headeronly ${Boost_LIBRARIES}) endif() + + # Find and configure intel-tbb if(SLIC3R_STATIC) set(TBB_STATIC 1) diff --git a/src/qhull/CMakeLists.txt b/src/qhull/CMakeLists.txt index 9ca0bdff23..ab9aba9afa 100644 --- a/src/qhull/CMakeLists.txt +++ b/src/qhull/CMakeLists.txt @@ -18,11 +18,13 @@ if(Qhull_FOUND) message(STATUS "Using qhull from system.") if(SLIC3R_STATIC) + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhullstatic_r" RelWithDebInfo Release) target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhullstatic_r) else() + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhull_r" RelWithDebInfo Release) target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhull_r) endif() - + else(Qhull_FOUND) project(qhull) From 7f0c4fafe6677c32dc4ae09d512f2ee2f242fa45 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 22 Oct 2019 16:42:40 +0200 Subject: [PATCH 08/82] Remove cmake debug messages --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d620f8693..31d2b7c8a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,11 +274,9 @@ function(slic3r_remap_configs targets from_Cfg to_Cfg) string(TOUPPER ${from_Cfg} from_CFG) string(TOLOWER ${from_Cfg} from_cfg) - message(STATUS "remapping targets: ${targets}") foreach(tgt ${targets}) if(TARGET ${tgt}) set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) - message(STATUS "remap ${tgt} from ${from_Cfg} to ${to_Cfg}") endif() endforeach() endfunction() From 8961e68f5ed2b2fe969c61cd06158c7384c9dbdb Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 22 Oct 2019 17:04:32 +0200 Subject: [PATCH 09/82] another cleanup --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31d2b7c8a5..dde5a51f3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,7 +272,6 @@ endif() function(slic3r_remap_configs targets from_Cfg to_Cfg) string(TOUPPER ${from_Cfg} from_CFG) - string(TOLOWER ${from_Cfg} from_cfg) foreach(tgt ${targets}) if(TARGET ${tgt}) From 4d1153c866bef9af7525ea4e1e7616b8e4acc115 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 23 Oct 2019 13:31:24 +0200 Subject: [PATCH 10/82] ENABLE_THUMBNAIL_GENERATOR -> WIP: Refactoring and preparation for adding thumbnails to exported gcode and 3mf files --- src/libslic3r/Format/3mf.cpp | 103 ++++++++++++++++++++ src/libslic3r/Format/3mf.hpp | 13 +++ src/libslic3r/GCode.cpp | 49 +++++++++- src/libslic3r/GCode.hpp | 21 ++++ src/libslic3r/GCode/ThumbnailData.cpp | 19 ++-- src/libslic3r/GCode/ThumbnailData.hpp | 2 + src/libslic3r/Print.cpp | 16 +++ src/libslic3r/Print.hpp | 13 +++ src/slic3r/GUI/BackgroundSlicingProcess.cpp | 12 ++- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 17 ++++ src/slic3r/GUI/GLCanvas3D.cpp | 6 ++ src/slic3r/GUI/Plater.cpp | 53 +++++++++- src/slic3r/GUI/Plater.hpp | 6 ++ src/slic3r/GUI/ThumbnailGenerator.cpp | 45 +++++---- src/slic3r/GUI/ThumbnailGenerator.hpp | 17 ++-- 15 files changed, 346 insertions(+), 46 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 47a8e52808..a981cca613 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3,6 +3,11 @@ #include "../Utils.hpp" #include "../GCode.hpp" #include "../Geometry.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "../GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "../I18N.hpp" @@ -40,6 +45,11 @@ const std::string MODEL_EXTENSION = ".model"; const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA const std::string CONTENT_TYPES_FILE = "[Content_Types].xml"; const std::string RELATIONSHIPS_FILE = "_rels/.rels"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config"; const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; @@ -1806,11 +1816,32 @@ namespace Slic3r { typedef std::map IdToObjectDataMap; public: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_content_types_file_to_archive(mz_zip_archive& archive); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_relationships_file_to_archive(mz_zip_archive& archive); bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data); bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets); @@ -1823,13 +1854,33 @@ namespace Slic3r { bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); }; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + { + clear_errors(); + return _save_model_to_file(filename, model, config, thumbnail); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) { clear_errors(); return _save_model_to_file(filename, model, config); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -1848,6 +1899,21 @@ namespace Slic3r { return false; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + if ((thumbnail != nullptr) && thumbnail->is_valid()) + { + // Adds the file Metadata/thumbnail.png. + if (!_add_thumbnail_file_to_archive(archive, *thumbnail)) + { + close_zip_writer(&archive); + boost::filesystem::remove(filename); + return false; + } + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Adds relationships file ("_rels/.rels"). // The content of this file is the same for each PrusaSlicer 3mf. // The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA. @@ -1941,6 +2007,11 @@ namespace Slic3r { stream << "\n"; stream << " \n"; stream << " \n"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + stream << " \n"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -1954,12 +2025,28 @@ namespace Slic3r { return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail) + { + // TODO -> add Metadata/thumbnail.png file containing thumbnail_data + + return true; + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool _3MF_Exporter::_add_relationships_file_to_archive(mz_zip_archive& archive) { std::stringstream stream; stream << "\n"; stream << "\n"; stream << " \n"; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + stream << " \n"; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2453,13 +2540,29 @@ namespace Slic3r { return res; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if ((path == nullptr) || (model == nullptr)) return false; _3MF_Exporter exporter; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + bool res = exporter.save_model_to_file(path, *model, config, thumbnail); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool res = exporter.save_model_to_file(path, *model, config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!res) exporter.log_errors(); diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index f387192ab5..0ce6eb742b 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -22,13 +22,26 @@ namespace Slic3r { class Model; class DynamicPrintConfig; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Load the content of a 3mf file into the given model and preset bundle. extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version); // Save the given model and the config data contained in the given Print into a 3mf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // namespace Slic3r diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2d14155a3a..13b417efad 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,6 +6,11 @@ #include "Geometry.hpp" #include "GCode/PrintExtents.hpp" #include "GCode/WipeTower.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "ShortestPath.hpp" #include "Utils.hpp" @@ -652,7 +657,15 @@ std::vector>> GCode::collec return layers_to_print; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_CLEAR(); @@ -678,7 +691,15 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ try { m_placeholder_parser_failed_templates.clear(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + this->_do_export(*print, file, thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->_do_export(*print, file); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fflush(file); if (ferror(file)) { fclose(file); @@ -742,7 +763,15 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::_do_export(Print &print, FILE *file) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_FUNC(); @@ -934,6 +963,21 @@ void GCode::_do_export(Print &print, FILE *file) // Write information on the generator. _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + // Write thumbnail + if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) + { + _write(file, "\n;\n; thumbnail begin\n"); + + // TODO -> export content of thumbnail_data.pixels + + _write(file, "; thumbnail end\n;\n\n"); + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Write notes (content of the Print Settings tab -> Notes) { std::list lines; @@ -949,11 +993,6 @@ void GCode::_do_export(Print &print, FILE *file) } print.throw_if_canceled(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // Write some terse information on the slicing parameters. const PrintObject *first_object = print.objects().front(); const double layer_height = first_object->config().layer_height.value; diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 45ff7eda65..4c5b92bf1c 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -30,6 +30,11 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class AvoidCrossingPerimeters { public: @@ -162,7 +167,15 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const ThumbnailData* thumbnail_data = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -190,7 +203,15 @@ public: static void append_full_config(const Print& print, std::string& str); protected: +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _do_export(Print &print, FILE *file); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif //ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Object and support extrusions of the same PrintObject at the same print_z. struct LayerToPrint diff --git a/src/libslic3r/GCode/ThumbnailData.cpp b/src/libslic3r/GCode/ThumbnailData.cpp index 17ccbdeb6e..80165916b5 100644 --- a/src/libslic3r/GCode/ThumbnailData.cpp +++ b/src/libslic3r/GCode/ThumbnailData.cpp @@ -7,16 +7,16 @@ namespace Slic3r { void ThumbnailData::set(unsigned int w, unsigned int h) { - if (!pixels.empty()) - reset(); - if ((w == 0) || (h == 0)) return; - width = w; - height = h; - // defaults to white texture - pixels = std::vector(width * height * 4, 255); + if ((width != w) || (height != h)) + { + width = w; + height = h; + // defaults to white texture + pixels = std::vector(width * height * 4, 255); + } } void ThumbnailData::reset() @@ -26,6 +26,11 @@ void ThumbnailData::reset() pixels.clear(); } +bool ThumbnailData::is_valid() const +{ + return (width != 0) && (height != 0) && ((unsigned int)pixels.size() == 4 * width * height); +} + } // namespace Slic3r #endif // ENABLE_THUMBNAIL_GENERATOR \ No newline at end of file diff --git a/src/libslic3r/GCode/ThumbnailData.hpp b/src/libslic3r/GCode/ThumbnailData.hpp index 193068ebe7..9823ffd31a 100644 --- a/src/libslic3r/GCode/ThumbnailData.hpp +++ b/src/libslic3r/GCode/ThumbnailData.hpp @@ -16,6 +16,8 @@ struct ThumbnailData ThumbnailData() { reset(); } void set(unsigned int w, unsigned int h); void reset(); + + bool is_valid() const; }; } // namespace Slic3r diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 88645df15b..742a2a960c 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1536,7 +1536,15 @@ void Print::process() // The export_gcode may die for various reasons (fails to process output_filename_format, // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // output everything to a G-code file // The following call may die if the output_filename_format template substitution fails. @@ -1553,7 +1561,15 @@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + gcode.do_export(this, path.c_str(), preview_data, thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ gcode.do_export(this, path.c_str(), preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 6d94a515f9..8dc54ee1dc 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -19,6 +19,11 @@ class PrintObject; class ModelObject; class GCode; class GCodePreviewData; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Print step IDs for keeping track of the print state. enum PrintStep { @@ -305,7 +310,15 @@ public: void process() override; // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data = nullptr); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // methods for handling state bool is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index a1db6884ee..9d53d60b25 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -82,8 +82,16 @@ void BackgroundSlicingProcess::process_fff() assert(m_print == m_fff_print); m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); - m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); - if (this->set_step_started(bspsGCodeFinalize)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { //FIXME localize the messages // Perform the final post-processing of the export path by applying the print statistics over the file name. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index cf5edd55f9..af20554dfb 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,6 +17,11 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Model; class SLAPrint; @@ -49,6 +54,12 @@ public: void set_fff_print(Print *print) { m_fff_print = print; } void set_sla_print(SLAPrint *print) { m_sla_print = print; } void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void set_thumbnail_data(const ThumbnailData* data) { m_thumbnail_data = data; } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished // and the background processing will transition into G-code export. // The wxCommandEvent is sent to the UI thread asynchronously without waiting for the event to be processed. @@ -151,6 +162,12 @@ private: SLAPrint *m_sla_print = nullptr; // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + // Data structure, used to write thumbnail into gcode. + const ThumbnailData *m_thumbnail_data = nullptr; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; // Output path provided by the user. The output path may be set even if the slicing is running, diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b472..4e72d15263 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2108,6 +2108,12 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re manip->set_dirty(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_THUMBNAIL_GENERATOR +// wxGetApp().plater()->generate_thumbnail(256, 256, true); +//#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // and force this canvas to be redrawn. m_dirty = true; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 4c44cce753..66fb72bbc2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1926,6 +1926,12 @@ struct Plater::priv bool can_mirror() const; bool can_reload_from_disk() const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void msw_rescale_object_menu(); // returns the path to project file with the given extension (none if extension == wxEmptyString) @@ -1993,6 +1999,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + background_process.set_thumbnail_data(&thumbnail_generator.get_data()); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); // Default printer technology for default config. @@ -3037,6 +3048,16 @@ bool Plater::priv::restart_background_process(unsigned int state) ( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) || (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + if ((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) + { + // force update of thumbnail data, so that they can be inserted into the exported gcode + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); + thumbnail_generator.save_to_png_file("C:/prusa/test/test.png"); + } +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3070,11 +3091,6 @@ void Plater::priv::export_gcode(fs::path output_path, PrintHostJob upload_job) return; if (! output_path.empty()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - thumbnail_generator.render_to_png_file(*view3D->get_canvas3d(), "C:/prusa/test/test.png", 256, 256, false); -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.schedule_export(output_path.string()); } else { background_process.schedule_upload(std::move(upload_job)); @@ -3604,6 +3620,15 @@ bool Plater::priv::init_object_menu() return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +{ + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Plater::priv::msw_rescale_object_menu() { for (MenuWithSeparators* menu : { &object_menu, &sla_object_menu, &part_menu, &default_menu }) @@ -4642,7 +4667,16 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); const std::string path_u8 = into_u8(path); wxBusyCursor wait; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + p->generate_thumbnail(128, 128, false); + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Success p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path)); p->set_project_filename(path); @@ -5139,6 +5173,15 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +{ + p->generate_thumbnail(w, h, printable_only); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Plater::msw_rescale() { p->preview->msw_rescale(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 00ceb89bc3..b14cff65a2 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,6 +240,12 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index db823cc0b5..a50c5541ca 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -3,9 +3,12 @@ #if ENABLE_THUMBNAIL_GENERATOR -#include "GLCanvas3D.hpp" +#include "Camera.hpp" #include "3DScene.hpp" +#include "GUI.hpp" +#include +#include #include namespace Slic3r { @@ -16,10 +19,18 @@ void ThumbnailGenerator::reset() m_data.reset(); } -bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only) +void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only) { + std::cout << "Generated thumbnail " << w << "x" << h << std::endl; + m_data.set(w, h); - render(canvas, printable_only); + render_and_store(volumes, printable_only); +} + +bool ThumbnailGenerator::save_to_png_file(const std::string& filename) +{ + if (!m_data.is_valid()) + return false; wxImage image(m_data.width, m_data.height); image.InitAlpha(); @@ -30,24 +41,26 @@ bool ThumbnailGenerator::render_to_png_file(const GLCanvas3D& canvas, const std: for (unsigned int c = 0; c < m_data.width; ++c) { unsigned char* px = m_data.pixels.data() + 4 * (rr + c); -// unsigned char* px = m_data.pixels.data() + 4 * (r * m_data.width + c); image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); image.SetAlpha((int)c, (int)r, px[3]); } } - image.SaveFile(filename, wxBITMAP_TYPE_PNG); + std::string path = filename; + if (!boost::iends_with(path, ".png")) + path = boost::filesystem::path(path).replace_extension(".png").string(); - return true; + return image.SaveFile(from_u8(path), wxBITMAP_TYPE_PNG); } -void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) +void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) { - const GLVolumeCollection& volumes = canvas.get_volumes(); + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; - std::vector visible_volumes; + GLVolumeConstPtrs visible_volumes; - for (const GLVolume* vol : volumes.volumes) + for (const GLVolume* vol : volumes) { if (!printable_only || vol->printable) visible_volumes.push_back(vol); @@ -69,19 +82,10 @@ void ThumbnailGenerator::render(const GLCanvas3D& canvas, bool printable_only) camera.apply_projection(box); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - render_objects(visible_volumes); - glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); -} - -void ThumbnailGenerator::render_objects(const std::vector& volumes) const -{ - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - glsafe(::glEnable(GL_LIGHTING)); glsafe(::glEnable(GL_DEPTH_TEST)); - for (const GLVolume* vol : volumes) + for (const GLVolume* vol : visible_volumes) { glsafe(::glColor3fv(vol->printable ? orange : gray)); vol->render(); @@ -89,6 +93,7 @@ void ThumbnailGenerator::render_objects(const std::vector& volu glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); } } // namespace GUI diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index 1c3aef76cb..e632106cd9 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -5,15 +5,15 @@ #include "../libslic3r/GCode/ThumbnailData.hpp" -#include - namespace Slic3r { class GLVolume; -namespace GUI { - class GLCanvas3D; + typedef std::vector GLVolumePtrs; + namespace GUI { class ThumbnailGenerator { + typedef std::vector GLVolumeConstPtrs; + ThumbnailData m_data; public: @@ -21,11 +21,14 @@ namespace GUI { void reset(); - bool render_to_png_file(const GLCanvas3D& canvas, const std::string& filename, unsigned int w, unsigned int h, bool printable_only); + void generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only); + + const ThumbnailData& get_data() const { return m_data; } + + bool save_to_png_file(const std::string& filename); private: - void render(const GLCanvas3D& canvas, bool printable_only); - void render_objects(const std::vector& volumes) const; + void render_and_store(const GLVolumePtrs& volumes, bool printable_only); }; } // namespace GUI From cf94482731746fda6bbd83c5aa5862105549c319 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 23 Oct 2019 15:07:41 +0200 Subject: [PATCH 11/82] Fix of Voronoi debug output. --- src/libslic3r/Geometry.cpp | 35 +++++++++++++++++------------------ src/libslic3r/Geometry.hpp | 4 +--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index e926b99979..46d7ef1543 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -663,7 +663,6 @@ namespace Voronoi { namespace Internal { typedef boost::polygon::point_data point_type; typedef boost::polygon::segment_data segment_type; typedef boost::polygon::rectangle_data rect_type; -// typedef voronoi_builder VB; typedef boost::polygon::voronoi_diagram VD; typedef VD::cell_type cell_type; typedef VD::cell_type::source_index_type source_index_type; @@ -710,15 +709,15 @@ namespace Voronoi { namespace Internal { if (cell1.contains_point() && cell2.contains_point()) { point_type p1 = retrieve_point(segments, cell1); point_type p2 = retrieve_point(segments, cell2); - origin.x((p1(0) + p2(0)) * 0.5); - origin.y((p1(1) + p2(1)) * 0.5); - direction.x(p1(1) - p2(1)); - direction.y(p2(0) - p1(0)); + origin.x((p1.x() + p2.x()) * 0.5); + origin.y((p1.y() + p2.y()) * 0.5); + direction.x(p1.y() - p2.y()); + direction.y(p2.x() - p1.x()); } else { origin = cell1.contains_segment() ? retrieve_point(segments, cell2) : retrieve_point(segments, cell1); segment_type segment = cell1.contains_segment() ? segments[cell1.source_index()] : segments[cell2.source_index()]; - coordinate_type dx = high(segment)(0) - low(segment)(0); - coordinate_type dy = high(segment)(1) - low(segment)(1); + coordinate_type dx = high(segment).x() - low(segment).x(); + coordinate_type dy = high(segment).y() - low(segment).y(); if ((low(segment) == origin) ^ cell1.contains_point()) { direction.x(dy); direction.y(-dx); @@ -727,19 +726,19 @@ namespace Voronoi { namespace Internal { direction.y(dx); } } - coordinate_type koef = bbox_max_size / (std::max)(fabs(direction(0)), fabs(direction(1))); + coordinate_type koef = bbox_max_size / (std::max)(fabs(direction.x()), fabs(direction.y())); if (edge.vertex0() == NULL) { clipped_edge->push_back(point_type( - origin(0) - direction(0) * koef, - origin(1) - direction(1) * koef)); + origin.x() - direction.x() * koef, + origin.y() - direction.y() * koef)); } else { clipped_edge->push_back( point_type(edge.vertex0()->x(), edge.vertex0()->y())); } if (edge.vertex1() == NULL) { clipped_edge->push_back(point_type( - origin(0) + direction(0) * koef, - origin(1) + direction(1) * koef)); + origin.x() + direction.x() * koef, + origin.y() + direction.y() * koef)); } else { clipped_edge->push_back( point_type(edge.vertex1()->x(), edge.vertex1()->y())); @@ -759,7 +758,7 @@ namespace Voronoi { namespace Internal { } /* namespace Internal */ } // namespace Voronoi -static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_diagram &vd, const ThickPolylines *polylines, const char *path) +static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ boost::polygon::voronoi_diagram &vd, const ThickPolylines *polylines, const char *path) { const double scale = 0.2; const std::string inputSegmentPointColor = "lightseagreen"; @@ -803,7 +802,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d Voronoi::Internal::point_type(double(it->b(0)), double(it->b(1))))); // Color exterior edges. - for (voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) + for (boost::polygon::voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) if (!it->is_finite()) Voronoi::Internal::color_exterior(&(*it)); @@ -818,11 +817,11 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d #if 1 // Draw voronoi vertices. - for (voronoi_diagram::const_vertex_iterator it = vd.vertices().begin(); it != vd.vertices().end(); ++it) + for (boost::polygon::voronoi_diagram::const_vertex_iterator it = vd.vertices().begin(); it != vd.vertices().end(); ++it) if (! internalEdgesOnly || it->color() != Voronoi::Internal::EXTERNAL_COLOR) - svg.draw(Point(coord_t((*it)(0)), coord_t((*it)(1))), voronoiPointColor, voronoiPointRadius); + svg.draw(Point(coord_t(it->x()), coord_t(it->y())), voronoiPointColor, voronoiPointRadius); - for (voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) { + for (boost::polygon::voronoi_diagram::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) { if (primaryEdgesOnly && !it->is_primary()) continue; if (internalEdgesOnly && (it->color() == Voronoi::Internal::EXTERNAL_COLOR)) @@ -845,7 +844,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d color = voronoiLineColorSecondary; } for (std::size_t i = 0; i + 1 < samples.size(); ++i) - svg.draw(Line(Point(coord_t(samples[i](0)), coord_t(samples[i](1))), Point(coord_t(samples[i+1](0)), coord_t(samples[i+1](1)))), color, voronoiLineWidth); + svg.draw(Line(Point(coord_t(samples[i].x()), coord_t(samples[i].y())), Point(coord_t(samples[i+1].x()), coord_t(samples[i+1].y()))), color, voronoiLineWidth); } #endif diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp index 44303711b5..d996658f27 100644 --- a/src/libslic3r/Geometry.hpp +++ b/src/libslic3r/Geometry.hpp @@ -11,8 +11,6 @@ #include #include "boost/polygon/voronoi.hpp" -using boost::polygon::voronoi_builder; -using boost::polygon::voronoi_diagram; namespace ClipperLib { class PolyNode; @@ -192,7 +190,7 @@ class MedialAxis { void build(Polylines* polylines); private: - class VD : public voronoi_diagram { + class VD : public boost::polygon::voronoi_diagram { public: typedef double coord_type; typedef boost::polygon::point_data point_type; From 16fd2820db44a34acb4f7aee1295c8ce05996530 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 23 Oct 2019 16:01:23 +0200 Subject: [PATCH 12/82] ENABLE_THUMBNAIL_GENERATOR -> WIP: Added missing include and preparation for adding thumbnail to exported sla archive files --- src/libslic3r/SLA/SLARasterWriter.cpp | 16 +++++++++++++++- src/libslic3r/SLA/SLARasterWriter.hpp | 18 ++++++++++++++++++ src/libslic3r/SLAPrint.hpp | 12 ++++++++++++ src/slic3r/GUI/BackgroundSlicingProcess.cpp | 18 +++++++++++++++++- src/slic3r/GUI/GLCanvas3D.cpp | 6 ------ src/slic3r/GUI/Plater.cpp | 5 +++++ src/slic3r/GUI/ThumbnailGenerator.cpp | 2 ++ 7 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/SLA/SLARasterWriter.cpp b/src/libslic3r/SLA/SLARasterWriter.cpp index f80ce01abf..27ffb8392e 100644 --- a/src/libslic3r/SLA/SLARasterWriter.cpp +++ b/src/libslic3r/SLA/SLARasterWriter.cpp @@ -28,7 +28,15 @@ RasterWriter::RasterWriter(const Raster::Resolution &res, : m_res(res), m_pxdim(pixdim), m_trafo(trafo), m_gamma(gamma) {} +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +void RasterWriter::save(const std::string& fpath, const ThumbnailData* thumbnail_data, const std::string& prjname) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { try { Zipper zipper(fpath); // zipper with no compression @@ -37,7 +45,13 @@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) boost::filesystem::path(fpath).stem().string() : prjname; zipper.add_entry("config.ini"); - + +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + // TODO add thumbnail_data as thumbnail.png file +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + zipper << createIniContent(project); for(unsigned i = 0; i < m_layers_rst.size(); i++) diff --git a/src/libslic3r/SLA/SLARasterWriter.hpp b/src/libslic3r/SLA/SLARasterWriter.hpp index c231655d28..180ea3b8a6 100644 --- a/src/libslic3r/SLA/SLARasterWriter.hpp +++ b/src/libslic3r/SLA/SLARasterWriter.hpp @@ -13,7 +13,17 @@ #include "SLARaster.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +namespace Slic3r { +struct ThumbnailData; +namespace sla { +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace sla { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // API to write the zipped sla output layers and metadata. // Implementation uses PNG raster output. @@ -111,7 +121,15 @@ public: } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + void save(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, const std::string& prjname = ""); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void save(const std::string &fpath, const std::string &prjname = ""); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void set_statistics(const PrintStatistics &statistics); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 2dc2a9040a..0c6b937710 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -358,11 +358,23 @@ public: // Returns true if the last step was finished with success. bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + inline void export_raster(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, + const std::string& projectname = "") + { + if (m_printer) m_printer->save(fpath, thumbnail_data, projectname); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ inline void export_raster(const std::string& fpath, const std::string& projectname = "") { if(m_printer) m_printer->save(fpath, projectname); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const PrintObjects& objects() const { return m_objects; } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 9d53d60b25..6def49d696 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -117,7 +117,15 @@ void BackgroundSlicingProcess::process_sla() if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_sla_print->export_raster(export_path, m_thumbnail_data); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_sla_print->export_raster(export_path); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_print->set_status(100, (boost::format(_utf8(L("Masked SLA file exported to %1%"))) % export_path).str()); } else if (! m_upload_job.empty()) { prepare_upload(); @@ -428,8 +436,16 @@ void BackgroundSlicingProcess::prepare_upload() m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); } else { m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR + m_sla_print->export_raster(source_path.string(), m_thumbnail_data, m_upload_job.upload_data.upload_path.string()); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string()); - } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + } m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4e72d15263..c55d64b472 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2108,12 +2108,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re manip->set_dirty(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_THUMBNAIL_GENERATOR -// wxGetApp().plater()->generate_thumbnail(256, 256, true); -//#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - // and force this canvas to be redrawn. m_dirty = true; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 66fb72bbc2..25331191b3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3395,6 +3395,11 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +//#if ENABLE_THUMBNAIL_GENERATOR +// thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); +//#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index a50c5541ca..37794dddfe 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -11,6 +11,8 @@ #include #include +#include + namespace Slic3r { namespace GUI { From d481feda13f45e1f5a25b48d5b40a00d6569e021 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 23 Oct 2019 16:24:59 +0200 Subject: [PATCH 13/82] Fix for unsupported cmake feature --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dde5a51f3e..f9c0469f61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,7 +283,14 @@ endfunction() if(TARGET Boost::system) message(STATUS "Boost::boost exists") target_link_libraries(boost_headeronly INTERFACE Boost::boost) - list(TRANSFORM _boost_components PREPEND Boost:: OUTPUT_VARIABLE _boost_targets) + + # Only from cmake 3.12 + # list(TRANSFORM _boost_components PREPEND Boost:: OUTPUT_VARIABLE _boost_targets) + set(_boost_targets "") + foreach(comp ${_boost_components}) + list(APPEND _boost_targets "Boost::${comp}") + endforeach() + target_link_libraries(boost_libs INTERFACE boost_headeronly # includes the custom compile definitions as well ${_boost_targets} From 77c52b748c3843aa1b29733022afeba5d3d0643d Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 23 Oct 2019 17:10:14 +0200 Subject: [PATCH 14/82] Zipper made available for modification after RasterWriter finishes. --- src/libslic3r/SLA/SLARasterWriter.cpp | 41 ++++++++++---------- src/libslic3r/SLA/SLARasterWriter.hpp | 22 ++--------- src/libslic3r/SLAPrint.hpp | 19 ++++------ src/libslic3r/Zipper.cpp | 5 +++ src/libslic3r/Zipper.hpp | 2 + src/slic3r/GUI/BackgroundSlicingProcess.cpp | 42 +++++++++++++-------- 6 files changed, 63 insertions(+), 68 deletions(-) diff --git a/src/libslic3r/SLA/SLARasterWriter.cpp b/src/libslic3r/SLA/SLARasterWriter.cpp index 27ffb8392e..6ac86827ef 100644 --- a/src/libslic3r/SLA/SLARasterWriter.cpp +++ b/src/libslic3r/SLA/SLARasterWriter.cpp @@ -28,47 +28,44 @@ RasterWriter::RasterWriter(const Raster::Resolution &res, : m_res(res), m_pxdim(pixdim), m_trafo(trafo), m_gamma(gamma) {} -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -void RasterWriter::save(const std::string& fpath, const ThumbnailData* thumbnail_data, const std::string& prjname) -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void RasterWriter::save(const std::string &fpath, const std::string &prjname) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { try { Zipper zipper(fpath); // zipper with no compression - - std::string project = prjname.empty()? - boost::filesystem::path(fpath).stem().string() : prjname; - + save(zipper, prjname); + zipper.finalize(); + } catch(std::exception& e) { + BOOST_LOG_TRIVIAL(error) << e.what(); + // Rethrow the exception + throw; + } +} + +void RasterWriter::save(Zipper &zipper, const std::string &prjname) +{ + try { + std::string project = + prjname.empty() ? + boost::filesystem::path(zipper.get_filename()).stem().string() : + prjname; + zipper.add_entry("config.ini"); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - // TODO add thumbnail_data as thumbnail.png file -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - zipper << createIniContent(project); - + for(unsigned i = 0; i < m_layers_rst.size(); i++) { if(m_layers_rst[i].rawbytes.size() > 0) { char lyrnum[6]; std::sprintf(lyrnum, "%.5d", i); auto zfilename = project + lyrnum + ".png"; - + // Add binary entry to the zipper zipper.add_entry(zfilename, m_layers_rst[i].rawbytes.data(), m_layers_rst[i].rawbytes.size()); } } - - zipper.finalize(); } catch(std::exception& e) { BOOST_LOG_TRIVIAL(error) << e.what(); // Rethrow the exception diff --git a/src/libslic3r/SLA/SLARasterWriter.hpp b/src/libslic3r/SLA/SLARasterWriter.hpp index 180ea3b8a6..93a315c821 100644 --- a/src/libslic3r/SLA/SLARasterWriter.hpp +++ b/src/libslic3r/SLA/SLARasterWriter.hpp @@ -12,18 +12,9 @@ #include "libslic3r/PrintConfig.hpp" #include "SLARaster.hpp" +#include "libslic3r/Zipper.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR -namespace Slic3r { -struct ThumbnailData; -namespace sla { -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace sla { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // API to write the zipped sla output layers and metadata. // Implementation uses PNG raster output. @@ -121,18 +112,11 @@ public: } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - void save(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, const std::string& prjname = ""); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void save(const std::string &fpath, const std::string &prjname = ""); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void save(Zipper &zipper, const std::string &prjname = ""); void set_statistics(const PrintStatistics &statistics); - + void set_config(const DynamicPrintConfig &cfg); }; diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 0c6b937710..8f386d407f 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -7,6 +7,7 @@ #include "SLA/SLARasterWriter.hpp" #include "Point.hpp" #include "MTUtils.hpp" +#include "Zipper.hpp" #include namespace Slic3r { @@ -358,23 +359,17 @@ public: // Returns true if the last step was finished with success. bool finished() const override { return this->is_step_done(slaposSliceSupports) && this->Inherited::is_step_done(slapsRasterize); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if ENABLE_THUMBNAIL_GENERATOR - inline void export_raster(const std::string& fpath, const ThumbnailData* thumbnail_data = nullptr, - const std::string& projectname = "") - { - if (m_printer) m_printer->save(fpath, thumbnail_data, projectname); - } -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ inline void export_raster(const std::string& fpath, const std::string& projectname = "") { if(m_printer) m_printer->save(fpath, projectname); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + inline void export_raster(Zipper &zipper, + const std::string& projectname = "") + { + if(m_printer) m_printer->save(zipper, projectname); + } const PrintObjects& objects() const { return m_objects; } diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp index 348be49ccb..a5b53584d7 100644 --- a/src/libslic3r/Zipper.cpp +++ b/src/libslic3r/Zipper.cpp @@ -217,4 +217,9 @@ void Zipper::finalize() m_impl->blow_up(); } +const std::string &Zipper::get_filename() const +{ + return m_impl->m_zipname; +} + } diff --git a/src/libslic3r/Zipper.hpp b/src/libslic3r/Zipper.hpp index a574de9596..be1e69b5c3 100644 --- a/src/libslic3r/Zipper.hpp +++ b/src/libslic3r/Zipper.hpp @@ -83,6 +83,8 @@ public: void finish_entry(); void finalize(); + + const std::string & get_filename() const; }; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 6def49d696..39c6e47ef4 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -107,25 +107,37 @@ void BackgroundSlicingProcess::process_fff() m_print->set_status(100, _utf8(L("Slicing complete"))); } this->set_step_done(bspsGCodeFinalize); - } + } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +static void write_thumbnail(Zipper &zipper, const ThumbnailData &data) +{ + // TODO add thumbnail_data as thumbnail.png file to the zipper with + // void Zipper::add_entry(const std::string& name, const std::uint8_t* data, size_t l); +} +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void BackgroundSlicingProcess::process_sla() { assert(m_print == m_sla_print); m_print->process(); if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { - const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); + const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path); + + Zipper zipper(export_path); + m_sla_print->export_raster(zipper); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - m_sla_print->export_raster(export_path, m_thumbnail_data); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - m_sla_print->export_raster(export_path); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if(m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + zipper.finalize(); + m_print->set_status(100, (boost::format(_utf8(L("Masked SLA file exported to %1%"))) % export_path).str()); } else if (! m_upload_job.empty()) { prepare_upload(); @@ -433,21 +445,21 @@ void BackgroundSlicingProcess::prepare_upload() throw std::runtime_error(_utf8(L("Copying of the temporary G-code to the output G-code failed"))); } run_post_process_scripts(source_path.string(), m_fff_print->config()); - m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + m_upload_job.upload_data.upload_path = m_fff_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); } else { - m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + m_upload_job.upload_data.upload_path = m_sla_print->print_statistics().finalize_output_path(m_upload_job.upload_data.upload_path.string()); + + Zipper zipper{source_path.string()}; + m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - m_sla_print->export_raster(source_path.string(), m_thumbnail_data, m_upload_job.upload_data.upload_path.string()); -#else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + zipper.finalize(); } - m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); + m_print->set_status(100, (boost::format(_utf8(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue"))) % m_upload_job.printhost->get_host()).str()); m_upload_job.upload_data.source_path = std::move(source_path); From ad0a9cf4390944deff74a45de65df2604c89dd18 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 08:46:39 +0200 Subject: [PATCH 15/82] ENABLE_THUMBNAIL_GENERATOR -> Add file thumbnail/thumbnail.png into sla output --- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 30 +++++++++++++++------ src/slic3r/GUI/Plater.cpp | 6 ++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 39c6e47ef4..3ef32ad641 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -10,12 +10,23 @@ #include #include +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx. #include "libslic3r/Print.hpp" #include "libslic3r/SLAPrint.hpp" #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PreviewData.hpp" +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +#include "libslic3r/GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/libslic3r.h" #include @@ -110,15 +121,18 @@ void BackgroundSlicingProcess::process_fff() } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR -static void write_thumbnail(Zipper &zipper, const ThumbnailData &data) +static void write_thumbnail(Zipper& zipper, const ThumbnailData& data) { - // TODO add thumbnail_data as thumbnail.png file to the zipper with - // void Zipper::add_entry(const std::string& name, const std::uint8_t* data, size_t l); + size_t png_size = 0; + void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); + if (png_data != nullptr) + { + zipper.add_entry("thumbnail/thumbnail.png", (const std::uint8_t*)png_data, png_size); + mz_free(png_data); + } } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void BackgroundSlicingProcess::process_sla() { @@ -130,11 +144,11 @@ void BackgroundSlicingProcess::process_sla() Zipper zipper(export_path); m_sla_print->export_raster(zipper); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #if ENABLE_THUMBNAIL_GENERATOR - if(m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data!= nullptr) + write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ zipper.finalize(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 25331191b3..71249bd90c 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3396,9 +3396,9 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//#if ENABLE_THUMBNAIL_GENERATOR -// thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); -//#endif // ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR + thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); +#endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } From 4517fcd997e0495045be6466bf11edad0ff9449c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 09:20:33 +0200 Subject: [PATCH 16/82] ENABLE_THUMBNAIL_GENERATOR -> Add file Metadata/thumbnail.png into 3mf output --- src/libslic3r/Format/3mf.cpp | 75 +++++++-------------- src/libslic3r/Format/3mf.hpp | 8 +-- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 2 +- 3 files changed, 26 insertions(+), 59 deletions(-) diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index a981cca613..ff3cf777d3 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -3,11 +3,9 @@ #include "../Utils.hpp" #include "../GCode.hpp" #include "../Geometry.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "../GCode/ThumbnailData.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "../I18N.hpp" @@ -45,11 +43,9 @@ const std::string MODEL_EXTENSION = ".model"; const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA const std::string CONTENT_TYPES_FILE = "[Content_Types].xml"; const std::string RELATIONSHIPS_FILE = "_rels/.rels"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR const std::string THUMBNAIL_FILE = "Metadata/thumbnail.png"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config"; const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config"; const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt"; @@ -1816,32 +1812,22 @@ namespace Slic3r { typedef std::map IdToObjectDataMap; public: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); + bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ private: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail); + bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_content_types_file_to_archive(mz_zip_archive& archive); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail); + bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _add_relationships_file_to_archive(mz_zip_archive& archive); bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data); bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets); @@ -1854,33 +1840,25 @@ namespace Slic3r { bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, const IdToObjectDataMap &objects_data); }; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) { clear_errors(); - return _save_model_to_file(filename, model, config, thumbnail); + return _save_model_to_file(filename, model, config, thumbnail_data); } #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) { clear_errors(); return _save_model_to_file(filename, model, config); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -1899,12 +1877,11 @@ namespace Slic3r { return false; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - if ((thumbnail != nullptr) && thumbnail->is_valid()) + if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { // Adds the file Metadata/thumbnail.png. - if (!_add_thumbnail_file_to_archive(archive, *thumbnail)) + if (!_add_thumbnail_file_to_archive(archive, *thumbnail_data)) { close_zip_writer(&archive); boost::filesystem::remove(filename); @@ -1912,7 +1889,6 @@ namespace Slic3r { } } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Adds relationships file ("_rels/.rels"). // The content of this file is the same for each PrusaSlicer 3mf. @@ -2007,11 +1983,9 @@ namespace Slic3r { stream << "\n"; stream << " \n"; stream << " \n"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR stream << " \n"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2025,16 +1999,25 @@ namespace Slic3r { return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail) + bool _3MF_Exporter::_add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data) { - // TODO -> add Metadata/thumbnail.png file containing thumbnail_data + bool res = false; - return true; + size_t png_size = 0; + void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)thumbnail_data.pixels.data(), thumbnail_data.width, thumbnail_data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); + if (png_data != nullptr) + { + res = mz_zip_writer_add_mem(&archive, THUMBNAIL_FILE.c_str(), (const void*)png_data, png_size, MZ_DEFAULT_COMPRESSION); + mz_free(png_data); + } + + if (!res) + add_error("Unable to add thumbnail file to archive"); + + return res; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool _3MF_Exporter::_add_relationships_file_to_archive(mz_zip_archive& archive) { @@ -2042,11 +2025,9 @@ namespace Slic3r { stream << "\n"; stream << "\n"; stream << " \n"; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR stream << " \n"; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ stream << ""; std::string out = stream.str(); @@ -2540,29 +2521,21 @@ namespace Slic3r { return res; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail) + bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { if ((path == nullptr) || (model == nullptr)) return false; _3MF_Exporter exporter; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - bool res = exporter.save_model_to_file(path, *model, config, thumbnail); + bool res = exporter.save_model_to_file(path, *model, config, thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool res = exporter.save_model_to_file(path, *model, config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!res) exporter.log_errors(); diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index 0ce6eb742b..2e85b7f59e 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -22,26 +22,20 @@ namespace Slic3r { class Model; class DynamicPrintConfig; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Load the content of a 3mf file into the given model and preset bundle. extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool check_version); // Save the given model and the config data contained in the given Print into a 3mf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail = nullptr); + extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // namespace Slic3r diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 3ef32ad641..67860138a4 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -146,7 +146,7 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data!= nullptr) + if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR From 5609f537979878673275ca30dd6e122e197b38ca Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:06:31 +0200 Subject: [PATCH 17/82] ENABLE_THUMBNAIL_GENERATOR -> Add thumbnail data into gcode output --- src/libslic3r/GCode.cpp | 25 ++++++++----------------- src/libslic3r/GCode.hpp | 10 ---------- src/slic3r/GUI/Plater.cpp | 27 ++++++++++++++++++--------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 13b417efad..2ea8eae1d6 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6,11 +6,9 @@ #include "Geometry.hpp" #include "GCode/PrintExtents.hpp" #include "GCode/WipeTower.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "GCode/ThumbnailData.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "ShortestPath.hpp" #include "Utils.hpp" @@ -657,15 +655,11 @@ std::vector>> GCode::collec return layers_to_print; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_CLEAR(); @@ -691,15 +685,11 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ try { m_placeholder_parser_failed_templates.clear(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR this->_do_export(*print, file, thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ this->_do_export(*print, file); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ fflush(file); if (ferror(file)) { fclose(file); @@ -763,15 +753,11 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GCode::_do_export(Print &print, FILE *file) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { PROFILE_FUNC(); @@ -964,19 +950,24 @@ void GCode::_do_export(Print &print, FILE *file) // Write information on the generator. _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR // Write thumbnail if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { _write(file, "\n;\n; thumbnail begin\n"); - // TODO -> export content of thumbnail_data.pixels + size_t row_size = 4 * thumbnail_data->width; + for (int r = (int)thumbnail_data->height - 1; r >= 0 ; --r) + { + _write(file, "; "); + const void* data_ptr = thumbnail_data->pixels.data() + r * row_size; + ::fwrite((const void*)data_ptr, 1, row_size, file); + _write(file, "\n"); + } _write(file, "; thumbnail end\n;\n\n"); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Write notes (content of the Print Settings tab -> Notes) { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 4c5b92bf1c..8116d06fc6 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -30,11 +30,9 @@ namespace Slic3r { // Forward declarations. class GCode; class GCodePreviewData; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class AvoidCrossingPerimeters { public: @@ -167,15 +165,11 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests. const Vec2d& origin() const { return m_origin; } @@ -203,15 +197,11 @@ public: static void append_full_config(const Print& print, std::string& str); protected: -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void _do_export(Print &print, FILE *file); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif //ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Object and support extrusions of the same PrintObject at the same print_z. struct LayerToPrint diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 71249bd90c..22edfcab20 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -87,6 +87,13 @@ using Slic3r::_3DScene; using Slic3r::Preset; using Slic3r::PrintHostJob; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_THUMBNAIL_GENERATOR +static const std::pair THUMBNAIL_SIZE_FFF = { 128, 128 }; +static const std::pair THUMBNAIL_SIZE_SLA = { 256, 256 }; +static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; +#endif // ENABLE_THUMBNAIL_GENERATOR +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -3052,9 +3059,11 @@ bool Plater::priv::restart_background_process(unsigned int state) #if ENABLE_THUMBNAIL_GENERATOR if ((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) { - // force update of thumbnail data, so that they can be inserted into the exported gcode - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); - thumbnail_generator.save_to_png_file("C:/prusa/test/test.png"); + // update thumbnail data + if (this->printer_technology == ptFFF) + generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + else if (this->printer_technology == ptSLA) + generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); } #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -3397,7 +3406,11 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) this->preview->reload_print(); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, 256, 256, true); + // update thumbnail data + if (this->printer_technology == ptFFF) + generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + else if (this->printer_technology == ptSLA) + generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); #endif // ENABLE_THUMBNAIL_GENERATOR //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } @@ -4672,16 +4685,12 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) DynamicPrintConfig cfg = wxGetApp().preset_bundle->full_config_secure(); const std::string path_u8 = into_u8(path); wxBusyCursor wait; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - p->generate_thumbnail(128, 128, false); + p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Success p->statusbar()->set_status_text(wxString::Format(_(L("3MF file exported to %s")), path)); p->set_project_filename(path); From 6d5572ae4739cb2e21744e736c247c5990311fad Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:25:40 +0200 Subject: [PATCH 18/82] ENABLE_THUMBNAIL_GENERATOR -> Code cleanup --- src/libslic3r/Print.cpp | 8 -------- src/libslic3r/Print.hpp | 6 ------ src/libslic3r/Technologies.hpp | 2 -- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 13 ++----------- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 6 ------ src/slic3r/GUI/GLCanvas3D.hpp | 3 --- src/slic3r/GUI/Plater.cpp | 18 ------------------ src/slic3r/GUI/Plater.hpp | 2 -- src/slic3r/GUI/ThumbnailGenerator.hpp | 4 +++- 9 files changed, 5 insertions(+), 57 deletions(-) diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 742a2a960c..b2ed87ca01 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1536,15 +1536,11 @@ void Print::process() // The export_gcode may die for various reasons (fails to process output_filename_format, // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { // output everything to a G-code file // The following call may die if the output_filename_format template substitution fails. @@ -1561,15 +1557,11 @@ std::string Print::export_gcode(const std::string &path_template, GCodePreviewDa // The following line may die for multiple reasons. GCode gcode; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR gcode.do_export(this, path.c_str(), preview_data, thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ gcode.do_export(this, path.c_str(), preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return path.c_str(); } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 8dc54ee1dc..aedeeff18c 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -19,11 +19,9 @@ class PrintObject; class ModelObject; class GCode; class GCodePreviewData; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Print step IDs for keeping track of the print state. enum PrintStep { @@ -310,15 +308,11 @@ public: void process() override; // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data = nullptr); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // methods for handling state bool is_step_done(PrintStep step) const { return Inherited::is_step_done(step); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 40e989bb2b..4b351adb29 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -32,7 +32,6 @@ #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING (0 && ENABLE_1_42_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //==================== // 2.2.0.alpha1 techs //==================== @@ -40,6 +39,5 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // _technologies_h_ diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 67860138a4..cedeab910c 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -10,11 +10,9 @@ #include #include -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx. #include "libslic3r/Print.hpp" @@ -22,11 +20,9 @@ #include "libslic3r/Utils.hpp" #include "libslic3r/GCode/PostProcessor.hpp" #include "libslic3r/GCode/PreviewData.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/GCode/ThumbnailData.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "libslic3r/libslic3r.h" #include @@ -93,15 +89,11 @@ void BackgroundSlicingProcess::process_fff() assert(m_print == m_fff_print); m_print->process(); wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_slicing_completed_id)); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_data); #else -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (this->set_step_started(bspsGCodeFinalize)) { if (! m_export_path.empty()) { //FIXME localize the messages @@ -465,11 +457,10 @@ void BackgroundSlicingProcess::prepare_upload() Zipper zipper{source_path.string()}; m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR - if (m_thumbnail_data) write_thumbnail(zipper, *m_thumbnail_data); + if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) + write_thumbnail(zipper, *m_thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ zipper.finalize(); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index af20554dfb..e51a4e961a 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -17,11 +17,9 @@ namespace Slic3r { class DynamicPrintConfig; class GCodePreviewData; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR struct ThumbnailData; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ class Model; class SLAPrint; @@ -54,11 +52,9 @@ public: void set_fff_print(Print *print) { m_fff_print = print; } void set_sla_print(SLAPrint *print) { m_sla_print = print; } void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void set_thumbnail_data(const ThumbnailData* data) { m_thumbnail_data = data; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished // and the background processing will transition into G-code export. @@ -162,12 +158,10 @@ private: SLAPrint *m_sla_print = nullptr; // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR // Data structure, used to write thumbnail into gcode. const ThumbnailData *m_thumbnail_data = nullptr; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; // Output path provided by the user. The output path may be set even if the slicing is running, diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2e7fc2d772..eb3c60bd16 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -446,12 +446,9 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR const GLVolumeCollection& get_volumes() const { return m_volumes; } -// GLVolumeCollection& get_volumes() { return m_volumes; } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool init(); void post_event(wxEvent &&event); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 22edfcab20..f9167cec9f 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -62,11 +62,9 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR #include "ThumbnailGenerator.hpp" #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -87,13 +85,11 @@ using Slic3r::_3DScene; using Slic3r::Preset; using Slic3r::PrintHostJob; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR static const std::pair THUMBNAIL_SIZE_FFF = { 128, 128 }; static const std::pair THUMBNAIL_SIZE_SLA = { 256, 256 }; static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ namespace Slic3r { namespace GUI { @@ -1385,11 +1381,9 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR ThumbnailGenerator thumbnail_generator; #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -1933,11 +1927,9 @@ struct Plater::priv bool can_mirror() const; bool can_reload_from_disk() const; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void msw_rescale_object_menu(); @@ -2006,11 +1998,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_fff_print(&fff_print); background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR background_process.set_thumbnail_data(&thumbnail_generator.get_data()); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); // Default printer technology for default config. @@ -3055,7 +3045,6 @@ bool Plater::priv::restart_background_process(unsigned int state) ( ((state & UPDATE_BACKGROUND_PROCESS_FORCE_RESTART) != 0 && ! this->background_process.finished()) || (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR if ((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) { @@ -3066,7 +3055,6 @@ bool Plater::priv::restart_background_process(unsigned int state) generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // The print is valid and it can be started. if (this->background_process.start()) { this->statusbar()->set_cancel_callback([this]() { @@ -3404,7 +3392,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR // update thumbnail data if (this->printer_technology == ptFFF) @@ -3412,7 +3399,6 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) else if (this->printer_technology == ptSLA) generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } @@ -3638,14 +3624,12 @@ bool Plater::priv::init_object_menu() return true; } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Plater::priv::msw_rescale_object_menu() { @@ -5187,14 +5171,12 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { p->generate_thumbnail(w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Plater::msw_rescale() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index b14cff65a2..7c671f6695 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,11 +240,9 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_THUMBNAIL_GENERATOR void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); #endif // ENABLE_THUMBNAIL_GENERATOR -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool can_delete() const; bool can_delete_all() const; diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index e632106cd9..ae7509b3c0 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -6,9 +6,11 @@ #include "../libslic3r/GCode/ThumbnailData.hpp" namespace Slic3r { + class GLVolume; typedef std::vector GLVolumePtrs; - namespace GUI { + +namespace GUI { class ThumbnailGenerator { From a1f2ecb285daebbac4271a6b145ead6433affcd7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 10:38:30 +0200 Subject: [PATCH 19/82] ENABLE_THUMBNAIL_GENERATOR -> Fixed color of non printable volumes into thumbnail --- src/slic3r/GUI/ThumbnailGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index 37794dddfe..f2a74cae9d 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -89,7 +89,7 @@ void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool prin for (const GLVolume* vol : visible_volumes) { - glsafe(::glColor3fv(vol->printable ? orange : gray)); + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); vol->render(); } From a417da8fea69547009ddb5994c44ade60c5fa9ac Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 11:08:39 +0200 Subject: [PATCH 20/82] ENABLE_THUMBNAIL_GENERATOR -> Fixed volumes visibility test to render them into thumbnail --- src/slic3r/GUI/ThumbnailGenerator.cpp | 34 ++++++--------------------- src/slic3r/GUI/ThumbnailGenerator.hpp | 2 -- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp index f2a74cae9d..634f9e61cb 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ b/src/slic3r/GUI/ThumbnailGenerator.cpp @@ -29,34 +29,14 @@ void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, u render_and_store(volumes, printable_only); } -bool ThumbnailGenerator::save_to_png_file(const std::string& filename) -{ - if (!m_data.is_valid()) - return false; - - wxImage image(m_data.width, m_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < m_data.height; ++r) - { - unsigned int rr = (m_data.height - 1 - r) * m_data.width; - for (unsigned int c = 0; c < m_data.width; ++c) - { - unsigned char* px = m_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - std::string path = filename; - if (!boost::iends_with(path, ".png")) - path = boost::filesystem::path(path).replace_extension(".png").string(); - - return image.SaveFile(from_u8(path), wxBITMAP_TYPE_PNG); -} - void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) { + auto is_visible = [] (const GLVolume& v) -> bool { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + static const float orange[] = { 0.99f, 0.49f, 0.26f }; static const float gray[] = { 0.64f, 0.64f, 0.64f }; @@ -64,7 +44,7 @@ void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool prin for (const GLVolume* vol : volumes) { - if (!printable_only || vol->printable) + if (!printable_only || is_visible(*vol)) visible_volumes.push_back(vol); } diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp index ae7509b3c0..20087b79b5 100644 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ b/src/slic3r/GUI/ThumbnailGenerator.hpp @@ -27,8 +27,6 @@ namespace GUI { const ThumbnailData& get_data() const { return m_data; } - bool save_to_png_file(const std::string& filename); - private: void render_and_store(const GLVolumePtrs& volumes, bool printable_only); }; From 29fd0ef7c6d2fdc1dcca6d599ba128d48615e232 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:09:09 +0200 Subject: [PATCH 21/82] ENABLE_THUMBNAIL_GENERATOR -> Refactoring to simplify code --- src/slic3r/CMakeLists.txt | 2 -- src/slic3r/GUI/GLCanvas3D.cpp | 61 +++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GLCanvas3D.hpp | 10 +++--- src/slic3r/GUI/Plater.cpp | 25 ++++++-------- src/slic3r/GUI/Plater.hpp | 4 --- 5 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 0b2dd67020..17b76e6296 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -136,8 +136,6 @@ set(SLIC3R_GUI_SOURCES GUI/ProgressStatusBar.cpp GUI/PrintHostDialogs.cpp GUI/PrintHostDialogs.hpp - GUI/ThumbnailGenerator.cpp - GUI/ThumbnailGenerator.hpp Utils/Http.cpp Utils/Http.hpp Utils/FixModelByWin10.cpp diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b472..8d16187cb8 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -7,6 +7,9 @@ #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/GCode/PreviewData.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "libslic3r/GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/Geometry.hpp" #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/Utils.hpp" @@ -1643,6 +1646,64 @@ void GLCanvas3D::render() #endif // ENABLE_RENDER_STATISTICS } +#if ENABLE_THUMBNAIL_GENERATOR +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only) +{ + auto is_visible = [](const GLVolume& v) -> bool { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + thumbnail_data.set(w, h); + + GLVolumePtrs visible_volumes; + + for (GLVolume* vol : m_volumes.volumes) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : visible_volumes) + { + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + + std::cout << "Generated thumbnail " << thumbnail_data.width << "x" << thumbnail_data.height << std::endl; + + // force a frame render to restore the default framebuffer + render(); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void GLCanvas3D::select_all() { m_selection.add_all(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index eb3c60bd16..611e9a932b 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -36,6 +36,9 @@ class GLShader; class ExPolygon; class BackgroundSlicingProcess; class GCodePreviewData; +#if ENABLE_THUMBNAIL_GENERATOR +struct ThumbnailData; +#endif // ENABLE_THUMBNAIL_GENERATOR struct SlicingParameters; enum LayerHeightEditActionType : unsigned int; @@ -446,10 +449,6 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } const wxGLCanvas* get_wxglcanvas() const { return m_canvas; } -#if ENABLE_THUMBNAIL_GENERATOR - const GLVolumeCollection& get_volumes() const { return m_volumes; } -#endif // ENABLE_THUMBNAIL_GENERATOR - bool init(); void post_event(wxEvent &&event); @@ -523,6 +522,9 @@ public: bool is_dragging() const { return m_gizmos.is_dragging() || m_moving; } void render(); +#if ENABLE_THUMBNAIL_GENERATOR + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only); +#endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); void deselect_all(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f9167cec9f..0ebd208fa2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -32,6 +32,9 @@ #include "libslic3r/Format/AMF.hpp" #include "libslic3r/Format/3mf.hpp" #include "libslic3r/GCode/PreviewData.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "libslic3r/GCode/ThumbnailData.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include "libslic3r/Model.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/Print.hpp" @@ -62,9 +65,6 @@ #include "GUI_Preview.hpp" #include "3DBed.hpp" #include "Camera.hpp" -#if ENABLE_THUMBNAIL_GENERATOR -#include "ThumbnailGenerator.hpp" -#endif // ENABLE_THUMBNAIL_GENERATOR #include "Tab.hpp" #include "PresetBundle.hpp" #include "BackgroundSlicingProcess.hpp" @@ -1370,6 +1370,9 @@ struct Plater::priv Slic3r::Model model; PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; +#if ENABLE_THUMBNAIL_GENERATOR + Slic3r::ThumbnailData thumbnail_data; +#endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements wxSizer* panel_sizer{ nullptr }; @@ -1381,9 +1384,6 @@ struct Plater::priv View3D* view3D; GLToolbar view_toolbar; Preview *preview; -#if ENABLE_THUMBNAIL_GENERATOR - ThumbnailGenerator thumbnail_generator; -#endif // ENABLE_THUMBNAIL_GENERATOR BackgroundSlicingProcess background_process; bool suppressed_backround_processing_update { false }; @@ -1999,7 +1999,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) background_process.set_sla_print(&sla_print); background_process.set_gcode_preview_data(&gcode_preview_data); #if ENABLE_THUMBNAIL_GENERATOR - background_process.set_thumbnail_data(&thumbnail_generator.get_data()); + background_process.set_thumbnail_data(&thumbnail_data); #endif // ENABLE_THUMBNAIL_GENERATOR background_process.set_slicing_completed_event(EVT_SLICING_COMPLETED); background_process.set_finished_event(EVT_PROCESS_COMPLETED); @@ -3627,7 +3627,7 @@ bool Plater::priv::init_object_menu() #if ENABLE_THUMBNAIL_GENERATOR void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) { - thumbnail_generator.generate(view3D->get_canvas3d()->get_volumes().volumes, w, h, printable_only); + view3D->get_canvas3d()->render_thumbnail(thumbnail_data, w, h, printable_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4671,7 +4671,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); - if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_generator.get_data())) { + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { #endif // ENABLE_THUMBNAIL_GENERATOR @@ -5171,13 +5171,6 @@ void Plater::paste_from_clipboard() p->view3D->get_canvas3d()->get_selection().paste_from_clipboard(); } -#if ENABLE_THUMBNAIL_GENERATOR -void Plater::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) -{ - p->generate_thumbnail(w, h, printable_only); -} -#endif // ENABLE_THUMBNAIL_GENERATOR - void Plater::msw_rescale() { p->preview->msw_rescale(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 7c671f6695..00ceb89bc3 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -240,10 +240,6 @@ public: void copy_selection_to_clipboard(); void paste_from_clipboard(); -#if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); -#endif // ENABLE_THUMBNAIL_GENERATOR - bool can_delete() const; bool can_delete_all() const; bool can_increase_instances() const; From d01532f4c682abd16a37cd0bff1f330911114d2b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:11:24 +0200 Subject: [PATCH 22/82] ENABLE_THUMBNAIL_GENERATOR -> Removed obsolete files --- src/slic3r/GUI/ThumbnailGenerator.cpp | 84 --------------------------- src/slic3r/GUI/ThumbnailGenerator.hpp | 40 ------------- 2 files changed, 124 deletions(-) delete mode 100644 src/slic3r/GUI/ThumbnailGenerator.cpp delete mode 100644 src/slic3r/GUI/ThumbnailGenerator.hpp diff --git a/src/slic3r/GUI/ThumbnailGenerator.cpp b/src/slic3r/GUI/ThumbnailGenerator.cpp deleted file mode 100644 index 634f9e61cb..0000000000 --- a/src/slic3r/GUI/ThumbnailGenerator.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "libslic3r/libslic3r.h" -#include "ThumbnailGenerator.hpp" - -#if ENABLE_THUMBNAIL_GENERATOR - -#include "Camera.hpp" -#include "3DScene.hpp" -#include "GUI.hpp" - -#include -#include -#include - -#include - -namespace Slic3r { -namespace GUI { - -void ThumbnailGenerator::reset() -{ - m_data.reset(); -} - -void ThumbnailGenerator::generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only) -{ - std::cout << "Generated thumbnail " << w << "x" << h << std::endl; - - m_data.set(w, h); - render_and_store(volumes, printable_only); -} - -void ThumbnailGenerator::render_and_store(const GLVolumePtrs& volumes, bool printable_only) -{ - auto is_visible = [] (const GLVolume& v) -> bool { - bool ret = v.printable; - ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); - return ret; - }; - - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - - GLVolumeConstPtrs visible_volumes; - - for (const GLVolume* vol : volumes) - { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); - } - - if (visible_volumes.empty()) - return; - - BoundingBoxf3 box; - for (const GLVolume* vol : visible_volumes) - { - box.merge(vol->transformed_bounding_box()); - } - - Camera camera; - camera.zoom_to_box(box, m_data.width, m_data.height); - camera.apply_viewport(0, 0, m_data.width, m_data.height); - camera.apply_view_matrix(); - camera.apply_projection(box); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - for (const GLVolume* vol : visible_volumes) - { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); - vol->render(); - } - - glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, m_data.width, m_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)m_data.pixels.data())); -} - -} // namespace GUI -} // namespace Slic3r - -#endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/ThumbnailGenerator.hpp b/src/slic3r/GUI/ThumbnailGenerator.hpp deleted file mode 100644 index 20087b79b5..0000000000 --- a/src/slic3r/GUI/ThumbnailGenerator.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef slic3r_GUI_ThumbnailGenerator_hpp_ -#define slic3r_GUI_ThumbnailGenerator_hpp_ - -#if ENABLE_THUMBNAIL_GENERATOR - -#include "../libslic3r/GCode/ThumbnailData.hpp" - -namespace Slic3r { - - class GLVolume; - typedef std::vector GLVolumePtrs; - -namespace GUI { - - class ThumbnailGenerator - { - typedef std::vector GLVolumeConstPtrs; - - ThumbnailData m_data; - - public: - ThumbnailGenerator() { reset(); } - - void reset(); - - void generate(const GLVolumePtrs& volumes, unsigned int w, unsigned int h, bool printable_only); - - const ThumbnailData& get_data() const { return m_data; } - - private: - void render_and_store(const GLVolumePtrs& volumes, bool printable_only); - }; - -} // namespace GUI -} // namespace Slic3r - -#endif // ENABLE_THUMBNAIL_GENERATOR - -#endif // slic3r_GUI_ThumbnailGenerator_hpp_ - From 1baa3336633bd4b596179310c4e0306e94155e36 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 12:30:19 +0200 Subject: [PATCH 23/82] ENABLE_THUMBNAIL_GENERATOR -> Fixed flickering of 3D view when generating thumbnail --- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8d16187cb8..a99b210acf 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1697,10 +1697,9 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, glsafe(::glDisable(GL_LIGHTING)); glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - std::cout << "Generated thumbnail " << thumbnail_data.width << "x" << thumbnail_data.height << std::endl; - - // force a frame render to restore the default framebuffer - render(); + // restore the framebuffer size to avoid flickering on the 3D scene + const Size& cnv_size = get_canvas_size(); + m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } #endif // ENABLE_THUMBNAIL_GENERATOR From 296d79abf7458719d51569fe785e519c32d57fec Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 Oct 2019 15:56:10 +0200 Subject: [PATCH 24/82] ENABLE_THUMBNAIL_GENERATOR -> Fixed thumbnail generation for SLA and 3mf --- src/libslic3r/SLAPrint.cpp | 5 +++++ src/slic3r/GUI/GLCanvas3D.cpp | 28 +++++++++++++++++++++++++--- src/slic3r/GUI/GLCanvas3D.hpp | 4 +++- src/slic3r/GUI/Plater.cpp | 27 ++++++++++++++++----------- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 2a1ae74d74..2c080ec3d4 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1372,7 +1372,12 @@ void SLAPrint::process() m_print_statistics.fast_layers_count = fast_layers; m_print_statistics.slow_layers_count = slow_layers; +#if ENABLE_THUMBNAIL_GENERATOR + // second argument set to -3 to differentiate it from the same call made into slice_supports() + m_report_status(*this, -3, "", SlicingStatus::RELOAD_SLA_PREVIEW); +#else m_report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); +#endif // ENABLE_THUMBNAIL_GENERATOR }; // Rasterizing the model objects, and their supports diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a99b210acf..914084bb65 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1647,7 +1647,7 @@ void GLCanvas3D::render() } #if ENABLE_THUMBNAIL_GENERATOR -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only) +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool { bool ret = v.printable; @@ -1664,8 +1664,11 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, for (GLVolume* vol : m_volumes.volumes) { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); + if (!vol->is_modifier && (!parts_only || (vol->composite_id.volume_id >= 0))) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } } if (visible_volumes.empty()) @@ -1697,6 +1700,25 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, glsafe(::glDisable(GL_LIGHTING)); glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); +#if 0 + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/test.png", wxBITMAP_TYPE_PNG); +#endif + // restore the framebuffer size to avoid flickering on the 3D scene const Size& cnv_size = get_canvas_size(); m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 611e9a932b..5b06b6311a 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -523,7 +523,9 @@ public: void render(); #if ENABLE_THUMBNAIL_GENERATOR - void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only); + // printable_only == false -> render also non printable volumes as grayed + // parts_only == false -> render also sla support and pad + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); #endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 0ebd208fa2..008a6eaa38 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1928,7 +1928,7 @@ struct Plater::priv bool can_reload_from_disk() const; #if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(unsigned int w, unsigned int h, bool printable_only); + void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -3050,9 +3050,12 @@ bool Plater::priv::restart_background_process(unsigned int state) { // update thumbnail data if (this->printer_technology == ptFFF) - generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); + // for ptFFF we need to generate the thumbnail before the export of gcode starts + generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true, true); else if (this->printer_technology == ptSLA) - generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); + // for ptSLA generate thumbnail without supports and pad (not yet calculated) + // to render also supports and pad see on_slicing_update() + generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, true); } #endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. @@ -3392,13 +3395,14 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); +/* #if ENABLE_THUMBNAIL_GENERATOR // update thumbnail data - if (this->printer_technology == ptFFF) - generate_thumbnail(THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true); - else if (this->printer_technology == ptSLA) - generate_thumbnail(THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true); + // for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered + if ((this->printer_technology == ptSLA) && (evt.status.percent == -3)) + generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, false); #endif // ENABLE_THUMBNAIL_GENERATOR +*/ } } @@ -3625,9 +3629,9 @@ bool Plater::priv::init_object_menu() } #if ENABLE_THUMBNAIL_GENERATOR -void Plater::priv::generate_thumbnail(unsigned int w, unsigned int h, bool printable_only) +void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { - view3D->get_canvas3d()->render_thumbnail(thumbnail_data, w, h, printable_only); + view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4670,8 +4674,9 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) const std::string path_u8 = into_u8(path); wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR - p->generate_thumbnail(THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false); - if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &p->thumbnail_data)) { + ThumbnailData thumbnail_data; + p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true); + if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { #endif // ENABLE_THUMBNAIL_GENERATOR From eee20e23e199989dfde0f963bacd936805f6a2ed Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 24 Oct 2019 17:32:05 +0200 Subject: [PATCH 25/82] Fix RelWithDebInfo build on Linux --- CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9c0469f61..9986aab7c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,13 +271,15 @@ if(NOT SLIC3R_STATIC) endif() function(slic3r_remap_configs targets from_Cfg to_Cfg) - string(TOUPPER ${from_Cfg} from_CFG) - - foreach(tgt ${targets}) - if(TARGET ${tgt}) - set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) - endif() - endforeach() + if(MSVC) + string(TOUPPER ${from_Cfg} from_CFG) + + foreach(tgt ${targets}) + if(TARGET ${tgt}) + set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) + endif() + endforeach() + endif() endfunction() if(TARGET Boost::system) From f7d3cf063bdae284989286ef84e07869c42b9382 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 08:19:02 +0200 Subject: [PATCH 26/82] ENABLE_THUMBNAIL_GENERATOR -> Added a comment --- src/slic3r/GUI/Plater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 008a6eaa38..60a90f1f13 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3395,6 +3395,8 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) } else if (evt.status.flags & PrintBase::SlicingStatus::RELOAD_SLA_PREVIEW) { // Update the SLA preview. Only called if not RELOAD_SLA_SUPPORT_POINTS, as the block above will refresh the preview anyways. this->preview->reload_print(); + + // uncomment the following lines if you want to render into the thumbnail also supports and pad for SLA printer /* #if ENABLE_THUMBNAIL_GENERATOR // update thumbnail data From 982ed95a3560a9e7212efa7c0eaf5f764a2096ea Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 08:57:13 +0200 Subject: [PATCH 27/82] ENABLE_THUMBNAIL_GENERATOR -> Save thumbnail size into gcode --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2ea8eae1d6..c964684153 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -954,7 +954,7 @@ void GCode::_do_export(Print &print, FILE *file) // Write thumbnail if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { - _write(file, "\n;\n; thumbnail begin\n"); + _write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height); size_t row_size = 4 * thumbnail_data->width; for (int r = (int)thumbnail_data->height - 1; r >= 0 ; --r) From 843251c91fd802a9a27e71b9e03c2e2bb5c518c5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 09:04:58 +0200 Subject: [PATCH 28/82] ENABLE_THUMBNAIL_GENERATOR -> Do not render wipe tower into thumbnail --- src/slic3r/GUI/GLCanvas3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 914084bb65..703321c3ca 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1664,7 +1664,7 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, for (GLVolume* vol : m_volumes.volumes) { - if (!vol->is_modifier && (!parts_only || (vol->composite_id.volume_id >= 0))) + if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) { if (!printable_only || is_visible(*vol)) visible_volumes.push_back(vol); From 45d80aba6390f0609137896313eb2daf6581d485 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 25 Oct 2019 10:41:56 +0200 Subject: [PATCH 29/82] Add catch2 extra args option to tests. update example --- tests/CMakeLists.txt | 3 +++ tests/example/CMakeLists.txt | 6 ++---- tests/fff_print/CMakeLists.txt | 2 +- tests/libnest2d/CMakeLists.txt | 2 +- tests/libslic3r/CMakeLists.txt | 2 +- tests/sla_print/CMakeLists.txt | 2 +- tests/timeutils/CMakeLists.txt | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e957c0c20e..7e8db00bf3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,8 @@ target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) add_library(Catch2::Catch2 ALIAS Catch2) include(Catch) +set(CATCH_EXTRA_ARGS "--durations yes" CACHE STRING "Extra arguments for catch2 test suites.") + add_library(test_common INTERFACE) target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE) target_link_libraries(test_common INTERFACE Catch2::Catch2) @@ -25,3 +27,4 @@ add_subdirectory(libslic3r) add_subdirectory(timeutils) add_subdirectory(fff_print) add_subdirectory(sla_print) +# add_subdirectory(example) diff --git a/tests/example/CMakeLists.txt b/tests/example/CMakeLists.txt index d62f0a96c0..b11c9e064b 100644 --- a/tests/example/CMakeLists.txt +++ b/tests/example/CMakeLists.txt @@ -1,8 +1,6 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests_main.cpp) -target_link_libraries(${_TEST_NAME}_tests test_common libslic3r -#${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES} -) +target_link_libraries(${_TEST_NAME}_tests test_common) # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") \ No newline at end of file +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) \ No newline at end of file diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 703d5b3cf4..32ae9757a9 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -19,4 +19,4 @@ target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) diff --git a/tests/libnest2d/CMakeLists.txt b/tests/libnest2d/CMakeLists.txt index 91a2e7852b..d4f684dd3c 100644 --- a/tests/libnest2d/CMakeLists.txt +++ b/tests/libnest2d/CMakeLists.txt @@ -4,4 +4,4 @@ target_link_libraries(${_TEST_NAME}_tests test_common libnest2d ) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 2dd2b34a3e..98aab498e4 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -11,4 +11,4 @@ target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) diff --git a/tests/sla_print/CMakeLists.txt b/tests/sla_print/CMakeLists.txt index d0b51a01da..e8921ba486 100644 --- a/tests/sla_print/CMakeLists.txt +++ b/tests/sla_print/CMakeLists.txt @@ -4,4 +4,4 @@ target_link_libraries(${_TEST_NAME}_tests test_common libslic3r) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) diff --git a/tests/timeutils/CMakeLists.txt b/tests/timeutils/CMakeLists.txt index b67ce85f1f..6ece9f4d10 100644 --- a/tests/timeutils/CMakeLists.txt +++ b/tests/timeutils/CMakeLists.txt @@ -8,4 +8,4 @@ target_link_libraries(${_TEST_NAME}_tests test_common) set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") # catch_discover_tests(${_TEST_NAME}_tests TEST_PREFIX "${_TEST_NAME}: ") -add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests "--durations yes") +add_test(${_TEST_NAME}_tests ${_TEST_NAME}_tests ${CATCH_EXTRA_ARGS}) From de60b403471bbfc510c54dae78757131e5de3ed2 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 12:18:10 +0200 Subject: [PATCH 30/82] ENABLE_THUMBNAIL_GENERATOR -> Thumbnail data saved into gcode using base64 encoding + debug code to extract thumbnails from gcode --- src/libslic3r/GCode.cpp | 12 ++--- src/slic3r/GUI/GUI_App.cpp | 86 ++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/GUI_App.hpp | 5 +++ src/slic3r/GUI/MainFrame.cpp | 5 +++ 4 files changed, 102 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index c964684153..db493270a7 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -21,6 +21,9 @@ #include #include #include +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR #include #include @@ -951,18 +954,15 @@ void GCode::_do_export(Print &print, FILE *file) _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); #if ENABLE_THUMBNAIL_GENERATOR - // Write thumbnail + // Write thumbnail using base64 encoding if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) { _write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height); size_t row_size = 4 * thumbnail_data->width; - for (int r = (int)thumbnail_data->height - 1; r >= 0 ; --r) + for (int r = (int)thumbnail_data->height - 1; r >= 0; --r) { - _write(file, "; "); - const void* data_ptr = thumbnail_data->pixels.data() + r * row_size; - ::fwrite((const void*)data_ptr, 1, row_size, file); - _write(file, "\n"); + _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(thumbnail_data->pixels.data() + r * row_size), row_size).c_str()); } _write(file, "; thumbnail end\n;\n\n"); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index b5e70c0a19..0b2244d656 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -51,6 +51,10 @@ #include #endif // __WXMSW__ +#if ENABLE_THUMBNAIL_GENERATOR +#include +#endif // ENABLE_THUMBNAIL_GENERATOR + namespace Slic3r { namespace GUI { @@ -1082,6 +1086,88 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage return res; } +#if ENABLE_THUMBNAIL_GENERATOR +void GUI_App::gcode_thumbnails_debug() +{ + const std::string BEGIN_MASK = "; thumbnail begin"; + const std::string END_MASK = "; thumbnail end"; + std::string gcode_line; + bool reading_image = false; + unsigned int width = 0; + unsigned int height = 0; + + wxFileDialog dialog(GetTopWindow(), _(L("Select a gcode file:")), "", "", "G-code files (*.gcode)|*.gcode;*.GCODE;", wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() != wxID_OK) + return; + + std::string in_filename = into_u8(dialog.GetPath()); + std::string out_path = boost::filesystem::path(in_filename).remove_filename().append(L"thumbnail").string(); + + boost::nowide::ifstream file(in_filename.c_str()); + std::vector rows; + if (file.good()) + { + while (std::getline(file, gcode_line)) + { + if (file.good()) + { + if (boost::starts_with(gcode_line, BEGIN_MASK)) + { + reading_image = true; + gcode_line = gcode_line.substr(BEGIN_MASK.length() + 1); + std::string::size_type x_pos = gcode_line.find('x'); + std::string width_str = gcode_line.substr(0, x_pos); + width = (unsigned int)::atoi(width_str.c_str()); + std::string height_str = gcode_line.substr(x_pos + 1); + height = (unsigned int)::atoi(height_str.c_str()); + } + else if (reading_image && boost::starts_with(gcode_line, END_MASK)) + { + if ((unsigned int)rows.size() == height) + { + std::vector thumbnail(4 * width * height, 0); + for (unsigned int r = 0; r < (unsigned int)rows.size(); ++r) + { + std::string decoded_row = boost::beast::detail::base64_decode(rows[r]); + if ((unsigned int)decoded_row.length() == width * 4) + { + void* image_ptr = (void*)(thumbnail.data() + r * width * 4); + ::memcpy(image_ptr, (const void*)decoded_row.c_str(), width * 4); + } + } + + wxImage image(width, height); + image.InitAlpha(); + + for (unsigned int r = 0; r < height; ++r) + { + unsigned int rr = r * width; + for (unsigned int c = 0; c < width; ++c) + { + unsigned char* px = thumbnail.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile(out_path + std::to_string(width) + "x" + std::to_string(height) + ".png", wxBITMAP_TYPE_PNG); + } + + reading_image = false; + width = 0; + height = 0; + rows.clear(); + } + else if (reading_image) + rows.push_back(gcode_line.substr(2)); + } + } + + file.close(); + } +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { if (name.empty()) { return; } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index c5ddc01528..f9f907e422 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -189,6 +189,11 @@ public: void open_web_page_localized(const std::string &http_address); bool run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage start_page = ConfigWizard::SP_WELCOME); +#if ENABLE_THUMBNAIL_GENERATOR + // temporary and debug only -> extract thumbnails from selected gcode and save them as png files + void gcode_thumbnails_debug(); +#endif // ENABLE_THUMBNAIL_GENERATOR + private: bool on_init_inner(); void window_pos_save(wxTopLevelWindow* window, const std::string &name); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6f39db86dd..56eda2c0da 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -682,6 +682,11 @@ void MainFrame::init_menubar() helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")), [this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); }); +#if ENABLE_THUMBNAIL_GENERATOR + helpMenu->AppendSeparator(); + append_menu_item(helpMenu, wxID_ANY, _(L("DEBUG gcode thumbnails")), _(L("DEBUG ONLY - read the selected gcode file and generates png for the contained thumbnails")), + [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); +#endif // ENABLE_THUMBNAIL_GENERATOR } // menubar From 62c90abbc03887c7cf03297d3ec2c7c68ee15755 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 25 Oct 2019 13:09:10 +0200 Subject: [PATCH 31/82] Fix of SPE-1041: set_state function for gizmos is called even if they are turned on/off by the undo/redo action --- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index f649c98b25..0defb13483 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -114,8 +114,17 @@ public: m_serializing = true; + // Following is needed to know which to be turn on, but not actually modify + // m_current prematurely, so activate_gizmo is not confused. + EType old_current = m_current; ar(m_current); + EType new_current = m_current; + m_current = old_current; + // activate_gizmo call sets m_current and calls set_state for the gizmo + // it does nothing in case the gizmo is already activated + // it can safely be called for Undefined gizmo + activate_gizmo(new_current); if (m_current != Undefined) m_gizmos[m_current]->load(ar); } From 4554da29abc153c48284235ed73f2aa7d4eefc8e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 25 Oct 2019 13:09:25 +0200 Subject: [PATCH 32/82] Add OpenVDB to dependencies * Add Linux openvdb integration * Add Mac openvdb integration and enable in ALL * Create openvdb sandbox to test integration. * Additional fixes in the patches * Remove slabasebed sandbox as it has no relevance now * Provide FindOpenVDB module and fix build issues --- CMakeLists.txt | 41 +- cmake/modules/FindOpenVDB.cmake | 490 ++++++ cmake/modules/FindTBB.cmake | 20 +- cmake/modules/OpenVDBUtils.cmake | 166 ++ deps/CMakeLists.txt | 2 + deps/blosc-mods.patch | 477 ++++++ deps/deps-linux.cmake | 8 +- deps/deps-macos.cmake | 4 +- deps/deps-unix-common.cmake | 58 +- deps/deps-windows.cmake | 160 +- deps/{igl-fixes.patch => igl-mods.patch} | 0 deps/openvdb-mods.patch | 1771 ++++++++++++++++++++++ deps/qhull-mods.patch | 144 +- sandboxes/CMakeLists.txt | 2 +- sandboxes/openvdb/CMakeLists.txt | 2 + sandboxes/openvdb/openvdb_example.cpp | 37 + sandboxes/slabasebed/CMakeLists.txt | 2 - sandboxes/slabasebed/slabasebed.cpp | 85 -- src/libslic3r/CMakeLists.txt | 1 + src/qhull/CMakeLists.txt | 4 +- 20 files changed, 3199 insertions(+), 275 deletions(-) create mode 100644 cmake/modules/FindOpenVDB.cmake create mode 100644 cmake/modules/OpenVDBUtils.cmake create mode 100644 deps/blosc-mods.patch rename deps/{igl-fixes.patch => igl-mods.patch} (100%) create mode 100644 deps/openvdb-mods.patch create mode 100644 sandboxes/openvdb/CMakeLists.txt create mode 100644 sandboxes/openvdb/openvdb_example.cpp delete mode 100644 sandboxes/slabasebed/CMakeLists.txt delete mode 100644 sandboxes/slabasebed/slabasebed.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b1d73f89f..1c704a04b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,7 +254,8 @@ if(NOT WIN32) # boost::process was introduced first in version 1.64.0 set(MINIMUM_BOOST_VERSION "1.64.0") endif() -find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS system filesystem thread log locale regex) +set(_boost_components "system;filesystem;thread;log;locale;regex") +find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS ${_boost_components}) add_library(boost_libs INTERFACE) add_library(boost_headeronly INTERFACE) @@ -268,23 +269,41 @@ if(NOT SLIC3R_STATIC) target_compile_definitions(boost_headeronly INTERFACE BOOST_LOG_DYN_LINK) endif() +function(slic3r_remap_configs targets from_Cfg to_Cfg) + if(MSVC) + string(TOUPPER ${from_Cfg} from_CFG) + + foreach(tgt ${targets}) + if(TARGET ${tgt}) + set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) + endif() + endforeach() + endif() +endfunction() + if(TARGET Boost::system) message(STATUS "Boost::boost exists") target_link_libraries(boost_headeronly INTERFACE Boost::boost) + + # Only from cmake 3.12 + # list(TRANSFORM _boost_components PREPEND Boost:: OUTPUT_VARIABLE _boost_targets) + set(_boost_targets "") + foreach(comp ${_boost_components}) + list(APPEND _boost_targets "Boost::${comp}") + endforeach() + target_link_libraries(boost_libs INTERFACE boost_headeronly # includes the custom compile definitions as well - Boost::system - Boost::filesystem - Boost::thread - Boost::log - Boost::locale - Boost::regex + ${_boost_targets} ) + slic3r_remap_configs("${_boost_targets}" RelWithDebInfo Release) else() target_include_directories(boost_headeronly INTERFACE ${Boost_INCLUDE_DIRS}) target_link_libraries(boost_libs INTERFACE boost_headeronly ${Boost_LIBRARIES}) endif() + + # Find and configure intel-tbb if(SLIC3R_STATIC) set(TBB_STATIC 1) @@ -377,6 +396,14 @@ add_custom_target(pot find_package(NLopt 1.4 REQUIRED) +if(SLIC3R_STATIC) + set(OPENVDB_USE_STATIC_LIBS ON) + set(USE_BLOSC TRUE) +endif() + +find_package(OpenVDB 5.0 REQUIRED openvdb) +slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) + # libslic3r, PrusaSlicer GUI and the PrusaSlicer executable. add_subdirectory(src) set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT PrusaSlicer_app_console) diff --git a/cmake/modules/FindOpenVDB.cmake b/cmake/modules/FindOpenVDB.cmake new file mode 100644 index 0000000000..9afe8a2356 --- /dev/null +++ b/cmake/modules/FindOpenVDB.cmake @@ -0,0 +1,490 @@ +# Copyright (c) DreamWorks Animation LLC +# +# All rights reserved. This software is distributed under the +# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) +# +# Redistributions of source code must retain the above copyright +# and license notice and the following restrictions and disclaimer. +# +# * Neither the name of DreamWorks Animation nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. +# +#[=======================================================================[.rst: + +FindOpenVDB +----------- + +Find OpenVDB include dirs, libraries and settings + +Use this module by invoking find_package with the form:: + + find_package(OpenVDB + [version] [EXACT] # Minimum or EXACT version + [REQUIRED] # Fail with error if OpenVDB is not found + [COMPONENTS ...] # OpenVDB libraries by their canonical name + # e.g. "openvdb" for "libopenvdb" + ) + +IMPORTED Targets +^^^^^^^^^^^^^^^^ + +``OpenVDB::openvdb`` + The core openvdb library target. + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``OpenVDB_FOUND`` + True if the system has the OpenVDB library. +``OpenVDB_VERSION`` + The version of the OpenVDB library which was found. +``OpenVDB_INCLUDE_DIRS`` + Include directories needed to use OpenVDB. +``OpenVDB_LIBRARIES`` + Libraries needed to link to OpenVDB. +``OpenVDB_LIBRARY_DIRS`` + OpenVDB library directories. +``OpenVDB_DEFINITIONS`` + Definitions to use when compiling code that uses OpenVDB. +``OpenVDB_{COMPONENT}_FOUND`` + True if the system has the named OpenVDB component. +``OpenVDB_USES_BLOSC`` + True if the OpenVDB Library has been built with blosc support +``OpenVDB_USES_LOG4CPLUS`` + True if the OpenVDB Library has been built with log4cplus support +``OpenVDB_USES_EXR`` + True if the OpenVDB Library has been built with openexr support +``OpenVDB_ABI`` + Set if this module was able to determine the ABI number the located + OpenVDB Library was built against. Unset otherwise. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``OpenVDB_INCLUDE_DIR`` + The directory containing ``openvdb/version.h``. +``OpenVDB_{COMPONENT}_LIBRARY`` + Individual component libraries for OpenVDB + +Hints +^^^^^ + +Instead of explicitly setting the cache variables, the following variables +may be provided to tell this module where to look. + +``OPENVDB_ROOT`` + Preferred installation prefix. +``OPENVDB_INCLUDEDIR`` + Preferred include directory e.g. /include +``OPENVDB_LIBRARYDIR`` + Preferred library directory e.g. /lib +``SYSTEM_LIBRARY_PATHS`` + Paths appended to all include and lib searches. + +#]=======================================================================] + +cmake_minimum_required(VERSION 3.3) +# Monitoring _ROOT variables +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + +# Include utility functions for version information +include(${CMAKE_CURRENT_LIST_DIR}/OpenVDBUtils.cmake) + +mark_as_advanced( + OpenVDB_INCLUDE_DIR + OpenVDB_LIBRARY +) + +set(_OPENVDB_COMPONENT_LIST + openvdb +) + +if(OpenVDB_FIND_COMPONENTS) + set(OPENVDB_COMPONENTS_PROVIDED TRUE) + set(_IGNORED_COMPONENTS "") + foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) + if(NOT ${COMPONENT} IN_LIST _OPENVDB_COMPONENT_LIST) + list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) + endif() + endforeach() + + if(_IGNORED_COMPONENTS) + message(STATUS "Ignoring unknown components of OpenVDB:") + foreach(COMPONENT ${_IGNORED_COMPONENTS}) + message(STATUS " ${COMPONENT}") + endforeach() + list(REMOVE_ITEM OpenVDB_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) + endif() +else() + set(OPENVDB_COMPONENTS_PROVIDED FALSE) + set(OpenVDB_FIND_COMPONENTS ${_OPENVDB_COMPONENT_LIST}) +endif() + +# Append OPENVDB_ROOT or $ENV{OPENVDB_ROOT} if set (prioritize the direct cmake var) +set(_OPENVDB_ROOT_SEARCH_DIR "") + +# Additionally try and use pkconfig to find OpenVDB + +find_package(PkgConfig) +pkg_check_modules(PC_OpenVDB QUIET OpenVDB) + +# ------------------------------------------------------------------------ +# Search for OpenVDB include DIR +# ------------------------------------------------------------------------ + +set(_OPENVDB_INCLUDE_SEARCH_DIRS "") +list(APPEND _OPENVDB_INCLUDE_SEARCH_DIRS + ${OPENVDB_INCLUDEDIR} + ${_OPENVDB_ROOT_SEARCH_DIR} + ${PC_OpenVDB_INCLUDE_DIRS} + ${SYSTEM_LIBRARY_PATHS} +) + +# Look for a standard OpenVDB header file. +find_path(OpenVDB_INCLUDE_DIR openvdb/version.h + PATHS ${_OPENVDB_INCLUDE_SEARCH_DIRS} + PATH_SUFFIXES include +) + +OPENVDB_VERSION_FROM_HEADER("${OpenVDB_INCLUDE_DIR}/openvdb/version.h" + VERSION OpenVDB_VERSION + MAJOR OpenVDB_MAJOR_VERSION + MINOR OpenVDB_MINOR_VERSION + PATCH OpenVDB_PATCH_VERSION +) + +# ------------------------------------------------------------------------ +# Search for OPENVDB lib DIR +# ------------------------------------------------------------------------ + +set(_OPENVDB_LIBRARYDIR_SEARCH_DIRS "") + +# Append to _OPENVDB_LIBRARYDIR_SEARCH_DIRS in priority order + +list(APPEND _OPENVDB_LIBRARYDIR_SEARCH_DIRS + ${OPENVDB_LIBRARYDIR} + ${_OPENVDB_ROOT_SEARCH_DIR} + ${PC_OpenVDB_LIBRARY_DIRS} + ${SYSTEM_LIBRARY_PATHS} +) + +# Build suffix directories + +set(OPENVDB_PATH_SUFFIXES + lib64 + lib +) + +# Static library setup +if(UNIX AND OPENVDB_USE_STATIC_LIBS) + set(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +endif() + +set(OpenVDB_LIB_COMPONENTS "") + +foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) + set(LIB_NAME ${COMPONENT}) + find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} + PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} + ) + list(APPEND OpenVDB_LIB_COMPONENTS ${OpenVDB_${COMPONENT}_LIBRARY}) + + if(OpenVDB_${COMPONENT}_LIBRARY) + set(OpenVDB_${COMPONENT}_FOUND TRUE) + else() + set(OpenVDB_${COMPONENT}_FOUND FALSE) + endif() +endforeach() + +if(UNIX AND OPENVDB_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(_OPENVDB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() + +# ------------------------------------------------------------------------ +# Cache and set OPENVDB_FOUND +# ------------------------------------------------------------------------ + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenVDB + FOUND_VAR OpenVDB_FOUND + REQUIRED_VARS + OpenVDB_INCLUDE_DIR + OpenVDB_LIB_COMPONENTS + VERSION_VAR OpenVDB_VERSION + HANDLE_COMPONENTS +) + +# ------------------------------------------------------------------------ +# Determine ABI number +# ------------------------------------------------------------------------ + +# Set the ABI number the library was built against. Uses vdb_print +find_program(OPENVDB_PRINT vdb_print PATHS ${OpenVDB_INCLUDE_DIR} ) + +OPENVDB_ABI_VERSION_FROM_PRINT( + "${OPENVDB_PRINT}" + ABI OpenVDB_ABI +) + +if(NOT OpenVDB_FIND_QUIET) + if(NOT OpenVDB_ABI) + message(WARNING "Unable to determine OpenVDB ABI version from OpenVDB " + "installation. The library major version \"${OpenVDB_MAJOR_VERSION}\" " + "will be inferred. If this is not correct, use " + "add_definitions(-DOPENVDB_ABI_VERSION_NUMBER=N)" + ) + else() + message(STATUS "OpenVDB ABI Version: ${OpenVDB_ABI}") + endif() +endif() + +# ------------------------------------------------------------------------ +# Handle OpenVDB dependencies +# ------------------------------------------------------------------------ + +# Add standard dependencies + +find_package(IlmBase COMPONENTS Half) +if(NOT IlmBase_FOUND) + pkg_check_modules(IlmBase QUIET IlmBase) +endif() +if (IlmBase_FOUND AND NOT TARGET IlmBase::Half) + message(STATUS "Falling back to IlmBase found by pkg-config...") + + find_library(IlmHalf_LIBRARY NAMES Half) + if(IlmHalf_LIBRARY-NOTFOUND) + message(FATAL_ERROR "IlmBase::Half can not be found!") + endif() + + add_library(IlmBase::Half UNKNOWN IMPORTED) + set_target_properties(IlmBase::Half PROPERTIES + IMPORTED_LOCATION "${IlmHalf_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES ${IlmBase_INCLUDE_DIRS}) +elseif(NOT IlmBase_FOUND) + message(FATAL_ERROR "IlmBase::Half can not be found!") +endif() +find_package(TBB REQUIRED COMPONENTS tbb) +find_package(ZLIB REQUIRED) +find_package(Boost REQUIRED COMPONENTS iostreams system) + +# Use GetPrerequisites to see which libraries this OpenVDB lib has linked to +# which we can query for optional deps. This basically runs ldd/otoll/objdump +# etc to track deps. We could use a vdb_config binary tools here to improve +# this process + +include(GetPrerequisites) + +set(_EXCLUDE_SYSTEM_PREREQUISITES 1) +set(_RECURSE_PREREQUISITES 0) +set(_OPENVDB_PREREQUISITE_LIST) + +if(NOT OPENVDB_USE_STATIC_LIBS) +get_prerequisites(${OpenVDB_openvdb_LIBRARY} + _OPENVDB_PREREQUISITE_LIST + ${_EXCLUDE_SYSTEM_PREREQUISITES} + ${_RECURSE_PREREQUISITES} + "" + "${SYSTEM_LIBRARY_PATHS}" +) +endif() + +unset(_EXCLUDE_SYSTEM_PREREQUISITES) +unset(_RECURSE_PREREQUISITES) + +# As the way we resolve optional libraries relies on library file names, use +# the configuration options from the main CMakeLists.txt to allow users +# to manually identify the requirements of OpenVDB builds if they know them. + +set(OpenVDB_USES_BLOSC ${USE_BLOSC}) +set(OpenVDB_USES_LOG4CPLUS ${USE_LOG4CPLUS}) +set(OpenVDB_USES_ILM ${USE_EXR}) +set(OpenVDB_USES_EXR ${USE_EXR}) + +# Search for optional dependencies + +foreach(PREREQUISITE ${_OPENVDB_PREREQUISITE_LIST}) + set(_HAS_DEP) + get_filename_component(PREREQUISITE ${PREREQUISITE} NAME) + + string(FIND ${PREREQUISITE} "blosc" _HAS_DEP) + if(NOT ${_HAS_DEP} EQUAL -1) + set(OpenVDB_USES_BLOSC ON) + endif() + + string(FIND ${PREREQUISITE} "log4cplus" _HAS_DEP) + if(NOT ${_HAS_DEP} EQUAL -1) + set(OpenVDB_USES_LOG4CPLUS ON) + endif() + + string(FIND ${PREREQUISITE} "IlmImf" _HAS_DEP) + if(NOT ${_HAS_DEP} EQUAL -1) + set(OpenVDB_USES_ILM ON) + endif() +endforeach() + +unset(_OPENVDB_PREREQUISITE_LIST) +unset(_HAS_DEP) + +if(OpenVDB_USES_BLOSC) + find_package(Blosc ) + if(NOT Blosc_FOUND OR NOT TARGET Blosc::blosc) + message(STATUS "find_package could not find Blosc. Using fallback blosc search...") + find_path(Blosc_INCLUDE_DIR blosc.h) + find_library(Blosc_LIBRARY NAMES blosc) + if (Blosc_INCLUDE_DIR AND Blosc_LIBRARY) + set(Blosc_FOUND TRUE) + add_library(Blosc::blosc UNKNOWN IMPORTED) + set_target_properties(Blosc::blosc PROPERTIES + IMPORTED_LOCATION "${Blosc_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES ${Blosc_INCLUDE_DIR}) + elseif() + message(FATAL_ERROR "Blosc library can not be found!") + endif() + endif() +endif() + +if(OpenVDB_USES_LOG4CPLUS) + find_package(Log4cplus REQUIRED) +endif() + +if(OpenVDB_USES_ILM) + find_package(IlmBase REQUIRED) +endif() + +if(OpenVDB_USES_EXR) + find_package(OpenEXR REQUIRED) +endif() + +if(UNIX) + find_package(Threads REQUIRED) +endif() + +# Set deps. Note that the order here is important. If we're building against +# Houdini 17.5 we must include OpenEXR and IlmBase deps first to ensure the +# users chosen namespaced headers are correctly prioritized. Otherwise other +# include paths from shared installs (including houdini) may pull in the wrong +# headers + +set(_OPENVDB_VISIBLE_DEPENDENCIES + Boost::iostreams + Boost::system + IlmBase::Half +) + +set(_OPENVDB_DEFINITIONS) +if(OpenVDB_ABI) + list(APPEND _OPENVDB_DEFINITIONS "-DOPENVDB_ABI_VERSION_NUMBER=${OpenVDB_ABI}") +endif() + +if(OpenVDB_USES_EXR) + list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES + IlmBase::IlmThread + IlmBase::Iex + IlmBase::Imath + OpenEXR::IlmImf + ) + list(APPEND _OPENVDB_DEFINITIONS "-DOPENVDB_TOOLS_RAYTRACER_USE_EXR") +endif() + +if(OpenVDB_USES_LOG4CPLUS) + list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES Log4cplus::log4cplus) + list(APPEND _OPENVDB_DEFINITIONS "-DOPENVDB_USE_LOG4CPLUS") +endif() + +list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES + TBB::tbb +) +if(UNIX) + list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES + Threads::Threads + ) +endif() + +set(_OPENVDB_HIDDEN_DEPENDENCIES) + +if(OpenVDB_USES_BLOSC) + if(OPENVDB_USE_STATIC_LIBS) + list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES $) + else() + list(APPEND _OPENVDB_HIDDEN_DEPENDENCIES Blosc::blosc) + endif() +endif() + +if(OPENVDB_USE_STATIC_LIBS) + list(APPEND _OPENVDB_VISIBLE_DEPENDENCIES $) +else() + list(APPEND _OPENVDB_HIDDEN_DEPENDENCIES ZLIB::ZLIB) +endif() + +# ------------------------------------------------------------------------ +# Configure imported target +# ------------------------------------------------------------------------ + +set(OpenVDB_LIBRARIES + ${OpenVDB_LIB_COMPONENTS} +) +set(OpenVDB_INCLUDE_DIRS ${OpenVDB_INCLUDE_DIR}) + +set(OpenVDB_DEFINITIONS) +list(APPEND OpenVDB_DEFINITIONS "${PC_OpenVDB_CFLAGS_OTHER}") +list(APPEND OpenVDB_DEFINITIONS "${_OPENVDB_DEFINITIONS}") +list(REMOVE_DUPLICATES OpenVDB_DEFINITIONS) + +set(OpenVDB_LIBRARY_DIRS "") +foreach(LIB ${OpenVDB_LIB_COMPONENTS}) + get_filename_component(_OPENVDB_LIBDIR ${LIB} DIRECTORY) + list(APPEND OpenVDB_LIBRARY_DIRS ${_OPENVDB_LIBDIR}) +endforeach() +list(REMOVE_DUPLICATES OpenVDB_LIBRARY_DIRS) + +foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) + if(NOT TARGET OpenVDB::${COMPONENT}) + add_library(OpenVDB::${COMPONENT} UNKNOWN IMPORTED) + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + IMPORTED_LOCATION "${OpenVDB_${COMPONENT}_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${OpenVDB_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${OpenVDB_INCLUDE_DIR}" + IMPORTED_LINK_DEPENDENT_LIBRARIES "${_OPENVDB_HIDDEN_DEPENDENCIES}" # non visible deps + INTERFACE_LINK_LIBRARIES "${_OPENVDB_VISIBLE_DEPENDENCIES}" # visible deps (headers) + INTERFACE_COMPILE_FEATURES cxx_std_11 + ) + + if (OPENVDB_USE_STATIC_LIBS) + set_target_properties(OpenVDB::${COMPONENT} PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" + ) + endif() + endif() +endforeach() + +if(OpenVDB_FOUND AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + message(STATUS "OpenVDB libraries: ${OpenVDB_LIBRARIES}") +endif() + +unset(_OPENVDB_DEFINITIONS) +unset(_OPENVDB_VISIBLE_DEPENDENCIES) +unset(_OPENVDB_HIDDEN_DEPENDENCIES) diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index b09bafda3a..3b9f46b962 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -93,8 +93,16 @@ # This module will also create the "tbb" target that may be used when building # executables and libraries. +unset(TBB_FOUND CACHE) +unset(TBB_INCLUDE_DIRS CACHE) +unset(TBB_LIBRARIES) +unset(TBB_LIBRARIES_DEBUG) +unset(TBB_LIBRARIES_RELEASE) + include(FindPackageHandleStandardArgs) +find_package(Threads QUIET REQUIRED) + if(NOT TBB_FOUND) ################################## @@ -215,6 +223,9 @@ if(NOT TBB_FOUND) foreach(_comp ${TBB_SEARCH_COMPOMPONENTS}) if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};") + unset(TBB_${_comp}_LIBRARY_DEBUG CACHE) + unset(TBB_${_comp}_LIBRARY_RELEASE CACHE) + # Search for the libraries find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX} HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} @@ -261,6 +272,7 @@ if(NOT TBB_FOUND) set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") endif() + set(TBB_DEFINITIONS "") if (MSVC AND TBB_STATIC) set(TBB_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE) endif () @@ -269,6 +281,7 @@ if(NOT TBB_FOUND) find_package_handle_standard_args(TBB REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES + FAIL_MESSAGE "TBB library cannot be found. Consider set TBBROOT environment variable." HANDLE_COMPONENTS VERSION_VAR TBB_VERSION) @@ -279,6 +292,8 @@ if(NOT TBB_FOUND) if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND) add_library(TBB::tbb UNKNOWN IMPORTED) set_target_properties(TBB::tbb PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS}" + INTERFACE_LINK_LIBRARIES "Threads::Threads;${CMAKE_DL_LIBS}" INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS} IMPORTED_LOCATION ${TBB_LIBRARIES}) if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) @@ -290,11 +305,6 @@ if(NOT TBB_FOUND) IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE} ) endif() - - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_package(Threads QUIET REQUIRED) - set_target_properties(TBB::tbb PROPERTIES INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS};Threads::Threads") - endif() endif() mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES) diff --git a/cmake/modules/OpenVDBUtils.cmake b/cmake/modules/OpenVDBUtils.cmake new file mode 100644 index 0000000000..bb3ce6e65d --- /dev/null +++ b/cmake/modules/OpenVDBUtils.cmake @@ -0,0 +1,166 @@ +# Copyright (c) DreamWorks Animation LLC +# +# All rights reserved. This software is distributed under the +# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) +# +# Redistributions of source code must retain the above copyright +# and license notice and the following restrictions and disclaimer. +# +# * Neither the name of DreamWorks Animation nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. +# +#[=======================================================================[.rst: + +OpenVDBUtils.cmake +------------------ + +A utility CMake file which provides helper functions for configuring an +OpenVDB installation. + +Use this module by invoking include with the form:: + + include ( OpenVDBUtils ) + + +The following functions are provided: + +``OPENVDB_VERSION_FROM_HEADER`` + + OPENVDB_VERSION_FROM_HEADER ( + VERSION [] + MAJOR [] + MINOR [] + PATCH [] ) + + Parse the provided version file to retrieve the current OpenVDB + version information. The file is expected to be a version.h file + as found in the following path of an OpenVDB repository: + openvdb/version.h + + If the file does not exist, variables are unmodified. + +``OPENVDB_ABI_VERSION_FROM_PRINT`` + + OPENVDB_ABI_VERSION_FROM_PRINT ( + [QUIET] + ABI [] ) + + Retrieve the ABI version that an installation of OpenVDB was compiled + for using the provided vdb_print binary. Parses the result of: + vdb_print --version + + If the binary does not exist or fails to launch, variables are + unmodified. + +#]=======================================================================] + + +function(OPENVDB_VERSION_FROM_HEADER OPENVDB_VERSION_FILE) + cmake_parse_arguments(_VDB "" "VERSION;MAJOR;MINOR;PATCH" "" ${ARGN}) + + if(NOT EXISTS ${OPENVDB_VERSION_FILE}) + return() + endif() + + file(STRINGS "${OPENVDB_VERSION_FILE}" openvdb_version_str + REGEX "^#define[\t ]+OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER[\t ]+.*" + ) + string(REGEX REPLACE "^.*OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER[\t ]+([0-9]*).*$" "\\1" + _OpenVDB_MAJOR_VERSION "${openvdb_version_str}" + ) + + file(STRINGS "${OPENVDB_VERSION_FILE}" openvdb_version_str + REGEX "^#define[\t ]+OPENVDB_LIBRARY_MINOR_VERSION_NUMBER[\t ]+.*" + ) + string(REGEX REPLACE "^.*OPENVDB_LIBRARY_MINOR_VERSION_NUMBER[\t ]+([0-9]*).*$" "\\1" + _OpenVDB_MINOR_VERSION "${openvdb_version_str}" + ) + + file(STRINGS "${OPENVDB_VERSION_FILE}" openvdb_version_str + REGEX "^#define[\t ]+OPENVDB_LIBRARY_PATCH_VERSION_NUMBER[\t ]+.*" + ) + string(REGEX REPLACE "^.*OPENVDB_LIBRARY_PATCH_VERSION_NUMBER[\t ]+([0-9]*).*$" "\\1" + _OpenVDB_PATCH_VERSION "${openvdb_version_str}" + ) + unset(openvdb_version_str) + + if(_VDB_VERSION) + set(${_VDB_VERSION} + ${_OpenVDB_MAJOR_VERSION}.${_OpenVDB_MINOR_VERSION}.${_OpenVDB_PATCH_VERSION} + PARENT_SCOPE + ) + endif() + if(_VDB_MAJOR) + set(${_VDB_MAJOR} ${_OpenVDB_MAJOR_VERSION} PARENT_SCOPE) + endif() + if(_VDB_MINOR) + set(${_VDB_MINOR} ${_OpenVDB_MINOR_VERSION} PARENT_SCOPE) + endif() + if(_VDB_PATCH) + set(${_VDB_PATCH} ${_OpenVDB_PATCH_VERSION} PARENT_SCOPE) + endif() +endfunction() + + +######################################################################## +######################################################################## + + +function(OPENVDB_ABI_VERSION_FROM_PRINT OPENVDB_PRINT) + cmake_parse_arguments(_VDB "QUIET" "ABI" "" ${ARGN}) + + if(NOT EXISTS ${OPENVDB_PRINT}) + message(WARNING "vdb_print not found! ${OPENVDB_PRINT}") + return() + endif() + + set(_VDB_PRINT_VERSION_STRING "") + set(_VDB_PRINT_RETURN_STATUS "") + + if(${_VDB_QUIET}) + execute_process(COMMAND ${OPENVDB_PRINT} "--version" + RESULT_VARIABLE _VDB_PRINT_RETURN_STATUS + OUTPUT_VARIABLE _VDB_PRINT_VERSION_STRING + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + execute_process(COMMAND ${OPENVDB_PRINT} "--version" + RESULT_VARIABLE _VDB_PRINT_RETURN_STATUS + OUTPUT_VARIABLE _VDB_PRINT_VERSION_STRING + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + + if(${_VDB_PRINT_RETURN_STATUS}) + message(WARNING "vdb_print returned with status ${_VDB_PRINT_RETURN_STATUS}") + return() + endif() + + set(_OpenVDB_ABI) + string(REGEX REPLACE ".*abi([0-9]*).*" "\\1" _OpenVDB_ABI ${_VDB_PRINT_VERSION_STRING}) + if(${_OpenVDB_ABI} STREQUAL ${_VDB_PRINT_VERSION_STRING}) + set(_OpenVDB_ABI "") + endif() + unset(_VDB_PRINT_RETURN_STATUS) + unset(_VDB_PRINT_VERSION_STRING) + + if(_VDB_ABI) + set(${_VDB_ABI} ${_OpenVDB_ABI} PARENT_SCOPE) + endif() +endfunction() diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 90ad6f0fa7..09e6c75982 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -96,6 +96,7 @@ if (MSVC) dep_nlopt # dep_qhull # Experimental dep_zlib # on Windows we still need zlib + dep_openvdb ) else() @@ -110,6 +111,7 @@ else() dep_cereal dep_nlopt dep_qhull + dep_openvdb # dep_libigl # Not working, static build has different Eigen ) diff --git a/deps/blosc-mods.patch b/deps/blosc-mods.patch new file mode 100644 index 0000000000..2289459ab5 --- /dev/null +++ b/deps/blosc-mods.patch @@ -0,0 +1,477 @@ +From 24640a466b28dfda26069096554676e8c0b6d090 Mon Sep 17 00:00:00 2001 +From: tamasmeszaros +Date: Tue, 22 Oct 2019 11:29:05 +0200 +Subject: [PATCH] Install.dll in prefix/bin and add config export to cmake + build + +--- + CMakeLists.txt | 112 ++++++++++++++++++++---------------- + blosc/CMakeLists.txt | 121 ++++++++++----------------------------- + cmake/FindLZ4.cmake | 6 +- + cmake/FindSnappy.cmake | 8 ++- + cmake/FindZstd.cmake | 8 ++- + cmake_config.cmake.in | 33 +++++++++++ + internal-complibs/CMakeLists.txt | 30 ++++++++++ + 7 files changed, 173 insertions(+), 145 deletions(-) + create mode 100644 cmake_config.cmake.in + create mode 100644 internal-complibs/CMakeLists.txt + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 59d9fab..bdc0dda 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -71,7 +71,7 @@ + # DEV: static includes blosc.a and blosc.h + + +-cmake_minimum_required(VERSION 2.8.12) ++cmake_minimum_required(VERSION 3.1) # Threads::Threads target available from 3.1 + if (NOT CMAKE_VERSION VERSION_LESS 3.3) + cmake_policy(SET CMP0063 NEW) + endif() +@@ -124,55 +124,37 @@ option(PREFER_EXTERNAL_ZSTD + + set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + ++set(PRIVATE_LIBS "") ++set(PUBLIC_LIBS "") ++set(PUBLIC_PACKAGES "" CACHE INTERNAL "") ++macro(use_package _pkg _tgt) ++ string(TOUPPER ${_pkg} _PKG) ++ if(NOT DEACTIVATE_${_PKG}) ++ if(PREFER_EXTERNAL_${_PKG}) ++ find_package(${_pkg}) ++ if (NOT ${_pkg}_FOUND ) ++ message(STATUS "No ${_pkg} found. Using internal sources.") ++ endif() ++ else() ++ message(STATUS "Using ${_pkg} internal sources.") ++ endif(PREFER_EXTERNAL_${_PKG}) ++ # HAVE_${_pkg} will be set to true because even if the library is ++ # not found, we will use the included sources for it ++ set(HAVE_${_PKG} TRUE) ++ if (${_pkg}_FOUND) ++ list(APPEND PUBLIC_LIBS ${_pkg}::${_tgt}) ++ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};${_pkg}" CACHE INTERNAL "") ++ else() ++ list(APPEND PRIVATE_LIBS ${_pkg}::${_tgt}) ++ endif() ++ endif(NOT DEACTIVATE_${_PKG}) ++endmacro() + +-if(NOT DEACTIVATE_LZ4) +- if(PREFER_EXTERNAL_LZ4) +- find_package(LZ4) +- else() +- message(STATUS "Using LZ4 internal sources.") +- endif(PREFER_EXTERNAL_LZ4) +- # HAVE_LZ4 will be set to true because even if the library is +- # not found, we will use the included sources for it +- set(HAVE_LZ4 TRUE) +-endif(NOT DEACTIVATE_LZ4) +- +-if(NOT DEACTIVATE_SNAPPY) +- if(PREFER_EXTERNAL_SNAPPY) +- find_package(Snappy) +- else() +- message(STATUS "Using Snappy internal sources.") +- endif(PREFER_EXTERNAL_SNAPPY) +- # HAVE_SNAPPY will be set to true because even if the library is not found, +- # we will use the included sources for it +- set(HAVE_SNAPPY TRUE) +-endif(NOT DEACTIVATE_SNAPPY) +- +-if(NOT DEACTIVATE_ZLIB) +- # import the ZLIB_ROOT environment variable to help finding the zlib library +- if(PREFER_EXTERNAL_ZLIB) +- set(ZLIB_ROOT $ENV{ZLIB_ROOT}) +- find_package(ZLIB) +- if (NOT ZLIB_FOUND ) +- message(STATUS "No zlib found. Using internal sources.") +- endif (NOT ZLIB_FOUND ) +- else() +- message(STATUS "Using zlib internal sources.") +- endif(PREFER_EXTERNAL_ZLIB) +- # HAVE_ZLIB will be set to true because even if the library is not found, +- # we will use the included sources for it +- set(HAVE_ZLIB TRUE) +-endif(NOT DEACTIVATE_ZLIB) +- +-if (NOT DEACTIVATE_ZSTD) +- if (PREFER_EXTERNAL_ZSTD) +- find_package(Zstd) +- else () +- message(STATUS "Using ZSTD internal sources.") +- endif (PREFER_EXTERNAL_ZSTD) +- # HAVE_ZSTD will be set to true because even if the library is +- # not found, we will use the included sources for it +- set(HAVE_ZSTD TRUE) +-endif (NOT DEACTIVATE_ZSTD) ++set(ZLIB_ROOT $ENV{ZLIB_ROOT}) ++use_package(ZLIB ZLIB) ++use_package(LZ4 LZ4) ++use_package(Snappy snappy) ++use_package(Zstd Zstd) + + # create the config.h file + configure_file ("blosc/config.h.in" "blosc/config.h" ) +@@ -316,6 +298,7 @@ endif() + + + # subdirectories ++add_subdirectory(internal-complibs) + add_subdirectory(blosc) + + if(BUILD_TESTS) +@@ -338,10 +321,41 @@ if (BLOSC_INSTALL) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/blosc.pc" + DESTINATION lib/pkgconfig COMPONENT DEV) + ++ configure_file( ++ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_config.cmake.in" ++ "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfig.cmake" ++ @ONLY) ++ + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) ++ ++ include(CMakePackageConfigHelpers) ++ write_basic_package_version_file( ++ "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfigVersion.cmake" ++ VERSION ${BLOSC_VERSION_MAJOR}.${BLOSC_VERSION_MINOR}.${BLOSC_VERSION_PATCH} ++ COMPATIBILITY AnyNewerVersion ++ ) ++ ++ export(EXPORT BloscTargets ++ FILE "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscTargets.cmake" ++ NAMESPACE Blosc::) ++ ++ install(EXPORT BloscTargets ++ FILE BloscTargets.cmake ++ NAMESPACE Blosc:: ++ DESTINATION lib/cmake/Blosc ++ EXPORT_LINK_INTERFACE_LIBRARIES) ++ ++ install(FILES ++ "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfig.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfigVersion.cmake" ++ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLZ4.cmake" ++ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindZstd.cmake" ++ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindSnappy.cmake" ++ DESTINATION lib/cmake/Blosc COMPONENT DEV) ++ + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + endif() +diff --git a/blosc/CMakeLists.txt b/blosc/CMakeLists.txt +index 1d1bebe..16aff02 100644 +--- a/blosc/CMakeLists.txt ++++ b/blosc/CMakeLists.txt +@@ -1,52 +1,11 @@ + # a simple way to detect that we are using CMAKE + add_definitions(-DUSING_CMAKE) + +-set(INTERNAL_LIBS ${PROJECT_SOURCE_DIR}/internal-complibs) +- + # Hide symbols by default unless they're specifically exported. + # This makes it easier to keep the set of exported symbols the + # same across all compilers/platforms. + set(CMAKE_C_VISIBILITY_PRESET hidden) + +-# includes +-set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}) +-if(NOT DEACTIVATE_LZ4) +- if (LZ4_FOUND) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${LZ4_INCLUDE_DIR}) +- else(LZ4_FOUND) +- set(LZ4_LOCAL_DIR ${INTERNAL_LIBS}/lz4-1.9.1) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${LZ4_LOCAL_DIR}) +- endif(LZ4_FOUND) +-endif(NOT DEACTIVATE_LZ4) +- +-if(NOT DEACTIVATE_SNAPPY) +- if (SNAPPY_FOUND) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${SNAPPY_INCLUDE_DIR}) +- else(SNAPPY_FOUND) +- set(SNAPPY_LOCAL_DIR ${INTERNAL_LIBS}/snappy-1.1.1) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${SNAPPY_LOCAL_DIR}) +- endif(SNAPPY_FOUND) +-endif(NOT DEACTIVATE_SNAPPY) +- +-if(NOT DEACTIVATE_ZLIB) +- if (ZLIB_FOUND) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}) +- else(ZLIB_FOUND) +- set(ZLIB_LOCAL_DIR ${INTERNAL_LIBS}/zlib-1.2.8) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${ZLIB_LOCAL_DIR}) +- endif(ZLIB_FOUND) +-endif(NOT DEACTIVATE_ZLIB) +- +-if (NOT DEACTIVATE_ZSTD) +- if (ZSTD_FOUND) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${ZSTD_INCLUDE_DIR}) +- else (ZSTD_FOUND) +- set(ZSTD_LOCAL_DIR ${INTERNAL_LIBS}/zstd-1.4.1) +- set(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIRS} ${ZSTD_LOCAL_DIR} ${ZSTD_LOCAL_DIR}/common) +- endif (ZSTD_FOUND) +-endif (NOT DEACTIVATE_ZSTD) +- +-include_directories(${BLOSC_INCLUDE_DIRS}) + + # library sources + set(SOURCES blosc.c blosclz.c fastcopy.c shuffle-generic.c bitshuffle-generic.c +@@ -73,53 +32,15 @@ if(WIN32) + message(STATUS "using the internal pthread library for win32 systems.") + set(SOURCES ${SOURCES} win32/pthread.c) + else(NOT Threads_FOUND) +- set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) ++ list(APPEND PUBLIC_LIBS Threads::Threads) ++ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};Threads" CACHE INTERNAL "") + endif(NOT Threads_FOUND) + else(WIN32) + find_package(Threads REQUIRED) +- set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) ++ list(APPEND PUBLIC_LIBS Threads::Threads) ++ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};Threads" CACHE INTERNAL "") + endif(WIN32) + +-if(NOT DEACTIVATE_LZ4) +- if(LZ4_FOUND) +- set(LIBS ${LIBS} ${LZ4_LIBRARY}) +- else(LZ4_FOUND) +- file(GLOB LZ4_FILES ${LZ4_LOCAL_DIR}/*.c) +- set(SOURCES ${SOURCES} ${LZ4_FILES}) +- endif(LZ4_FOUND) +-endif(NOT DEACTIVATE_LZ4) +- +-if(NOT DEACTIVATE_SNAPPY) +- if(SNAPPY_FOUND) +- set(LIBS ${LIBS} ${SNAPPY_LIBRARY}) +- else(SNAPPY_FOUND) +- file(GLOB SNAPPY_FILES ${SNAPPY_LOCAL_DIR}/*.cc) +- set(SOURCES ${SOURCES} ${SNAPPY_FILES}) +- endif(SNAPPY_FOUND) +-endif(NOT DEACTIVATE_SNAPPY) +- +-if(NOT DEACTIVATE_ZLIB) +- if(ZLIB_FOUND) +- set(LIBS ${LIBS} ${ZLIB_LIBRARY}) +- else(ZLIB_FOUND) +- file(GLOB ZLIB_FILES ${ZLIB_LOCAL_DIR}/*.c) +- set(SOURCES ${SOURCES} ${ZLIB_FILES}) +- endif(ZLIB_FOUND) +-endif(NOT DEACTIVATE_ZLIB) +- +-if (NOT DEACTIVATE_ZSTD) +- if (ZSTD_FOUND) +- set(LIBS ${LIBS} ${ZSTD_LIBRARY}) +- else (ZSTD_FOUND) +- file(GLOB ZSTD_FILES +- ${ZSTD_LOCAL_DIR}/common/*.c +- ${ZSTD_LOCAL_DIR}/compress/*.c +- ${ZSTD_LOCAL_DIR}/decompress/*.c) +- set(SOURCES ${SOURCES} ${ZSTD_FILES}) +- endif (ZSTD_FOUND) +-endif (NOT DEACTIVATE_ZSTD) +- +- + # targets + if (BUILD_SHARED) + add_library(blosc_shared SHARED ${SOURCES}) +@@ -191,14 +112,18 @@ if (BUILD_TESTS) + endif() + endif() + ++add_library(blosc INTERFACE) ++ + if (BUILD_SHARED) +- target_link_libraries(blosc_shared ${LIBS}) +- target_include_directories(blosc_shared PUBLIC ${BLOSC_INCLUDE_DIRS}) ++ target_link_libraries(blosc_shared PUBLIC ${PUBLIC_LIBS}) ++ target_link_libraries(blosc_shared PRIVATE ${PRIVATE_LIBS}) ++ target_include_directories(blosc_shared PUBLIC $) ++ target_link_libraries(blosc INTERFACE blosc_shared) + endif() + + if (BUILD_TESTS) +- target_link_libraries(blosc_shared_testing ${LIBS}) +- target_include_directories(blosc_shared_testing PUBLIC ${BLOSC_INCLUDE_DIRS}) ++ target_link_libraries(blosc_shared_testing ${PUBLIC_LIBS} ${PRIVATE_LIBS}) ++ target_include_directories(blosc_shared_testing PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + + if(BUILD_STATIC) +@@ -207,17 +132,31 @@ if(BUILD_STATIC) + if (MSVC) + set_target_properties(blosc_static PROPERTIES PREFIX lib) + endif() +- target_link_libraries(blosc_static ${LIBS}) +- target_include_directories(blosc_static PUBLIC ${BLOSC_INCLUDE_DIRS}) ++ target_link_libraries(blosc_static PUBLIC ${PUBLIC_LIBS}) ++ target_link_libraries(blosc_static PRIVATE ${PRIVATE_LIBS}) ++ target_include_directories(blosc_static PUBLIC $) ++ if (NOT BUILD_SHARED) ++ target_link_libraries(blosc INTERFACE blosc_static) ++ endif() + endif(BUILD_STATIC) + ++ + # install + if(BLOSC_INSTALL) + install(FILES blosc.h blosc-export.h DESTINATION include COMPONENT DEV) ++ set(_inst_libs "blosc") + if(BUILD_SHARED) +- install(TARGETS blosc_shared DESTINATION ${lib_dir} COMPONENT LIB) ++ list(APPEND _inst_libs blosc_shared) + endif(BUILD_SHARED) + if(BUILD_STATIC) +- install(TARGETS blosc_static DESTINATION ${lib_dir} COMPONENT DEV) ++ list(APPEND _inst_libs blosc_static) + endif(BUILD_STATIC) ++ ++ install(TARGETS ${_inst_libs} ++ EXPORT BloscTargets ++ LIBRARY DESTINATION ${lib_dir} ++ ARCHIVE DESTINATION ${lib_dir} ++ RUNTIME DESTINATION bin ++ COMPONENT DEV ++ INCLUDES DESTINATION include) + endif(BLOSC_INSTALL) +diff --git a/cmake/FindLZ4.cmake b/cmake/FindLZ4.cmake +index e581a80..05de6ef 100644 +--- a/cmake/FindLZ4.cmake ++++ b/cmake/FindLZ4.cmake +@@ -5,6 +5,10 @@ find_library(LZ4_LIBRARY NAMES lz4) + if (LZ4_INCLUDE_DIR AND LZ4_LIBRARY) + set(LZ4_FOUND TRUE) + message(STATUS "Found LZ4 library: ${LZ4_LIBRARY}") ++ add_library(LZ4::LZ4 UNKNOWN IMPORTED) ++ set_target_properties(LZ4::LZ4 PROPERTIES ++ IMPORTED_LOCATION ${LZ4_LIBRARY} ++ INTERFACE_INCLUDE_DIRECTORIES ${LZ4_INCLUDE_DIR}) + else () + message(STATUS "No LZ4 library found. Using internal sources.") +-endif () ++endif () +\ No newline at end of file +diff --git a/cmake/FindSnappy.cmake b/cmake/FindSnappy.cmake +index 688d4d5..21dbee1 100644 +--- a/cmake/FindSnappy.cmake ++++ b/cmake/FindSnappy.cmake +@@ -3,8 +3,12 @@ find_path(SNAPPY_INCLUDE_DIR snappy-c.h) + find_library(SNAPPY_LIBRARY NAMES snappy) + + if (SNAPPY_INCLUDE_DIR AND SNAPPY_LIBRARY) +- set(SNAPPY_FOUND TRUE) ++ set(Snappy_FOUND TRUE) ++ add_library(Snappy::snappy UNKNOWN IMPORTED) ++ set_target_properties(Snappy::snappy PROPERTIES ++ IMPORTED_LOCATION ${SNAPPY_LIBRARY} ++ INTERFACE_INCLUDE_DIRECTORIES ${SNAPPY_INCLUDE_DIR}) + message(STATUS "Found SNAPPY library: ${SNAPPY_LIBRARY}") + else () + message(STATUS "No snappy found. Using internal sources.") +-endif () ++endif () +\ No newline at end of file +diff --git a/cmake/FindZstd.cmake b/cmake/FindZstd.cmake +index 7db4bb9..cabc2f8 100644 +--- a/cmake/FindZstd.cmake ++++ b/cmake/FindZstd.cmake +@@ -3,8 +3,12 @@ find_path(ZSTD_INCLUDE_DIR zstd.h) + find_library(ZSTD_LIBRARY NAMES zstd) + + if (ZSTD_INCLUDE_DIR AND ZSTD_LIBRARY) +- set(ZSTD_FOUND TRUE) ++ set(Zstd_FOUND TRUE) ++ add_library(Zstd::Zstd UNKNOWN IMPORTED) ++ set_target_properties(Zstd::Zstd PROPERTIES ++ IMPORTED_LOCATION ${ZSTD_LIBRARY} ++ INTERFACE_INCLUDE_DIRECTORIES ${ZSTD_INCLUDE_DIR}) + message(STATUS "Found Zstd library: ${ZSTD_LIBRARY}") + else () + message(STATUS "No Zstd library found. Using internal sources.") +-endif () ++endif () +\ No newline at end of file +diff --git a/cmake_config.cmake.in b/cmake_config.cmake.in +new file mode 100644 +index 0000000..b4ede30 +--- /dev/null ++++ b/cmake_config.cmake.in +@@ -0,0 +1,33 @@ ++include(CMakeFindDependencyMacro) ++ ++list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) ++ ++set(_deps "@PUBLIC_PACKAGES@") ++ ++foreach(pkg ${_deps}) ++ # no minimum versions are required by upstream ++ find_dependency(${pkg}) ++endforeach() ++ ++include("${CMAKE_CURRENT_LIST_DIR}/BloscTargets.cmake") ++ ++function(remap_configs from_Cfg to_Cfg) ++ string(TOUPPER ${from_Cfg} from_CFG) ++ string(TOLOWER ${from_Cfg} from_cfg) ++ ++ if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/BloscTargets-${from_cfg}.cmake) ++ foreach(tgt IN ITEMS blosc_static blosc_shared blosc) ++ if(TARGET Blosc::${tgt}) ++ set_target_properties(Blosc::${tgt} PROPERTIES ++ MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg}) ++ endif() ++ endforeach() ++ endif() ++endfunction() ++ ++# MSVC will try to link RelWithDebInfo or MinSizeRel target with debug config ++# if no matching installation is present which would result in link errors. ++if(MSVC) ++ remap_configs(RelWithDebInfo Release) ++ remap_configs(MinSizeRel Release) ++endif() +diff --git a/internal-complibs/CMakeLists.txt b/internal-complibs/CMakeLists.txt +new file mode 100644 +index 0000000..5b23484 +--- /dev/null ++++ b/internal-complibs/CMakeLists.txt +@@ -0,0 +1,30 @@ ++macro(add_lib_target pkg tgt incdir files) ++ string(TOUPPER ${pkg} TGT) ++ if(NOT DEACTIVATE_${TGT} AND NOT ${pkg}_FOUND) ++ add_library(${tgt} INTERFACE) ++ target_include_directories(${tgt} INTERFACE $) ++ target_sources(${tgt} INTERFACE "$") ++ add_library(${pkg}::${tgt} ALIAS ${tgt}) ++ ++ # This creates dummy (empty) interface targets in the exported config. ++ install(TARGETS ${tgt} EXPORT BloscTargets INCLUDES DESTINATION include) ++ endif() ++ unset(TGT) ++endmacro() ++ ++set(ZLIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zlib-1.2.8) ++file(GLOB ZLIB_FILES ${ZLIB_DIR}/*.c) ++add_lib_target(ZLIB ZLIB ${ZLIB_DIR} "${ZLIB_FILES}") ++ ++set(SNAPPY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/snappy-1.1.1) ++file(GLOB SNAPPY_FILES ${SNAPPY_DIR}/*.cc) ++add_lib_target(Snappy snappy ${SNAPPY_DIR} "${SNAPPY_FILES}") ++ ++set(LZ4_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lz4-1.9.1) ++file(GLOB LZ4_FILES ${LZ4_DIR}/*.c) ++add_lib_target(LZ4 LZ4 ${LZ4_DIR} "${LZ4_FILES}") ++ ++set(ZSTD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zstd-1.4.1) ++file(GLOB ZSTD_FILES ${ZSTD_DIR}/common/*.c ${ZSTD_DIR}/compress/*.c ${ZSTD_DIR}/decompress/*.c) ++add_lib_target(Zstd Zstd ${ZSTD_DIR} "${ZSTD_FILES}") ++target_include_directories(Zstd INTERFACE $) +\ No newline at end of file +-- +2.16.2.windows.1 + diff --git a/deps/deps-linux.cmake b/deps/deps-linux.cmake index 03e8e12d57..f5571d4704 100644 --- a/deps/deps-linux.cmake +++ b/deps/deps-linux.cmake @@ -5,11 +5,11 @@ include("deps-unix-common.cmake") ExternalProject_Add(dep_boost EXCLUDE_FROM_ALL 1 - URL "https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz" - URL_HASH SHA256=bd0df411efd9a585e5a2212275f8762079fed8842264954675a4fddc46cfcf60 + URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz" + URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./bootstrap.sh - --with-libraries=system,filesystem,thread,log,locale,regex + --with-libraries=system,iostreams,filesystem,thread,log,locale,regex "--prefix=${DESTDIR}/usr/local" BUILD_COMMAND ./b2 -j ${NPROC} @@ -123,3 +123,5 @@ ExternalProject_Add(dep_wxwidgets BUILD_COMMAND make "-j${NPROC}" && make -C locale allmo INSTALL_COMMAND make install ) + +add_dependencies(dep_openvdb dep_boost) \ No newline at end of file diff --git a/deps/deps-macos.cmake b/deps/deps-macos.cmake index d22e4a2e2c..e6fca8a726 100644 --- a/deps/deps-macos.cmake +++ b/deps/deps-macos.cmake @@ -25,7 +25,7 @@ ExternalProject_Add(dep_boost URL_HASH SHA256=bd0df411efd9a585e5a2212275f8762079fed8842264954675a4fddc46cfcf60 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./bootstrap.sh - --with-libraries=system,filesystem,thread,log,locale,regex + --with-libraries=system,iostreams,filesystem,thread,log,locale,regex "--prefix=${DESTDIR}/usr/local" BUILD_COMMAND ./b2 -j ${NPROC} @@ -114,3 +114,5 @@ ExternalProject_Add(dep_wxwidgets BUILD_COMMAND make "-j${NPROC}" && PATH=/usr/local/opt/gettext/bin/:$ENV{PATH} make -C locale allmo INSTALL_COMMAND make install ) + +add_dependencies(dep_openvdb dep_boost) \ No newline at end of file diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index 6e559d05a3..0df535fc31 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -53,8 +53,8 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz" - URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78 + URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -87,6 +87,58 @@ ExternalProject_Add(dep_libigl -DLIBIGL_WITH_TETGEN=OFF -DLIBIGL_WITH_TRIANGLE=OFF -DLIBIGL_WITH_XML=OFF - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch + PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch ) + +ExternalProject_Add(dep_blosc + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/Blosc/c-blosc.git + GIT_TAG v1.17.0 + DEPENDS + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DCMAKE_DEBUG_POSTFIX=d + -DBUILD_SHARED=OFF + -DBUILD_STATIC=ON + -DBUILD_TESTS=OFF + -DBUILD_BENCHMARKS=OFF + -DPREFER_EXTERNAL_ZLIB=OFF + PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch +) + +ExternalProject_Add(dep_openexr + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/openexr/openexr.git + GIT_TAG v2.4.0 + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DBUILD_TESTING=OFF + -DPYILMBASE_ENABLE:BOOL=OFF + -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF + -DOPENEXR_BUILD_UTILS:BOOL=OFF +) + +ExternalProject_Add(dep_openvdb + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git + GIT_TAG v6.2.1 + DEPENDS dep_blosc dep_openexr dep_tbb + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DCMAKE_DEBUG_POSTFIX=d + -DCMAKE_PREFIX_PATH=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DOPENVDB_BUILD_PYTHON_MODULE=OFF + -DUSE_BLOSC=ON + -DOPENVDB_CORE_SHARED=OFF + -DOPENVDB_CORE_STATIC=ON + -DTBB_STATIC=ON + -DOPENVDB_BUILD_VDB_PRINT=ON + PATCH_COMMAND ${GIT_EXECUTABLE} apply ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch +) \ No newline at end of file diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 85013fbddd..08e10758d3 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -43,6 +43,18 @@ else () set(DEP_BOOST_DEBUG "") endif () +macro(add_debug_dep _dep) +if (${DEP_DEBUG}) + ExternalProject_Get_Property(${_dep} BINARY_DIR) + ExternalProject_Add_Step(${_dep} build_debug + DEPENDEES build + DEPENDERS install + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj + WORKING_DIRECTORY "${BINARY_DIR}" + ) +endif () +endmacro() + ExternalProject_Add(dep_boost EXCLUDE_FROM_ALL 1 URL "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz" @@ -52,6 +64,7 @@ ExternalProject_Add(dep_boost BUILD_COMMAND b2.exe -j "${NPROC}" --with-system + --with-iostreams --with-filesystem --with-thread --with-log @@ -83,16 +96,8 @@ ExternalProject_Add(dep_tbb BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_tbb BINARY_DIR) - ExternalProject_Add_Step(dep_tbb build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () +add_debug_dep(dep_tbb) ExternalProject_Add(dep_gtest EXCLUDE_FROM_ALL 1 @@ -108,16 +113,8 @@ ExternalProject_Add(dep_gtest BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_gtest BINARY_DIR) - ExternalProject_Add_Step(dep_gtest build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () +add_debug_dep(dep_gtest) ExternalProject_Add(dep_cereal EXCLUDE_FROM_ALL 1 @@ -132,7 +129,6 @@ ExternalProject_Add(dep_cereal INSTALL_COMMAND "" ) - ExternalProject_Add(dep_nlopt EXCLUDE_FROM_ALL 1 URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz" @@ -151,16 +147,8 @@ ExternalProject_Add(dep_nlopt BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_nlopt BINARY_DIR) - ExternalProject_Add_Step(dep_nlopt build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () +add_debug_dep(dep_nlopt) ExternalProject_Add(dep_zlib EXCLUDE_FROM_ALL 1 @@ -176,15 +164,9 @@ ExternalProject_Add(dep_zlib BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_zlib BINARY_DIR) - ExternalProject_Add_Step(dep_zlib build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () + +add_debug_dep(dep_zlib) + # The following steps are unfortunately needed to remove the _static suffix on libraries ExternalProject_Add_Step(dep_zlib fix_static DEPENDEES install @@ -238,8 +220,8 @@ find_package(Git REQUIRED) ExternalProject_Add(dep_qhull EXCLUDE_FROM_ALL 1 - URL "https://github.com/qhull/qhull/archive/v7.2.1.tar.gz" - URL_HASH SHA256=6fc251e0b75467e00943bfb7191e986fce0e1f8f6f0251f9c6ce5a843821ea78 + URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz" + URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0 CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -251,16 +233,7 @@ ExternalProject_Add(dep_qhull INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_qhull BINARY_DIR) - ExternalProject_Add_Step(dep_qhull build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () - +add_debug_dep(dep_qhull) if (${DEPS_BITS} EQUAL 32) set(DEP_WXWIDGETS_TARGET "") @@ -300,20 +273,12 @@ ExternalProject_Add(dep_libigl -DLIBIGL_WITH_XML=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_DEBUG_POSTFIX=d - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-fixes.patch + PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) -if (${DEP_DEBUG}) - ExternalProject_Get_Property(dep_libigl BINARY_DIR) - ExternalProject_Add_Step(dep_libigl build_debug - DEPENDEES build - DEPENDERS install - COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj - WORKING_DIRECTORY "${BINARY_DIR}" - ) -endif () +add_debug_dep(dep_libigl) ExternalProject_Add(dep_wxwidgets EXCLUDE_FROM_ALL 1 @@ -337,3 +302,80 @@ if (${DEP_DEBUG}) WORKING_DIRECTORY "${SOURCE_DIR}" ) endif () + +ExternalProject_Add(dep_blosc + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/Blosc/c-blosc.git + GIT_TAG v1.17.0 + DEPENDS dep_zlib + CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DCMAKE_DEBUG_POSTFIX=d + -DBUILD_SHARED=OFF + -DBUILD_STATIC=ON + -DBUILD_TESTS=OFF + -DBUILD_BENCHMARKS=OFF + -DPREFER_EXTERNAL_ZLIB=ON + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj + INSTALL_COMMAND "" +) + +add_debug_dep(dep_blosc) + +ExternalProject_Add(dep_openexr + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/openexr/openexr.git + GIT_TAG v2.4.0 + DEPENDS dep_zlib + CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DBUILD_TESTING=OFF + -DPYILMBASE_ENABLE:BOOL=OFF + -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF + -DOPENEXR_BUILD_UTILS:BOOL=OFF + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj + INSTALL_COMMAND "" +) + +add_debug_dep(dep_openexr) + +ExternalProject_Add(dep_openvdb + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git + GIT_TAG v6.2.1 + DEPENDS dep_blosc dep_openexr dep_tbb + CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + -DCMAKE_DEBUG_POSTFIX=d + -DCMAKE_PREFIX_PATH=${DESTDIR}/usr/local + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DOPENVDB_BUILD_PYTHON_MODULE=OFF + -DUSE_BLOSC=ON + -DOPENVDB_CORE_SHARED=OFF + -DOPENVDB_CORE_STATIC=ON + -DTBB_STATIC=ON + -DOPENVDB_BUILD_VDB_PRINT=ON + BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch + INSTALL_COMMAND "" +) + +if (${DEP_DEBUG}) + ExternalProject_Get_Property(dep_openvdb BINARY_DIR) + ExternalProject_Add_Step(dep_openvdb build_debug + DEPENDEES build + DEPENDERS install + COMMAND ${CMAKE_COMMAND} ../dep_openvdb -DOPENVDB_BUILD_VDB_PRINT=OFF + COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj + WORKING_DIRECTORY "${BINARY_DIR}" + ) +endif () \ No newline at end of file diff --git a/deps/igl-fixes.patch b/deps/igl-mods.patch similarity index 100% rename from deps/igl-fixes.patch rename to deps/igl-mods.patch diff --git a/deps/openvdb-mods.patch b/deps/openvdb-mods.patch new file mode 100644 index 0000000000..a05076e986 --- /dev/null +++ b/deps/openvdb-mods.patch @@ -0,0 +1,1771 @@ +From ee867b9f226412c0f3b83fa01cd43539acc4ed95 Mon Sep 17 00:00:00 2001 +From: tamasmeszaros +Date: Wed, 16 Oct 2019 17:42:50 +0200 +Subject: [PATCH] Build fixes for PrusaSlicer integration + +--- + CMakeLists.txt | 3 - + cmake/FindBlosc.cmake | 218 --------------- + cmake/FindCppUnit.cmake | 4 +- + cmake/FindIlmBase.cmake | 337 ----------------------- + cmake/FindOpenEXR.cmake | 329 ---------------------- + cmake/FindOpenVDB.cmake | 19 +- + cmake/FindTBB.cmake | 593 ++++++++++++++++++++-------------------- + openvdb/CMakeLists.txt | 13 +- + openvdb/Grid.cc | 3 + + openvdb/PlatformConfig.h | 9 +- + openvdb/cmd/CMakeLists.txt | 4 +- + openvdb/unittest/CMakeLists.txt | 3 +- + openvdb/unittest/TestFile.cc | 2 +- + 13 files changed, 325 insertions(+), 1212 deletions(-) + delete mode 100644 cmake/FindBlosc.cmake + delete mode 100644 cmake/FindIlmBase.cmake + delete mode 100644 cmake/FindOpenEXR.cmake + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 580b353..6d364c1 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -267,12 +267,9 @@ endif() + + if(OPENVDB_INSTALL_CMAKE_MODULES) + set(OPENVDB_CMAKE_MODULES +- cmake/FindBlosc.cmake + cmake/FindCppUnit.cmake + cmake/FindJemalloc.cmake +- cmake/FindIlmBase.cmake + cmake/FindLog4cplus.cmake +- cmake/FindOpenEXR.cmake + cmake/FindOpenVDB.cmake + cmake/FindTBB.cmake + cmake/OpenVDBGLFW3Setup.cmake +diff --git a/cmake/FindBlosc.cmake b/cmake/FindBlosc.cmake +deleted file mode 100644 +index 5aacfdd..0000000 +--- a/cmake/FindBlosc.cmake ++++ /dev/null +@@ -1,218 +0,0 @@ +-# Copyright (c) DreamWorks Animation LLC +-# +-# All rights reserved. This software is distributed under the +-# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) +-# +-# Redistributions of source code must retain the above copyright +-# and license notice and the following restrictions and disclaimer. +-# +-# * Neither the name of DreamWorks Animation nor the names of +-# its contributors may be used to endorse or promote products derived +-# from this software without specific prior written permission. +-# +-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +-# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. +-# +-#[=======================================================================[.rst: +- +-FindBlosc +---------- +- +-Find Blosc include dirs and libraries +- +-Use this module by invoking find_package with the form:: +- +- find_package(Blosc +- [version] [EXACT] # Minimum or EXACT version e.g. 1.5.0 +- [REQUIRED] # Fail with error if Blosc is not found +- ) +- +-IMPORTED Targets +-^^^^^^^^^^^^^^^^ +- +-``Blosc::blosc`` +- This module defines IMPORTED target Blosc::Blosc, if Blosc has been found. +- +-Result Variables +-^^^^^^^^^^^^^^^^ +- +-This will define the following variables: +- +-``Blosc_FOUND`` +- True if the system has the Blosc library. +-``Blosc_VERSION`` +- The version of the Blosc library which was found. +-``Blosc_INCLUDE_DIRS`` +- Include directories needed to use Blosc. +-``Blosc_LIBRARIES`` +- Libraries needed to link to Blosc. +-``Blosc_LIBRARY_DIRS`` +- Blosc library directories. +- +-Cache Variables +-^^^^^^^^^^^^^^^ +- +-The following cache variables may also be set: +- +-``Blosc_INCLUDE_DIR`` +- The directory containing ``blosc.h``. +-``Blosc_LIBRARY`` +- The path to the Blosc library. +- +-Hints +-^^^^^ +- +-Instead of explicitly setting the cache variables, the following variables +-may be provided to tell this module where to look. +- +-``BLOSC_ROOT`` +- Preferred installation prefix. +-``BLOSC_INCLUDEDIR`` +- Preferred include directory e.g. /include +-``BLOSC_LIBRARYDIR`` +- Preferred library directory e.g. /lib +-``SYSTEM_LIBRARY_PATHS`` +- Paths appended to all include and lib searches. +- +-#]=======================================================================] +- +-mark_as_advanced( +- Blosc_INCLUDE_DIR +- Blosc_LIBRARY +-) +- +-# Append BLOSC_ROOT or $ENV{BLOSC_ROOT} if set (prioritize the direct cmake var) +-set(_BLOSC_ROOT_SEARCH_DIR "") +- +-if(BLOSC_ROOT) +- list(APPEND _BLOSC_ROOT_SEARCH_DIR ${BLOSC_ROOT}) +-else() +- set(_ENV_BLOSC_ROOT $ENV{BLOSC_ROOT}) +- if(_ENV_BLOSC_ROOT) +- list(APPEND _BLOSC_ROOT_SEARCH_DIR ${_ENV_BLOSC_ROOT}) +- endif() +-endif() +- +-# Additionally try and use pkconfig to find blosc +- +-find_package(PkgConfig) +-pkg_check_modules(PC_Blosc QUIET blosc) +- +-# ------------------------------------------------------------------------ +-# Search for blosc include DIR +-# ------------------------------------------------------------------------ +- +-set(_BLOSC_INCLUDE_SEARCH_DIRS "") +-list(APPEND _BLOSC_INCLUDE_SEARCH_DIRS +- ${BLOSC_INCLUDEDIR} +- ${_BLOSC_ROOT_SEARCH_DIR} +- ${PC_Blosc_INCLUDE_DIRS} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Look for a standard blosc header file. +-find_path(Blosc_INCLUDE_DIR blosc.h +- NO_DEFAULT_PATH +- PATHS ${_BLOSC_INCLUDE_SEARCH_DIRS} +- PATH_SUFFIXES include +-) +- +-if(EXISTS "${Blosc_INCLUDE_DIR}/blosc.h") +- file(STRINGS "${Blosc_INCLUDE_DIR}/blosc.h" +- _blosc_version_major_string REGEX "#define BLOSC_VERSION_MAJOR +[0-9]+ " +- ) +- string(REGEX REPLACE "#define BLOSC_VERSION_MAJOR +([0-9]+).*$" "\\1" +- _blosc_version_major_string "${_blosc_version_major_string}" +- ) +- string(STRIP "${_blosc_version_major_string}" Blosc_VERSION_MAJOR) +- +- file(STRINGS "${Blosc_INCLUDE_DIR}/blosc.h" +- _blosc_version_minor_string REGEX "#define BLOSC_VERSION_MINOR +[0-9]+ " +- ) +- string(REGEX REPLACE "#define BLOSC_VERSION_MINOR +([0-9]+).*$" "\\1" +- _blosc_version_minor_string "${_blosc_version_minor_string}" +- ) +- string(STRIP "${_blosc_version_minor_string}" Blosc_VERSION_MINOR) +- +- unset(_blosc_version_major_string) +- unset(_blosc_version_minor_string) +- +- set(Blosc_VERSION ${Blosc_VERSION_MAJOR}.${Blosc_VERSION_MINOR}) +-endif() +- +-# ------------------------------------------------------------------------ +-# Search for blosc lib DIR +-# ------------------------------------------------------------------------ +- +-set(_BLOSC_LIBRARYDIR_SEARCH_DIRS "") +-list(APPEND _BLOSC_LIBRARYDIR_SEARCH_DIRS +- ${BLOSC_LIBRARYDIR} +- ${_BLOSC_ROOT_SEARCH_DIR} +- ${PC_Blosc_LIBRARY_DIRS} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Static library setup +-if(UNIX AND BLOSC_USE_STATIC_LIBS) +- set(_BLOSC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +-endif() +- +-set(BLOSC_PATH_SUFFIXES +- lib64 +- lib +-) +- +-find_library(Blosc_LIBRARY blosc +- NO_DEFAULT_PATH +- PATHS ${_BLOSC_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES ${BLOSC_PATH_SUFFIXES} +-) +- +-if(UNIX AND BLOSC_USE_STATIC_LIBS) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_BLOSC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +- unset(_BLOSC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +-endif() +- +-# ------------------------------------------------------------------------ +-# Cache and set Blosc_FOUND +-# ------------------------------------------------------------------------ +- +-include(FindPackageHandleStandardArgs) +-find_package_handle_standard_args(Blosc +- FOUND_VAR Blosc_FOUND +- REQUIRED_VARS +- Blosc_LIBRARY +- Blosc_INCLUDE_DIR +- VERSION_VAR Blosc_VERSION +-) +- +-if(Blosc_FOUND) +- set(Blosc_LIBRARIES ${Blosc_LIBRARY}) +- set(Blosc_INCLUDE_DIRS ${Blosc_INCLUDE_DIR}) +- set(Blosc_DEFINITIONS ${PC_Blosc_CFLAGS_OTHER}) +- +- get_filename_component(Blosc_LIBRARY_DIRS ${Blosc_LIBRARY} DIRECTORY) +- +- if(NOT TARGET Blosc::blosc) +- add_library(Blosc::blosc UNKNOWN IMPORTED) +- set_target_properties(Blosc::blosc PROPERTIES +- IMPORTED_LOCATION "${Blosc_LIBRARIES}" +- INTERFACE_COMPILE_DEFINITIONS "${Blosc_DEFINITIONS}" +- INTERFACE_INCLUDE_DIRECTORIES "${Blosc_INCLUDE_DIRS}" +- ) +- endif() +-elseif(Blosc_FIND_REQUIRED) +- message(FATAL_ERROR "Unable to find Blosc") +-endif() +diff --git a/cmake/FindCppUnit.cmake b/cmake/FindCppUnit.cmake +index e2beb93..a891624 100644 +--- a/cmake/FindCppUnit.cmake ++++ b/cmake/FindCppUnit.cmake +@@ -125,7 +125,7 @@ list(APPEND _CPPUNIT_INCLUDE_SEARCH_DIRS + + # Look for a standard cppunit header file. + find_path(CppUnit_INCLUDE_DIR cppunit/Portability.h +- NO_DEFAULT_PATH ++ # NO_DEFAULT_PATH + PATHS ${_CPPUNIT_INCLUDE_SEARCH_DIRS} + PATH_SUFFIXES include + ) +@@ -177,7 +177,7 @@ set(CPPUNIT_PATH_SUFFIXES + ) + + find_library(CppUnit_LIBRARY cppunit +- NO_DEFAULT_PATH ++ # NO_DEFAULT_PATH + PATHS ${_CPPUNIT_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${CPPUNIT_PATH_SUFFIXES} + ) +diff --git a/cmake/FindIlmBase.cmake b/cmake/FindIlmBase.cmake +deleted file mode 100644 +index 9dbc252..0000000 +--- a/cmake/FindIlmBase.cmake ++++ /dev/null +@@ -1,337 +0,0 @@ +-# Copyright (c) DreamWorks Animation LLC +-# +-# All rights reserved. This software is distributed under the +-# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) +-# +-# Redistributions of source code must retain the above copyright +-# and license notice and the following restrictions and disclaimer. +-# +-# * Neither the name of DreamWorks Animation nor the names of +-# its contributors may be used to endorse or promote products derived +-# from this software without specific prior written permission. +-# +-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +-# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. +-# +-#[=======================================================================[.rst: +- +-FindIlmBase +------------ +- +-Find IlmBase include dirs and libraries +- +-Use this module by invoking find_package with the form:: +- +- find_package(IlmBase +- [version] [EXACT] # Minimum or EXACT version +- [REQUIRED] # Fail with error if IlmBase is not found +- [COMPONENTS ...] # IlmBase libraries by their canonical name +- # e.g. "Half" for "libHalf" +- ) +- +-IMPORTED Targets +-^^^^^^^^^^^^^^^^ +- +-``IlmBase::Half`` +- The Half library target. +-``IlmBase::Iex`` +- The Iex library target. +-``IlmBase::IexMath`` +- The IexMath library target. +-``IlmBase::IlmThread`` +- The IlmThread library target. +-``IlmBase::Imath`` +- The Imath library target. +- +-Result Variables +-^^^^^^^^^^^^^^^^ +- +-This will define the following variables: +- +-``IlmBase_FOUND`` +- True if the system has the IlmBase library. +-``IlmBase_VERSION`` +- The version of the IlmBase library which was found. +-``IlmBase_INCLUDE_DIRS`` +- Include directories needed to use IlmBase. +-``IlmBase_LIBRARIES`` +- Libraries needed to link to IlmBase. +-``IlmBase_LIBRARY_DIRS`` +- IlmBase library directories. +-``IlmBase_{COMPONENT}_FOUND`` +- True if the system has the named IlmBase component. +- +-Cache Variables +-^^^^^^^^^^^^^^^ +- +-The following cache variables may also be set: +- +-``IlmBase_INCLUDE_DIR`` +- The directory containing ``IlmBase/config-auto.h``. +-``IlmBase_{COMPONENT}_LIBRARY`` +- Individual component libraries for IlmBase +-``IlmBase_{COMPONENT}_DLL`` +- Individual component dlls for IlmBase on Windows. +- +-Hints +-^^^^^ +- +-Instead of explicitly setting the cache variables, the following variables +-may be provided to tell this module where to look. +- +-``ILMBASE_ROOT`` +- Preferred installation prefix. +-``ILMBASE_INCLUDEDIR`` +- Preferred include directory e.g. /include +-``ILMBASE_LIBRARYDIR`` +- Preferred library directory e.g. /lib +-``SYSTEM_LIBRARY_PATHS`` +- Paths appended to all include and lib searches. +- +-#]=======================================================================] +- +-# Support new if() IN_LIST operator +-if(POLICY CMP0057) +- cmake_policy(SET CMP0057 NEW) +-endif() +- +-mark_as_advanced( +- IlmBase_INCLUDE_DIR +- IlmBase_LIBRARY +-) +- +-set(_ILMBASE_COMPONENT_LIST +- Half +- Iex +- IexMath +- IlmThread +- Imath +-) +- +-if(IlmBase_FIND_COMPONENTS) +- set(ILMBASE_COMPONENTS_PROVIDED TRUE) +- set(_IGNORED_COMPONENTS "") +- foreach(COMPONENT ${IlmBase_FIND_COMPONENTS}) +- if(NOT ${COMPONENT} IN_LIST _ILMBASE_COMPONENT_LIST) +- list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) +- endif() +- endforeach() +- +- if(_IGNORED_COMPONENTS) +- message(STATUS "Ignoring unknown components of IlmBase:") +- foreach(COMPONENT ${_IGNORED_COMPONENTS}) +- message(STATUS " ${COMPONENT}") +- endforeach() +- list(REMOVE_ITEM IlmBase_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) +- endif() +-else() +- set(ILMBASE_COMPONENTS_PROVIDED FALSE) +- set(IlmBase_FIND_COMPONENTS ${_ILMBASE_COMPONENT_LIST}) +-endif() +- +-# Append ILMBASE_ROOT or $ENV{ILMBASE_ROOT} if set (prioritize the direct cmake var) +-set(_ILMBASE_ROOT_SEARCH_DIR "") +- +-if(ILMBASE_ROOT) +- list(APPEND _ILMBASE_ROOT_SEARCH_DIR ${ILMBASE_ROOT}) +-else() +- set(_ENV_ILMBASE_ROOT $ENV{ILMBASE_ROOT}) +- if(_ENV_ILMBASE_ROOT) +- list(APPEND _ILMBASE_ROOT_SEARCH_DIR ${_ENV_ILMBASE_ROOT}) +- endif() +-endif() +- +-# Additionally try and use pkconfig to find IlmBase +- +-find_package(PkgConfig) +-pkg_check_modules(PC_IlmBase QUIET IlmBase) +- +-# ------------------------------------------------------------------------ +-# Search for IlmBase include DIR +-# ------------------------------------------------------------------------ +- +-set(_ILMBASE_INCLUDE_SEARCH_DIRS "") +-list(APPEND _ILMBASE_INCLUDE_SEARCH_DIRS +- ${ILMBASE_INCLUDEDIR} +- ${_ILMBASE_ROOT_SEARCH_DIR} +- ${PC_IlmBase_INCLUDEDIR} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Look for a standard IlmBase header file. +-find_path(IlmBase_INCLUDE_DIR IlmBaseConfig.h +- NO_DEFAULT_PATH +- PATHS ${_ILMBASE_INCLUDE_SEARCH_DIRS} +- PATH_SUFFIXES include/OpenEXR OpenEXR +-) +- +-if(EXISTS "${IlmBase_INCLUDE_DIR}/IlmBaseConfig.h") +- # Get the ILMBASE version information from the config header +- file(STRINGS "${IlmBase_INCLUDE_DIR}/IlmBaseConfig.h" +- _ilmbase_version_major_string REGEX "#define ILMBASE_VERSION_MAJOR " +- ) +- string(REGEX REPLACE "#define ILMBASE_VERSION_MAJOR" "" +- _ilmbase_version_major_string "${_ilmbase_version_major_string}" +- ) +- string(STRIP "${_ilmbase_version_major_string}" IlmBase_VERSION_MAJOR) +- +- file(STRINGS "${IlmBase_INCLUDE_DIR}/IlmBaseConfig.h" +- _ilmbase_version_minor_string REGEX "#define ILMBASE_VERSION_MINOR " +- ) +- string(REGEX REPLACE "#define ILMBASE_VERSION_MINOR" "" +- _ilmbase_version_minor_string "${_ilmbase_version_minor_string}" +- ) +- string(STRIP "${_ilmbase_version_minor_string}" IlmBase_VERSION_MINOR) +- +- unset(_ilmbase_version_major_string) +- unset(_ilmbase_version_minor_string) +- +- set(IlmBase_VERSION ${IlmBase_VERSION_MAJOR}.${IlmBase_VERSION_MINOR}) +-endif() +- +-# ------------------------------------------------------------------------ +-# Search for ILMBASE lib DIR +-# ------------------------------------------------------------------------ +- +-set(_ILMBASE_LIBRARYDIR_SEARCH_DIRS "") +- +-# Append to _ILMBASE_LIBRARYDIR_SEARCH_DIRS in priority order +- +-list(APPEND _ILMBASE_LIBRARYDIR_SEARCH_DIRS +- ${ILMBASE_LIBRARYDIR} +- ${_ILMBASE_ROOT_SEARCH_DIR} +- ${PC_IlmBase_LIBDIR} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Build suffix directories +- +-set(ILMBASE_PATH_SUFFIXES +- lib64 +- lib +-) +- +-if(UNIX) +- list(INSERT ILMBASE_PATH_SUFFIXES 0 lib/x86_64-linux-gnu) +-endif() +- +-set(_ILMBASE_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- +-# library suffix handling +-if(WIN32) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${IlmBase_VERSION_MAJOR}_${IlmBase_VERSION_MINOR}.lib" +- ) +-else() +- if(ILMBASE_USE_STATIC_LIBS) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${IlmBase_VERSION_MAJOR}_${IlmBase_VERSION_MINOR}.a" +- ) +- else() +- if(APPLE) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${IlmBase_VERSION_MAJOR}_${IlmBase_VERSION_MINOR}.dylib" +- ) +- else() +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${IlmBase_VERSION_MAJOR}_${IlmBase_VERSION_MINOR}.so" +- ) +- endif() +- endif() +-endif() +- +-set(IlmBase_LIB_COMPONENTS "") +- +-foreach(COMPONENT ${IlmBase_FIND_COMPONENTS}) +- find_library(IlmBase_${COMPONENT}_LIBRARY ${COMPONENT} +- NO_DEFAULT_PATH +- PATHS ${_ILMBASE_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES ${ILMBASE_PATH_SUFFIXES} +- ) +- list(APPEND IlmBase_LIB_COMPONENTS ${IlmBase_${COMPONENT}_LIBRARY}) +- +- if(WIN32 AND NOT ILMBASE_USE_STATIC_LIBS) +- set(_ILMBASE_TMP ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") +- find_library(IlmBase_${COMPONENT}_DLL ${COMPONENT} +- NO_DEFAULT_PATH +- PATHS ${_ILMBASE_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES bin +- ) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_ILMBASE_TMP}) +- unset(_ILMBASE_TMP) +- endif() +- +- if(IlmBase_${COMPONENT}_LIBRARY) +- set(IlmBase_${COMPONENT}_FOUND TRUE) +- else() +- set(IlmBase_${COMPONENT}_FOUND FALSE) +- endif() +-endforeach() +- +-# reset lib suffix +- +-set(CMAKE_FIND_LIBRARY_SUFFIXES ${_ILMBASE_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +-unset(_ILMBASE_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +- +-# ------------------------------------------------------------------------ +-# Cache and set ILMBASE_FOUND +-# ------------------------------------------------------------------------ +- +-include(FindPackageHandleStandardArgs) +-find_package_handle_standard_args(IlmBase +- FOUND_VAR IlmBase_FOUND +- REQUIRED_VARS +- IlmBase_INCLUDE_DIR +- IlmBase_LIB_COMPONENTS +- VERSION_VAR IlmBase_VERSION +- HANDLE_COMPONENTS +-) +- +-if(IlmBase_FOUND) +- set(IlmBase_LIBRARIES ${IlmBase_LIB_COMPONENTS}) +- +- # We have to add both include and include/OpenEXR to the include +- # path in case OpenEXR and IlmBase are installed separately +- +- set(IlmBase_INCLUDE_DIRS) +- list(APPEND IlmBase_INCLUDE_DIRS +- ${IlmBase_INCLUDE_DIR}/../ +- ${IlmBase_INCLUDE_DIR} +- ) +- set(IlmBase_DEFINITIONS ${PC_IlmBase_CFLAGS_OTHER}) +- +- set(IlmBase_LIBRARY_DIRS "") +- foreach(LIB ${IlmBase_LIB_COMPONENTS}) +- get_filename_component(_ILMBASE_LIBDIR ${LIB} DIRECTORY) +- list(APPEND IlmBase_LIBRARY_DIRS ${_ILMBASE_LIBDIR}) +- endforeach() +- list(REMOVE_DUPLICATES IlmBase_LIBRARY_DIRS) +- +- # Configure imported targets +- +- foreach(COMPONENT ${IlmBase_FIND_COMPONENTS}) +- if(NOT TARGET IlmBase::${COMPONENT}) +- add_library(IlmBase::${COMPONENT} UNKNOWN IMPORTED) +- set_target_properties(IlmBase::${COMPONENT} PROPERTIES +- IMPORTED_LOCATION "${IlmBase_${COMPONENT}_LIBRARY}" +- INTERFACE_COMPILE_OPTIONS "${IlmBase_DEFINITIONS}" +- INTERFACE_INCLUDE_DIRECTORIES "${IlmBase_INCLUDE_DIRS}" +- ) +- endif() +- endforeach() +- +-elseif(IlmBase_FIND_REQUIRED) +- message(FATAL_ERROR "Unable to find IlmBase") +-endif() +diff --git a/cmake/FindOpenEXR.cmake b/cmake/FindOpenEXR.cmake +deleted file mode 100644 +index 339c1a2..0000000 +--- a/cmake/FindOpenEXR.cmake ++++ /dev/null +@@ -1,329 +0,0 @@ +-# Copyright (c) DreamWorks Animation LLC +-# +-# All rights reserved. This software is distributed under the +-# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) +-# +-# Redistributions of source code must retain the above copyright +-# and license notice and the following restrictions and disclaimer. +-# +-# * Neither the name of DreamWorks Animation nor the names of +-# its contributors may be used to endorse or promote products derived +-# from this software without specific prior written permission. +-# +-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +-# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. +-# +-#[=======================================================================[.rst: +- +-FindOpenEXR +------------ +- +-Find OpenEXR include dirs and libraries +- +-Use this module by invoking find_package with the form:: +- +- find_package(OpenEXR +- [version] [EXACT] # Minimum or EXACT version +- [REQUIRED] # Fail with error if OpenEXR is not found +- [COMPONENTS ...] # OpenEXR libraries by their canonical name +- # e.g. "IlmImf" for "libIlmImf" +- ) +- +-IMPORTED Targets +-^^^^^^^^^^^^^^^^ +- +-``OpenEXR::IlmImf`` +- The IlmImf library target. +-``OpenEXR::IlmImfUtil`` +- The IlmImfUtil library target. +- +-Result Variables +-^^^^^^^^^^^^^^^^ +- +-This will define the following variables: +- +-``OpenEXR_FOUND`` +- True if the system has the OpenEXR library. +-``OpenEXR_VERSION`` +- The version of the OpenEXR library which was found. +-``OpenEXR_INCLUDE_DIRS`` +- Include directories needed to use OpenEXR. +-``OpenEXR_LIBRARIES`` +- Libraries needed to link to OpenEXR. +-``OpenEXR_LIBRARY_DIRS`` +- OpenEXR library directories. +-``OpenEXR_DEFINITIONS`` +- Definitions to use when compiling code that uses OpenEXR. +-``OpenEXR_{COMPONENT}_FOUND`` +- True if the system has the named OpenEXR component. +- +-Cache Variables +-^^^^^^^^^^^^^^^ +- +-The following cache variables may also be set: +- +-``OpenEXR_INCLUDE_DIR`` +- The directory containing ``OpenEXR/config-auto.h``. +-``OpenEXR_{COMPONENT}_LIBRARY`` +- Individual component libraries for OpenEXR +-``OpenEXR_{COMPONENT}_DLL`` +- Individual component dlls for OpenEXR on Windows. +- +-Hints +-^^^^^ +- +-Instead of explicitly setting the cache variables, the following variables +-may be provided to tell this module where to look. +- +-``OPENEXR_ROOT`` +- Preferred installation prefix. +-``OPENEXR_INCLUDEDIR`` +- Preferred include directory e.g. /include +-``OPENEXR_LIBRARYDIR`` +- Preferred library directory e.g. /lib +-``SYSTEM_LIBRARY_PATHS`` +- Paths appended to all include and lib searches. +- +-#]=======================================================================] +- +-# Support new if() IN_LIST operator +-if(POLICY CMP0057) +- cmake_policy(SET CMP0057 NEW) +-endif() +- +-mark_as_advanced( +- OpenEXR_INCLUDE_DIR +- OpenEXR_LIBRARY +-) +- +-set(_OPENEXR_COMPONENT_LIST +- IlmImf +- IlmImfUtil +-) +- +-if(OpenEXR_FIND_COMPONENTS) +- set(OPENEXR_COMPONENTS_PROVIDED TRUE) +- set(_IGNORED_COMPONENTS "") +- foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) +- if(NOT ${COMPONENT} IN_LIST _OPENEXR_COMPONENT_LIST) +- list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) +- endif() +- endforeach() +- +- if(_IGNORED_COMPONENTS) +- message(STATUS "Ignoring unknown components of OpenEXR:") +- foreach(COMPONENT ${_IGNORED_COMPONENTS}) +- message(STATUS " ${COMPONENT}") +- endforeach() +- list(REMOVE_ITEM OpenEXR_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) +- endif() +-else() +- set(OPENEXR_COMPONENTS_PROVIDED FALSE) +- set(OpenEXR_FIND_COMPONENTS ${_OPENEXR_COMPONENT_LIST}) +-endif() +- +-# Append OPENEXR_ROOT or $ENV{OPENEXR_ROOT} if set (prioritize the direct cmake var) +-set(_OPENEXR_ROOT_SEARCH_DIR "") +- +-if(OPENEXR_ROOT) +- list(APPEND _OPENEXR_ROOT_SEARCH_DIR ${OPENEXR_ROOT}) +-else() +- set(_ENV_OPENEXR_ROOT $ENV{OPENEXR_ROOT}) +- if(_ENV_OPENEXR_ROOT) +- list(APPEND _OPENEXR_ROOT_SEARCH_DIR ${_ENV_OPENEXR_ROOT}) +- endif() +-endif() +- +-# Additionally try and use pkconfig to find OpenEXR +- +-find_package(PkgConfig) +-pkg_check_modules(PC_OpenEXR QUIET OpenEXR) +- +-# ------------------------------------------------------------------------ +-# Search for OpenEXR include DIR +-# ------------------------------------------------------------------------ +- +-set(_OPENEXR_INCLUDE_SEARCH_DIRS "") +-list(APPEND _OPENEXR_INCLUDE_SEARCH_DIRS +- ${OPENEXR_INCLUDEDIR} +- ${_OPENEXR_ROOT_SEARCH_DIR} +- ${PC_OpenEXR_INCLUDEDIR} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Look for a standard OpenEXR header file. +-find_path(OpenEXR_INCLUDE_DIR OpenEXRConfig.h +- NO_DEFAULT_PATH +- PATHS ${_OPENEXR_INCLUDE_SEARCH_DIRS} +- PATH_SUFFIXES include/OpenEXR OpenEXR +-) +- +-if(EXISTS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h") +- # Get the EXR version information from the config header +- file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h" +- _openexr_version_major_string REGEX "#define OPENEXR_VERSION_MAJOR " +- ) +- string(REGEX REPLACE "#define OPENEXR_VERSION_MAJOR" "" +- _openexr_version_major_string "${_openexr_version_major_string}" +- ) +- string(STRIP "${_openexr_version_major_string}" OpenEXR_VERSION_MAJOR) +- +- file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h" +- _openexr_version_minor_string REGEX "#define OPENEXR_VERSION_MINOR " +- ) +- string(REGEX REPLACE "#define OPENEXR_VERSION_MINOR" "" +- _openexr_version_minor_string "${_openexr_version_minor_string}" +- ) +- string(STRIP "${_openexr_version_minor_string}" OpenEXR_VERSION_MINOR) +- +- unset(_openexr_version_major_string) +- unset(_openexr_version_minor_string) +- +- set(OpenEXR_VERSION ${OpenEXR_VERSION_MAJOR}.${OpenEXR_VERSION_MINOR}) +-endif() +- +-# ------------------------------------------------------------------------ +-# Search for OPENEXR lib DIR +-# ------------------------------------------------------------------------ +- +-set(_OPENEXR_LIBRARYDIR_SEARCH_DIRS "") +- +-# Append to _OPENEXR_LIBRARYDIR_SEARCH_DIRS in priority order +- +-list(APPEND _OPENEXR_LIBRARYDIR_SEARCH_DIRS +- ${OPENEXR_LIBRARYDIR} +- ${_OPENEXR_ROOT_SEARCH_DIR} +- ${PC_OpenEXR_LIBDIR} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Build suffix directories +- +-set(OPENEXR_PATH_SUFFIXES +- lib64 +- lib +-) +- +-if(UNIX ) +- list(INSERT OPENEXR_PATH_SUFFIXES 0 lib/x86_64-linux-gnu) +-endif() +- +-set(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- +-# library suffix handling +-if(WIN32) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}.lib" +- ) +-else() +- if(OPENEXR_USE_STATIC_LIBS) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}.a" +- ) +- else() +- if(APPLE) +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}.dylib" +- ) +- else() +- list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES +- "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}.so" +- ) +- endif() +- endif() +-endif() +- +-set(OpenEXR_LIB_COMPONENTS "") +- +-foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) +- find_library(OpenEXR_${COMPONENT}_LIBRARY ${COMPONENT} +- NO_DEFAULT_PATH +- PATHS ${_OPENEXR_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES ${OPENEXR_PATH_SUFFIXES} +- ) +- list(APPEND OpenEXR_LIB_COMPONENTS ${OpenEXR_${COMPONENT}_LIBRARY}) +- +- if(WIN32 AND NOT OPENEXR_USE_STATIC_LIBS) +- set(_OPENEXR_TMP ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") +- find_library(OpenEXR_${COMPONENT}_DLL ${COMPONENT} +- NO_DEFAULT_PATH +- PATHS ${_OPENEXR_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES bin +- ) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENEXR_TMP}) +- unset(_OPENEXR_TMP) +- endif() +- +- if(OpenEXR_${COMPONENT}_LIBRARY) +- set(OpenEXR_${COMPONENT}_FOUND TRUE) +- else() +- set(OpenEXR_${COMPONENT}_FOUND FALSE) +- endif() +-endforeach() +- +-# reset lib suffix +- +-set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +-unset(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +- +-# ------------------------------------------------------------------------ +-# Cache and set OPENEXR_FOUND +-# ------------------------------------------------------------------------ +- +-include(FindPackageHandleStandardArgs) +-find_package_handle_standard_args(OpenEXR +- FOUND_VAR OpenEXR_FOUND +- REQUIRED_VARS +- OpenEXR_INCLUDE_DIR +- OpenEXR_LIB_COMPONENTS +- VERSION_VAR OpenEXR_VERSION +- HANDLE_COMPONENTS +-) +- +-if(OpenEXR_FOUND) +- set(OpenEXR_LIBRARIES ${OpenEXR_LIB_COMPONENTS}) +- +- # We have to add both include and include/OpenEXR to the include +- # path in case OpenEXR and IlmBase are installed separately +- +- set(OpenEXR_INCLUDE_DIRS) +- list(APPEND OpenEXR_INCLUDE_DIRS +- ${OpenEXR_INCLUDE_DIR}/../ +- ${OpenEXR_INCLUDE_DIR} +- ) +- set(OpenEXR_DEFINITIONS ${PC_OpenEXR_CFLAGS_OTHER}) +- +- set(OpenEXR_LIBRARY_DIRS "") +- foreach(LIB ${OpenEXR_LIB_COMPONENTS}) +- get_filename_component(_OPENEXR_LIBDIR ${LIB} DIRECTORY) +- list(APPEND OpenEXR_LIBRARY_DIRS ${_OPENEXR_LIBDIR}) +- endforeach() +- list(REMOVE_DUPLICATES OpenEXR_LIBRARY_DIRS) +- +- # Configure imported target +- +- foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) +- if(NOT TARGET OpenEXR::${COMPONENT}) +- add_library(OpenEXR::${COMPONENT} UNKNOWN IMPORTED) +- set_target_properties(OpenEXR::${COMPONENT} PROPERTIES +- IMPORTED_LOCATION "${OpenEXR_${COMPONENT}_LIBRARY}" +- INTERFACE_COMPILE_OPTIONS "${OpenEXR_DEFINITIONS}" +- INTERFACE_INCLUDE_DIRECTORIES "${OpenEXR_INCLUDE_DIRS}" +- ) +- endif() +- endforeach() +-elseif(OpenEXR_FIND_REQUIRED) +- message(FATAL_ERROR "Unable to find OpenEXR") +-endif() +diff --git a/cmake/FindOpenVDB.cmake b/cmake/FindOpenVDB.cmake +index 63a2eda..6211071 100644 +--- a/cmake/FindOpenVDB.cmake ++++ b/cmake/FindOpenVDB.cmake +@@ -244,7 +244,7 @@ set(OpenVDB_LIB_COMPONENTS "") + + foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) + set(LIB_NAME ${COMPONENT}) +- find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} ++ find_library(OpenVDB_${COMPONENT}_LIBRARY ${LIB_NAME} lib${LIB_NAME} + NO_DEFAULT_PATH + PATHS ${_OPENVDB_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${OPENVDB_PATH_SUFFIXES} +@@ -282,16 +282,13 @@ find_package_handle_standard_args(OpenVDB + # ------------------------------------------------------------------------ + + # Set the ABI number the library was built against. Uses vdb_print ++find_program(OPENVDB_PRINT vdb_print ++ PATHS ${_OPENVDB_INSTALL}/bin ${OpenVDB_INCLUDE_DIR} ++ NO_DEFAULT_PATH) + + if(_OPENVDB_INSTALL) + OPENVDB_ABI_VERSION_FROM_PRINT( +- "${_OPENVDB_INSTALL}/bin/vdb_print" +- ABI OpenVDB_ABI +- ) +-else() +- # Try and find vdb_print from the include path +- OPENVDB_ABI_VERSION_FROM_PRINT( +- "${OpenVDB_INCLUDE_DIR}/../bin/vdb_print" ++ "${OPENVDB_PRINT}" + ABI OpenVDB_ABI + ) + endif() +@@ -472,6 +469,12 @@ foreach(COMPONENT ${OpenVDB_FIND_COMPONENTS}) + INTERFACE_LINK_LIBRARIES "${_OPENVDB_VISIBLE_DEPENDENCIES}" # visible deps (headers) + INTERFACE_COMPILE_FEATURES cxx_std_11 + ) ++ ++ if (OPENVDB_USE_STATIC_LIBS) ++ set_target_properties(OpenVDB::${COMPONENT} PROPERTIES ++ INTERFACE_COMPILE_DEFINITIONS "OPENVDB_STATICLIB;OPENVDB_OPENEXR_STATICLIB" ++ ) ++ endif() + endif() + endforeach() + +diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake +index bdf9c81..ffdee03 100644 +--- a/cmake/FindTBB.cmake ++++ b/cmake/FindTBB.cmake +@@ -1,333 +1,322 @@ +-# Copyright (c) DreamWorks Animation LLC ++# The MIT License (MIT) + # +-# All rights reserved. This software is distributed under the +-# Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ ) ++# Copyright (c) 2015 Justus Calvin ++# ++# Permission is hereby granted, free of charge, to any person obtaining a copy ++# of this software and associated documentation files (the "Software"), to deal ++# in the Software without restriction, including without limitation the rights ++# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++# copies of the Software, and to permit persons to whom the Software is ++# furnished to do so, subject to the following conditions: ++# ++# The above copyright notice and this permission notice shall be included in all ++# copies or substantial portions of the Software. ++# ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++# SOFTWARE. ++ + # +-# Redistributions of source code must retain the above copyright +-# and license notice and the following restrictions and disclaimer. ++# FindTBB ++# ------- + # +-# * Neither the name of DreamWorks Animation nor the names of +-# its contributors may be used to endorse or promote products derived +-# from this software without specific prior written permission. ++# Find TBB include directories and libraries. + # +-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, +-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE +-# LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00. ++# Usage: + # +-#[=======================================================================[.rst: +- +-FindTBB +-------- +- +-Find Tbb include dirs and libraries +- +-Use this module by invoking find_package with the form:: +- +- find_package(TBB +- [version] [EXACT] # Minimum or EXACT version +- [REQUIRED] # Fail with error if Tbb is not found +- [COMPONENTS ...] # Tbb libraries by their canonical name +- # e.g. "tbb" for "libtbb" +- ) +- +-IMPORTED Targets +-^^^^^^^^^^^^^^^^ +- +-``TBB::tbb`` +- The tbb library target. +-``TBB::tbbmalloc`` +- The tbbmalloc library target. +-``TBB::tbbmalloc_proxy`` +- The tbbmalloc_proxy library target. +- +-Result Variables +-^^^^^^^^^^^^^^^^ +- +-This will define the following variables: +- +-``Tbb_FOUND`` +- True if the system has the Tbb library. +-``Tbb_VERSION`` +- The version of the Tbb library which was found. +-``Tbb_INCLUDE_DIRS`` +- Include directories needed to use Tbb. +-``Tbb_LIBRARIES`` +- Libraries needed to link to Tbb. +-``Tbb_LIBRARY_DIRS`` +- Tbb library directories. +-``TBB_{COMPONENT}_FOUND`` +- True if the system has the named TBB component. +- +-Cache Variables +-^^^^^^^^^^^^^^^ +- +-The following cache variables may also be set: +- +-``Tbb_INCLUDE_DIR`` +- The directory containing ``tbb/tbb_stddef.h``. +-``Tbb_{COMPONENT}_LIBRARY`` +- Individual component libraries for Tbb +- +-Hints +-^^^^^ +- +-Instead of explicitly setting the cache variables, the following variables +-may be provided to tell this module where to look. +- +-``TBB_ROOT`` +- Preferred installation prefix. +-``TBB_INCLUDEDIR`` +- Preferred include directory e.g. /include +-``TBB_LIBRARYDIR`` +- Preferred library directory e.g. /lib +-``SYSTEM_LIBRARY_PATHS`` +- Paths appended to all include and lib searches. +- +-#]=======================================================================] +- +-# Support new if() IN_LIST operator +-if(POLICY CMP0057) +- cmake_policy(SET CMP0057 NEW) +-endif() ++# find_package(TBB [major[.minor]] [EXACT] ++# [QUIET] [REQUIRED] ++# [[COMPONENTS] [components...]] ++# [OPTIONAL_COMPONENTS components...]) ++# ++# where the allowed components are tbbmalloc and tbb_preview. Users may modify ++# the behavior of this module with the following variables: ++# ++# * TBB_ROOT_DIR - The base directory the of TBB installation. ++# * TBB_INCLUDE_DIR - The directory that contains the TBB headers files. ++# * TBB_LIBRARY - The directory that contains the TBB library files. ++# * TBB__LIBRARY - The path of the TBB the corresponding TBB library. ++# These libraries, if specified, override the ++# corresponding library search results, where ++# may be tbb, tbb_debug, tbbmalloc, tbbmalloc_debug, ++# tbb_preview, or tbb_preview_debug. ++# * TBB_USE_DEBUG_BUILD - The debug version of tbb libraries, if present, will ++# be used instead of the release version. ++# * TBB_STATIC - Static linking of libraries with a _static suffix. ++# For example, on Windows a tbb_static.lib will be searched for ++# instead of tbb.lib. ++# ++# Users may modify the behavior of this module with the following environment ++# variables: ++# ++# * TBB_INSTALL_DIR ++# * TBBROOT ++# * LIBRARY_PATH ++# ++# This module will set the following variables: ++# ++# * TBB_FOUND - Set to false, or undefined, if we haven’t found, or ++# don’t want to use TBB. ++# * TBB__FOUND - If False, optional part of TBB sytem is ++# not available. ++# * TBB_VERSION - The full version string ++# * TBB_VERSION_MAJOR - The major version ++# * TBB_VERSION_MINOR - The minor version ++# * TBB_INTERFACE_VERSION - The interface version number defined in ++# tbb/tbb_stddef.h. ++# * TBB__LIBRARY_RELEASE - The path of the TBB release version of ++# , where may be tbb, tbb_debug, ++# tbbmalloc, tbbmalloc_debug, tbb_preview, or ++# tbb_preview_debug. ++# * TBB__LIBRARY_DEGUG - The path of the TBB release version of ++# , where may be tbb, tbb_debug, ++# tbbmalloc, tbbmalloc_debug, tbb_preview, or ++# tbb_preview_debug. ++# ++# The following varibles should be used to build and link with TBB: ++# ++# * TBB_INCLUDE_DIRS - The include directory for TBB. ++# * TBB_LIBRARIES - The libraries to link against to use TBB. ++# * TBB_LIBRARIES_RELEASE - The release libraries to link against to use TBB. ++# * TBB_LIBRARIES_DEBUG - The debug libraries to link against to use TBB. ++# * TBB_DEFINITIONS - Definitions to use when compiling code that uses ++# TBB. ++# * TBB_DEFINITIONS_RELEASE - Definitions to use when compiling release code that ++# uses TBB. ++# * TBB_DEFINITIONS_DEBUG - Definitions to use when compiling debug code that ++# uses TBB. ++# ++# This module will also create the "tbb" target that may be used when building ++# executables and libraries. ++ ++include(FindPackageHandleStandardArgs) ++ ++if(NOT TBB_FOUND) + +-mark_as_advanced( +- Tbb_INCLUDE_DIR +- Tbb_LIBRARY +-) +- +-set(_TBB_COMPONENT_LIST +- tbb +- tbbmalloc +- tbbmalloc_proxy +-) +- +-if(TBB_FIND_COMPONENTS) +- set(_TBB_COMPONENTS_PROVIDED TRUE) +- set(_IGNORED_COMPONENTS "") +- foreach(COMPONENT ${TBB_FIND_COMPONENTS}) +- if(NOT ${COMPONENT} IN_LIST _TBB_COMPONENT_LIST) +- list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) ++ ################################## ++ # Check the build type ++ ################################## ++ ++ if(NOT DEFINED TBB_USE_DEBUG_BUILD) ++ if(CMAKE_BUILD_TYPE MATCHES "(Debug|DEBUG|debug)") ++ set(TBB_BUILD_TYPE DEBUG) ++ else() ++ set(TBB_BUILD_TYPE RELEASE) ++ endif() ++ elseif(TBB_USE_DEBUG_BUILD) ++ set(TBB_BUILD_TYPE DEBUG) ++ else() ++ set(TBB_BUILD_TYPE RELEASE) ++ endif() ++ ++ ################################## ++ # Set the TBB search directories ++ ################################## ++ ++ # Define search paths based on user input and environment variables ++ set(TBB_SEARCH_DIR ${TBB_ROOT_DIR} $ENV{TBB_INSTALL_DIR} $ENV{TBBROOT}) ++ ++ # Define the search directories based on the current platform ++ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") ++ set(TBB_DEFAULT_SEARCH_DIR "C:/Program Files/Intel/TBB" ++ "C:/Program Files (x86)/Intel/TBB") ++ ++ # Set the target architecture ++ if(CMAKE_SIZEOF_VOID_P EQUAL 8) ++ set(TBB_ARCHITECTURE "intel64") ++ else() ++ set(TBB_ARCHITECTURE "ia32") ++ endif() ++ ++ # Set the TBB search library path search suffix based on the version of VC ++ if(WINDOWS_STORE) ++ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui") ++ elseif(MSVC14) ++ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc14") ++ elseif(MSVC12) ++ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc12") ++ elseif(MSVC11) ++ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11") ++ elseif(MSVC10) ++ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10") + endif() +- endforeach() + +- if(_IGNORED_COMPONENTS) +- message(STATUS "Ignoring unknown components of TBB:") +- foreach(COMPONENT ${_IGNORED_COMPONENTS}) +- message(STATUS " ${COMPONENT}") +- endforeach() +- list(REMOVE_ITEM TBB_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) ++ # Add the library path search suffix for the VC independent version of TBB ++ list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt") ++ ++ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") ++ # OS X ++ set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb") ++ ++ # TODO: Check to see which C++ library is being used by the compiler. ++ if(NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 13.0) ++ # The default C++ library on OS X 10.9 and later is libc++ ++ set(TBB_LIB_PATH_SUFFIX "lib/libc++" "lib") ++ else() ++ set(TBB_LIB_PATH_SUFFIX "lib") ++ endif() ++ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") ++ # Linux ++ set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb") ++ ++ # TODO: Check compiler version to see the suffix should be /gcc4.1 or ++ # /gcc4.1. For now, assume that the compiler is more recent than ++ # gcc 4.4.x or later. ++ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") ++ set(TBB_LIB_PATH_SUFFIX "lib/intel64/gcc4.4") ++ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$") ++ set(TBB_LIB_PATH_SUFFIX "lib/ia32/gcc4.4") ++ endif() ++ endif() ++ ++ ################################## ++ # Find the TBB include dir ++ ################################## ++ ++ find_path(TBB_INCLUDE_DIRS tbb/tbb.h ++ HINTS ${TBB_INCLUDE_DIR} ${TBB_SEARCH_DIR} ++ PATHS ${TBB_DEFAULT_SEARCH_DIR} ++ PATH_SUFFIXES include) ++ ++ ################################## ++ # Set version strings ++ ################################## ++ ++ if(TBB_INCLUDE_DIRS) ++ file(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _tbb_version_file) ++ string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" ++ TBB_VERSION_MAJOR "${_tbb_version_file}") ++ string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" ++ TBB_VERSION_MINOR "${_tbb_version_file}") ++ string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" ++ TBB_INTERFACE_VERSION "${_tbb_version_file}") ++ set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}") + endif() +-else() +- set(_TBB_COMPONENTS_PROVIDED FALSE) +- set(TBB_FIND_COMPONENTS ${_TBB_COMPONENT_LIST}) +-endif() + +-# Append TBB_ROOT or $ENV{TBB_ROOT} if set (prioritize the direct cmake var) +-set(_TBB_ROOT_SEARCH_DIR "") ++ ################################## ++ # Find TBB components ++ ################################## + +-if(TBB_ROOT) +- list(APPEND _TBB_ROOT_SEARCH_DIR ${TBB_ROOT}) +-else() +- set(_ENV_TBB_ROOT $ENV{TBB_ROOT}) +- if(_ENV_TBB_ROOT) +- list(APPEND _TBB_ROOT_SEARCH_DIR ${_ENV_TBB_ROOT}) ++ if(TBB_VERSION VERSION_LESS 4.3) ++ set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc tbb) ++ else() ++ set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc_proxy tbbmalloc tbb) + endif() +-endif() + +-# Additionally try and use pkconfig to find Tbb +- +-find_package(PkgConfig) +-pkg_check_modules(PC_Tbb QUIET tbb) +- +-# ------------------------------------------------------------------------ +-# Search for tbb include DIR +-# ------------------------------------------------------------------------ +- +-set(_TBB_INCLUDE_SEARCH_DIRS "") +-list(APPEND _TBB_INCLUDE_SEARCH_DIRS +- ${TBB_INCLUDEDIR} +- ${_TBB_ROOT_SEARCH_DIR} +- ${PC_Tbb_INCLUDE_DIRS} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Look for a standard tbb header file. +-find_path(Tbb_INCLUDE_DIR tbb/tbb_stddef.h +- NO_DEFAULT_PATH +- PATHS ${_TBB_INCLUDE_SEARCH_DIRS} +- PATH_SUFFIXES include +-) +- +-if(EXISTS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h") +- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" +- _tbb_version_major_string REGEX "#define TBB_VERSION_MAJOR " +- ) +- string(REGEX REPLACE "#define TBB_VERSION_MAJOR" "" +- _tbb_version_major_string "${_tbb_version_major_string}" +- ) +- string(STRIP "${_tbb_version_major_string}" Tbb_VERSION_MAJOR) +- +- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" +- _tbb_version_minor_string REGEX "#define TBB_VERSION_MINOR " +- ) +- string(REGEX REPLACE "#define TBB_VERSION_MINOR" "" +- _tbb_version_minor_string "${_tbb_version_minor_string}" +- ) +- string(STRIP "${_tbb_version_minor_string}" Tbb_VERSION_MINOR) +- +- unset(_tbb_version_major_string) +- unset(_tbb_version_minor_string) +- +- set(Tbb_VERSION ${Tbb_VERSION_MAJOR}.${Tbb_VERSION_MINOR}) +-endif() ++ if(TBB_STATIC) ++ set(TBB_STATIC_SUFFIX "_static") ++ endif() ++ ++ # Find each component ++ foreach(_comp ${TBB_SEARCH_COMPOMPONENTS}) ++ if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};") + +-# ------------------------------------------------------------------------ +-# Search for TBB lib DIR +-# ------------------------------------------------------------------------ ++ # Search for the libraries ++ find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX} ++ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} ++ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH ++ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) + +-set(_TBB_LIBRARYDIR_SEARCH_DIRS "") ++ find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}${TBB_STATIC_SUFFIX}_debug ++ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} ++ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH ++ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) + +-# Append to _TBB_LIBRARYDIR_SEARCH_DIRS in priority order ++ if(TBB_${_comp}_LIBRARY_DEBUG) ++ list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}") ++ endif() ++ if(TBB_${_comp}_LIBRARY_RELEASE) ++ list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}") ++ endif() ++ if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY) ++ set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}") ++ endif() + +-set(_TBB_LIBRARYDIR_SEARCH_DIRS "") +-list(APPEND _TBB_LIBRARYDIR_SEARCH_DIRS +- ${TBB_LIBRARYDIR} +- ${_TBB_ROOT_SEARCH_DIR} +- ${PC_Tbb_LIBRARY_DIRS} +- ${SYSTEM_LIBRARY_PATHS} +-) ++ if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}") ++ set(TBB_${_comp}_FOUND TRUE) ++ else() ++ set(TBB_${_comp}_FOUND FALSE) ++ endif() + +-set(TBB_PATH_SUFFIXES +- lib64 +- lib +-) ++ # Mark internal variables as advanced ++ mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE) ++ mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG) ++ mark_as_advanced(TBB_${_comp}_LIBRARY) + +-# platform branching ++ endif() ++ endforeach() + +-if(UNIX) +- list(INSERT TBB_PATH_SUFFIXES 0 lib/x86_64-linux-gnu) +-endif() ++ ################################## ++ # Set compile flags and libraries ++ ################################## + +-if(APPLE) +- if(TBB_FOR_CLANG) +- list(INSERT TBB_PATH_SUFFIXES 0 lib/libc++) ++ set(TBB_DEFINITIONS_RELEASE "") ++ set(TBB_DEFINITIONS_DEBUG "TBB_USE_DEBUG=1") ++ ++ if(TBB_LIBRARIES_${TBB_BUILD_TYPE}) ++ set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") + endif() +-elseif(WIN32) +- if(MSVC10) +- set(TBB_VC_DIR vc10) +- elseif(MSVC11) +- set(TBB_VC_DIR vc11) +- elseif(MSVC12) +- set(TBB_VC_DIR vc12) +- endif() +- list(INSERT TBB_PATH_SUFFIXES 0 lib/intel64/${TBB_VC_DIR}) +-else() +- if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU) +- if(TBB_MATCH_COMPILER_VERSION) +- string(REGEX MATCHALL "[0-9]+" GCC_VERSION_COMPONENTS ${CMAKE_CXX_COMPILER_VERSION}) +- list(GET GCC_VERSION_COMPONENTS 0 GCC_MAJOR) +- list(GET GCC_VERSION_COMPONENTS 1 GCC_MINOR) +- list(INSERT TBB_PATH_SUFFIXES 0 lib/intel64/gcc${GCC_MAJOR}.${GCC_MINOR}) +- else() +- list(INSERT TBB_PATH_SUFFIXES 0 lib/intel64/gcc4.4) +- endif() ++ ++ if(NOT MSVC AND NOT TBB_LIBRARIES) ++ set(TBB_LIBRARIES ${TBB_LIBRARIES_RELEASE}) + endif() +-endif() + +-if(UNIX AND TBB_USE_STATIC_LIBS) +- set(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +-endif() ++ if (MSVC AND TBB_STATIC) ++ set(TBB_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE) ++ endif () ++ ++ unset (TBB_STATIC_SUFFIX) ++ ++ find_package_handle_standard_args(TBB ++ REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES ++ HANDLE_COMPONENTS ++ VERSION_VAR TBB_VERSION) ++ ++ ################################## ++ # Create targets ++ ################################## ++ ++ if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND) ++ add_library(TBB::tbb UNKNOWN IMPORTED) ++ set_target_properties(TBB::tbb PROPERTIES ++ INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS} ++ IMPORTED_LOCATION ${TBB_LIBRARIES}) ++ if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) ++ set_target_properties(TBB::tbb PROPERTIES ++ INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_DEBUG}>;$<$:${TBB_DEFINITIONS_RELEASE}>" ++ IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG} ++ IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_RELEASE} ++ IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE} ++ IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE} ++ ) ++ endif() + +-set(Tbb_LIB_COMPONENTS "") +- +-foreach(COMPONENT ${TBB_FIND_COMPONENTS}) +- find_library(Tbb_${COMPONENT}_LIBRARY ${COMPONENT} +- NO_DEFAULT_PATH +- PATHS ${_TBB_LIBRARYDIR_SEARCH_DIRS} +- PATH_SUFFIXES ${TBB_PATH_SUFFIXES} +- ) +- +- # On Unix, TBB sometimes uses linker scripts instead of symlinks, so parse the linker script +- # and correct the library name if so +- if(UNIX AND EXISTS ${Tbb_${COMPONENT}_LIBRARY}) +- # Ignore files where the first four bytes equals the ELF magic number +- file(READ ${Tbb_${COMPONENT}_LIBRARY} Tbb_${COMPONENT}_HEX OFFSET 0 LIMIT 4 HEX) +- if(NOT ${Tbb_${COMPONENT}_HEX} STREQUAL "7f454c46") +- # Read the first 1024 bytes of the library and match against an "INPUT (file)" regex +- file(READ ${Tbb_${COMPONENT}_LIBRARY} Tbb_${COMPONENT}_ASCII OFFSET 0 LIMIT 1024) +- if("${Tbb_${COMPONENT}_ASCII}" MATCHES "INPUT \\(([^(]+)\\)") +- # Extract the directory and apply the matched text (in brackets) +- get_filename_component(Tbb_${COMPONENT}_DIR "${Tbb_${COMPONENT}_LIBRARY}" DIRECTORY) +- set(Tbb_${COMPONENT}_LIBRARY "${Tbb_${COMPONENT}_DIR}/${CMAKE_MATCH_1}") +- endif() ++ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") ++ find_package(Threads QUIET REQUIRED) ++ set_target_properties(TBB::tbb PROPERTIES INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS};Threads::Threads") + endif() + endif() + +- list(APPEND Tbb_LIB_COMPONENTS ${Tbb_${COMPONENT}_LIBRARY}) +- +- if(Tbb_${COMPONENT}_LIBRARY) +- set(TBB_${COMPONENT}_FOUND TRUE) +- else() +- set(TBB_${COMPONENT}_FOUND FALSE) ++ mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES) ++ ++ unset(TBB_ARCHITECTURE) ++ unset(TBB_BUILD_TYPE) ++ unset(TBB_LIB_PATH_SUFFIX) ++ unset(TBB_DEFAULT_SEARCH_DIR) ++ ++ if(TBB_DEBUG) ++ message(STATUS " TBB_FOUND = ${TBB_FOUND}") ++ message(STATUS " TBB_INCLUDE_DIRS = ${TBB_INCLUDE_DIRS}") ++ message(STATUS " TBB_DEFINITIONS = ${TBB_DEFINITIONS}") ++ message(STATUS " TBB_LIBRARIES = ${TBB_LIBRARIES}") ++ message(STATUS " TBB_DEFINITIONS_DEBUG = ${TBB_DEFINITIONS_DEBUG}") ++ message(STATUS " TBB_LIBRARIES_DEBUG = ${TBB_LIBRARIES_DEBUG}") ++ message(STATUS " TBB_DEFINITIONS_RELEASE = ${TBB_DEFINITIONS_RELEASE}") ++ message(STATUS " TBB_LIBRARIES_RELEASE = ${TBB_LIBRARIES_RELEASE}") + endif() +-endforeach() + +-if(UNIX AND TBB_USE_STATIC_LIBS) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +- unset(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +-endif() +- +-# ------------------------------------------------------------------------ +-# Cache and set TBB_FOUND +-# ------------------------------------------------------------------------ +- +-include(FindPackageHandleStandardArgs) +-find_package_handle_standard_args(TBB +- FOUND_VAR TBB_FOUND +- REQUIRED_VARS +- Tbb_INCLUDE_DIR +- Tbb_LIB_COMPONENTS +- VERSION_VAR Tbb_VERSION +- HANDLE_COMPONENTS +-) +- +-if(TBB_FOUND) +- set(Tbb_LIBRARIES +- ${Tbb_LIB_COMPONENTS} +- ) +- set(Tbb_INCLUDE_DIRS ${Tbb_INCLUDE_DIR}) +- set(Tbb_DEFINITIONS ${PC_Tbb_CFLAGS_OTHER}) +- +- set(Tbb_LIBRARY_DIRS "") +- foreach(LIB ${Tbb_LIB_COMPONENTS}) +- get_filename_component(_TBB_LIBDIR ${LIB} DIRECTORY) +- list(APPEND Tbb_LIBRARY_DIRS ${_TBB_LIBDIR}) +- endforeach() +- list(REMOVE_DUPLICATES Tbb_LIBRARY_DIRS) +- +- # Configure imported targets +- +- foreach(COMPONENT ${TBB_FIND_COMPONENTS}) +- if(NOT TARGET TBB::${COMPONENT}) +- add_library(TBB::${COMPONENT} UNKNOWN IMPORTED) +- set_target_properties(TBB::${COMPONENT} PROPERTIES +- IMPORTED_LOCATION "${Tbb_${COMPONENT}_LIBRARY}" +- INTERFACE_COMPILE_OPTIONS "${Tbb_DEFINITIONS}" +- INTERFACE_INCLUDE_DIRECTORIES "${Tbb_INCLUDE_DIR}" +- ) +- endif() +- endforeach() +-elseif(TBB_FIND_REQUIRED) +- message(FATAL_ERROR "Unable to find TBB") + endif() +diff --git a/openvdb/CMakeLists.txt b/openvdb/CMakeLists.txt +index 89301bd..df27aae 100644 +--- a/openvdb/CMakeLists.txt ++++ b/openvdb/CMakeLists.txt +@@ -78,7 +78,7 @@ else() + endif() + + find_package(TBB ${MINIMUM_TBB_VERSION} REQUIRED COMPONENTS tbb) +-if(${Tbb_VERSION} VERSION_LESS FUTURE_MINIMUM_TBB_VERSION) ++if(${TBB_VERSION} VERSION_LESS FUTURE_MINIMUM_TBB_VERSION) + message(DEPRECATION "Support for TBB versions < ${FUTURE_MINIMUM_TBB_VERSION} " + "is deprecated and will be removed.") + endif() +@@ -185,11 +185,6 @@ if(WIN32) + endif() + endif() + +-# @todo Should be target definitions +-if(WIN32) +- add_definitions(-D_WIN32 -DNOMINMAX -DOPENVDB_DLL) +-endif() +- + ##### Core library configuration + + set(OPENVDB_LIBRARY_SOURCE_FILES +@@ -374,10 +369,16 @@ set(OPENVDB_LIBRARY_UTIL_INCLUDE_FILES + + if(OPENVDB_CORE_SHARED) + add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES}) ++ if(WIN32) ++ target_compile_definitions(openvdb_shared PUBLIC OPENVDB_DLL) ++ endif() + endif() + + if(OPENVDB_CORE_STATIC) + add_library(openvdb_static STATIC ${OPENVDB_LIBRARY_SOURCE_FILES}) ++ if(WIN32) ++ target_compile_definitions(openvdb_static PUBLIC OPENVDB_STATICLIB) ++ endif() + endif() + + # Alias either the shared or static library to the generic OpenVDB +diff --git a/openvdb/Grid.cc b/openvdb/Grid.cc +index 0015f81..cb6084a 100644 +--- a/openvdb/Grid.cc ++++ b/openvdb/Grid.cc +@@ -35,6 +35,9 @@ + #include + #include + ++// WTF??? Somehow from stdlib.h ++#undef min ++#undef max + + namespace openvdb { + OPENVDB_USE_VERSION_NAMESPACE +diff --git a/openvdb/PlatformConfig.h b/openvdb/PlatformConfig.h +index 20ad9a3..c2dd1ef 100644 +--- a/openvdb/PlatformConfig.h ++++ b/openvdb/PlatformConfig.h +@@ -44,9 +44,12 @@ + + // By default, assume that we're dynamically linking OpenEXR, unless + // OPENVDB_OPENEXR_STATICLIB is defined. +- #if !defined(OPENVDB_OPENEXR_STATICLIB) && !defined(OPENEXR_DLL) +- #define OPENEXR_DLL +- #endif ++ // Meszaros Tamas: Why? OpenEXR and its imported targets have OPENEXR_DLL ++ // in INTERFACE_COMPILE_DEFINITIONS if build with it. ++ // #if !defined(OPENVDB_OPENEXR_STATICLIB) && !defined(OPENEXR_DLL) ++ // #define OPENEXR_DLL ++ // static_assert(false, "This is bad: OPENEXR_DLL"); ++ // #endif + + #endif // _WIN32 + +diff --git a/openvdb/cmd/CMakeLists.txt b/openvdb/cmd/CMakeLists.txt +index 57fbec0..55b3850 100644 +--- a/openvdb/cmd/CMakeLists.txt ++++ b/openvdb/cmd/CMakeLists.txt +@@ -74,8 +74,9 @@ if(WIN32) + endif() + endif() + ++# @todo Should be target definitions + if(WIN32) +- add_definitions(-D_WIN32 -DNOMINMAX -DOPENVDB_DLL) ++ add_definitions(-D_WIN32 -DNOMINMAX) + endif() + + # rpath handling +@@ -88,7 +89,6 @@ if(OPENVDB_ENABLE_RPATH) + ${IlmBase_LIBRARY_DIRS} + ${Log4cplus_LIBRARY_DIRS} + ${Blosc_LIBRARY_DIRS} +- ${Tbb_LIBRARY_DIRS} + ) + if(OPENVDB_BUILD_CORE) + list(APPEND RPATHS ${CMAKE_INSTALL_PREFIX}/lib) +diff --git a/openvdb/unittest/CMakeLists.txt b/openvdb/unittest/CMakeLists.txt +index c9e0c34..7e261c0 100644 +--- a/openvdb/unittest/CMakeLists.txt ++++ b/openvdb/unittest/CMakeLists.txt +@@ -71,8 +71,9 @@ if(WIN32) + link_directories(${Boost_LIBRARY_DIR}) + endif() + ++# @todo Should be target definitions + if(WIN32) +- add_definitions(-D_WIN32 -DNOMINMAX -DOPENVDB_DLL) ++ add_definitions(-D_WIN32 -DNOMINMAX) + endif() + + ##### VDB unit tests +diff --git a/openvdb/unittest/TestFile.cc b/openvdb/unittest/TestFile.cc +index df51830..0ab0c12 100644 +--- a/openvdb/unittest/TestFile.cc ++++ b/openvdb/unittest/TestFile.cc +@@ -2573,7 +2573,7 @@ TestFile::testBlosc() + outdata(new char[decompbufbytes]); + + for (int compcode = 0; compcode <= BLOSC_ZLIB; ++compcode) { +- char* compname = nullptr; ++ const char* compname = nullptr; + if (0 > blosc_compcode_to_compname(compcode, &compname)) continue; + /// @todo This changes the compressor setting globally. + if (blosc_set_compressor(compname) < 0) continue; +-- +2.16.2.windows.1 + diff --git a/deps/qhull-mods.patch b/deps/qhull-mods.patch index 94aeeca2f5..70f7be6a74 100644 --- a/deps/qhull-mods.patch +++ b/deps/qhull-mods.patch @@ -1,121 +1,49 @@ -From a31ae4781a4afa60e21c70e5b4ae784bcd447c8a Mon Sep 17 00:00:00 2001 +From 7f55a56b3d112f4dffbf21b1722f400c64bf03b1 Mon Sep 17 00:00:00 2001 From: tamasmeszaros -Date: Thu, 6 Jun 2019 15:41:43 +0200 -Subject: [PATCH] prusa-slicer changes +Date: Mon, 21 Oct 2019 16:52:04 +0200 +Subject: [PATCH] Fix the build on macOS --- - CMakeLists.txt | 44 +++++++++++++++++++++++++++++++++++--- - Config.cmake.in | 2 ++ - src/libqhull_r/qhull_r-exports.def | 2 ++ - src/libqhull_r/user_r.h | 2 +- - 4 files changed, 46 insertions(+), 4 deletions(-) - create mode 100644 Config.cmake.in + CMakeLists.txt | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt -index 59dff41..20c2ec5 100644 +index 07d3da2..14df8e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -61,7 +61,7 @@ - # $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $ +@@ -626,18 +626,18 @@ install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets + include(CMakePackageConfigHelpers) - project(qhull) --cmake_minimum_required(VERSION 2.6) -+cmake_minimum_required(VERSION 3.0) + write_basic_package_version_file( +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake" + VERSION ${qhull_VERSION} + COMPATIBILITY AnyNewerVersion + ) - # Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri - set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c -@@ -610,10 +610,48 @@ add_test(NAME user_eg3 - # Define install - # --------------------------------------- + export(EXPORT QhullTargets +- FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake" ++ FILE "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullTargets.cmake" + NAMESPACE Qhull:: + ) --install(TARGETS ${qhull_TARGETS_INSTALL} -+install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets - RUNTIME DESTINATION ${BIN_INSTALL_DIR} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} -- ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) -+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -+ INCLUDES DESTINATION include) -+ -+include(CMakePackageConfigHelpers) -+ -+write_basic_package_version_file( -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" -+ VERSION ${qhull_VERSION} -+ COMPATIBILITY AnyNewerVersion -+) -+ -+export(EXPORT QhullTargets -+ FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake" -+ NAMESPACE Qhull:: -+) -+ -+configure_file(Config.cmake.in -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" -+ @ONLY -+) -+ -+set(ConfigPackageLocation lib/cmake/Qhull) -+install(EXPORT QhullTargets -+ FILE -+ QhullTargets.cmake -+ NAMESPACE -+ Qhull:: -+ DESTINATION -+ ${ConfigPackageLocation} -+) -+install( -+ FILES -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" -+ "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" -+ DESTINATION -+ ${ConfigPackageLocation} -+ COMPONENT -+ Devel -+) + configure_file(${PROJECT_SOURCE_DIR}/build/config.cmake.in +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake" + @ONLY + ) - install(FILES ${libqhull_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull) - install(FILES ${libqhull_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull) -diff --git a/Config.cmake.in b/Config.cmake.in -new file mode 100644 -index 0000000..bc92bfe ---- /dev/null -+++ b/Config.cmake.in -@@ -0,0 +1,2 @@ -+include("${CMAKE_CURRENT_LIST_DIR}/QhullTargets.cmake") -+ -diff --git a/src/libqhull_r/qhull_r-exports.def b/src/libqhull_r/qhull_r-exports.def -index 325d57c..72f6ad0 100644 ---- a/src/libqhull_r/qhull_r-exports.def -+++ b/src/libqhull_r/qhull_r-exports.def -@@ -185,6 +185,7 @@ qh_memsetup - qh_memsize - qh_memstatistics - qh_memtotal -+qh_memcheck - qh_merge_degenredundant - qh_merge_nonconvex - qh_mergecycle -@@ -372,6 +373,7 @@ qh_settruncate - qh_setunique - qh_setvoronoi_all - qh_setzero -+qh_setendpointer - qh_sharpnewfacets - qh_skipfacet - qh_skipfilename -diff --git a/src/libqhull_r/user_r.h b/src/libqhull_r/user_r.h -index fc105b9..7cca65a 100644 ---- a/src/libqhull_r/user_r.h -+++ b/src/libqhull_r/user_r.h -@@ -139,7 +139,7 @@ Code flags -- - REALfloat = 1 all numbers are 'float' type - = 0 all numbers are 'double' type - */ --#define REALfloat 0 -+#define REALfloat 1 - - #if (REALfloat == 1) - #define realT float +@@ -652,8 +652,8 @@ install(EXPORT QhullTargets + ) + install( + FILES +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake" +- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake" ++ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake" + DESTINATION + ${ConfigPackageLocation} + COMPONENT -- -2.16.2.windows.1 +2.17.1 diff --git a/sandboxes/CMakeLists.txt b/sandboxes/CMakeLists.txt index 5905c438e9..3372698c39 100644 --- a/sandboxes/CMakeLists.txt +++ b/sandboxes/CMakeLists.txt @@ -1,2 +1,2 @@ -add_subdirectory(slabasebed) add_subdirectory(slasupporttree) +add_subdirectory(openvdb) diff --git a/sandboxes/openvdb/CMakeLists.txt b/sandboxes/openvdb/CMakeLists.txt new file mode 100644 index 0000000000..184452e833 --- /dev/null +++ b/sandboxes/openvdb/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(openvdb_example openvdb_example.cpp) +target_link_libraries(openvdb_example libslic3r) diff --git a/sandboxes/openvdb/openvdb_example.cpp b/sandboxes/openvdb/openvdb_example.cpp new file mode 100644 index 0000000000..0df60d8aa3 --- /dev/null +++ b/sandboxes/openvdb/openvdb_example.cpp @@ -0,0 +1,37 @@ +#include +#include + +int main() +{ + // Initialize the OpenVDB library. This must be called at least + // once per program and may safely be called multiple times. + openvdb::initialize(); + // Create an empty floating-point grid with background value 0. + openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(); + std::cout << "Testing random access:" << std::endl; + // Get an accessor for coordinate-based access to voxels. + openvdb::FloatGrid::Accessor accessor = grid->getAccessor(); + // Define a coordinate with large signed indices. + openvdb::Coord xyz(1000, -200000000, 30000000); + // Set the voxel value at (1000, -200000000, 30000000) to 1. + accessor.setValue(xyz, 1.0); + // Verify that the voxel value at (1000, -200000000, 30000000) is 1. + std::cout << "Grid" << xyz << " = " << accessor.getValue(xyz) << std::endl; + // Reset the coordinates to those of a different voxel. + xyz.reset(1000, 200000000, -30000000); + // Verify that the voxel value at (1000, 200000000, -30000000) is + // the background value, 0. + std::cout << "Grid" << xyz << " = " << accessor.getValue(xyz) << std::endl; + // Set the voxel value at (1000, 200000000, -30000000) to 2. + accessor.setValue(xyz, 2.0); + // Set the voxels at the two extremes of the available coordinate space. + // For 32-bit signed coordinates these are (-2147483648, -2147483648, -2147483648) + // and (2147483647, 2147483647, 2147483647). + accessor.setValue(openvdb::Coord::min(), 3.0f); + accessor.setValue(openvdb::Coord::max(), 4.0f); + std::cout << "Testing sequential access:" << std::endl; + // Print all active ("on") voxels by means of an iterator. + for (openvdb::FloatGrid::ValueOnCIter iter = grid->cbeginValueOn(); iter; ++iter) { + std::cout << "Grid" << iter.getCoord() << " = " << *iter << std::endl; + } +} diff --git a/sandboxes/slabasebed/CMakeLists.txt b/sandboxes/slabasebed/CMakeLists.txt deleted file mode 100644 index 9d731a1333..0000000000 --- a/sandboxes/slabasebed/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_executable(slabasebed EXCLUDE_FROM_ALL slabasebed.cpp) -target_link_libraries(slabasebed libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) diff --git a/sandboxes/slabasebed/slabasebed.cpp b/sandboxes/slabasebed/slabasebed.cpp deleted file mode 100644 index 1996a1eb87..0000000000 --- a/sandboxes/slabasebed/slabasebed.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -const std::string USAGE_STR = { - "Usage: slabasebed stlfilename.stl" -}; - -namespace Slic3r { namespace sla { - -Contour3D create_pad(const Polygons &ground_layer, - const ExPolygons &holes = {}, - const PadConfig& cfg = PadConfig()); - -Contour3D walls(const Polygon& floor_plate, const Polygon& ceiling, - double floor_z_mm, double ceiling_z_mm, - double offset_difference_mm, ThrowOnCancel thr); - -void offset(ExPolygon& sh, coord_t distance); - -} -} - -int main(const int argc, const char *argv[]) { - using namespace Slic3r; - using std::cout; using std::endl; - - if(argc < 2) { - cout << USAGE_STR << endl; - return EXIT_SUCCESS; - } - - TriangleMesh model; - Benchmark bench; - - model.ReadSTLFile(argv[1]); - model.align_to_origin(); - - ExPolygons ground_slice; - sla::pad_plate(model, ground_slice, 0.1f); - if(ground_slice.empty()) return EXIT_FAILURE; - - ground_slice = offset_ex(ground_slice, 0.5); - ExPolygon gndfirst; gndfirst = ground_slice.front(); - sla::breakstick_holes(gndfirst, 0.5, 10, 0.3); - - sla::Contour3D mesh; - - bench.start(); - - sla::PadConfig cfg; - cfg.min_wall_height_mm = 0; - cfg.edge_radius_mm = 0; - mesh = sla::create_pad(to_polygons(ground_slice), {}, cfg); - - bench.stop(); - - cout << "Base pool creation time: " << std::setprecision(10) - << bench.getElapsedSec() << " seconds." << endl; - - for(auto& trind : mesh.indices) { - Vec3d p0 = mesh.points[size_t(trind[0])]; - Vec3d p1 = mesh.points[size_t(trind[1])]; - Vec3d p2 = mesh.points[size_t(trind[2])]; - Vec3d p01 = p1 - p0; - Vec3d p02 = p2 - p0; - auto a = p01.cross(p02).norm() / 2.0; - if(std::abs(a) < 1e-6) std::cout << "degenerate triangle" << std::endl; - } - - // basepool.write_ascii("out.stl"); - - std::fstream outstream("out.obj", std::fstream::out); - mesh.to_obj(outstream); - - return EXIT_SUCCESS; -} diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index cbaa24e9ca..fb13acc85a 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -222,6 +222,7 @@ target_link_libraries(libslic3r qhull semver TBB::tbb + OpenVDB::openvdb ${CMAKE_DL_LIBS} ) diff --git a/src/qhull/CMakeLists.txt b/src/qhull/CMakeLists.txt index 9ca0bdff23..ab9aba9afa 100644 --- a/src/qhull/CMakeLists.txt +++ b/src/qhull/CMakeLists.txt @@ -18,11 +18,13 @@ if(Qhull_FOUND) message(STATUS "Using qhull from system.") if(SLIC3R_STATIC) + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhullstatic_r" RelWithDebInfo Release) target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhullstatic_r) else() + slic3r_remap_configs("Qhull::qhullcpp;Qhull::qhull_r" RelWithDebInfo Release) target_link_libraries(qhull INTERFACE Qhull::qhullcpp Qhull::qhull_r) endif() - + else(Qhull_FOUND) project(qhull) From bcc2c21d5fd9e9dc088f61ab84a5ca9b668e9e40 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 25 Oct 2019 13:23:05 +0200 Subject: [PATCH 33/82] Disable OpenVDB until deps get updated --- CMakeLists.txt | 2 +- src/libslic3r/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3b0fc5ed6..f76f1bb8df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -402,7 +402,7 @@ if(SLIC3R_STATIC) set(USE_BLOSC TRUE) endif() -find_package(OpenVDB 5.0 REQUIRED openvdb) +find_package(OpenVDB 5.0 COMPONENTS openvdb) slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) # libslic3r, PrusaSlicer GUI and the PrusaSlicer executable. diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index fb13acc85a..8b162a1d58 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -222,7 +222,7 @@ target_link_libraries(libslic3r qhull semver TBB::tbb - OpenVDB::openvdb + # OpenVDB::openvdb ${CMAKE_DL_LIBS} ) From 5e8572a196a3a50bb0733d1922cc24ddc37bebfa Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 25 Oct 2019 13:34:37 +0200 Subject: [PATCH 34/82] New functions for variable offsets of polygons / expolygons. Test cases for the above. Improvements of older test cases. --- src/libslic3r/ClipperUtils.cpp | 314 +++++++++++++++++++++++- src/libslic3r/ClipperUtils.hpp | 5 + src/libslic3r/ExPolygon.hpp | 9 + src/libslic3r/Polygon.hpp | 9 + tests/fff_print/test_flow.cpp | 3 - tests/fff_print/test_skirt_brim.cpp | 36 +-- tests/libslic3r/CMakeLists.txt | 2 + tests/libslic3r/test_clipper_offset.cpp | 214 ++++++++++++++++ 8 files changed, 565 insertions(+), 27 deletions(-) create mode 100644 tests/libslic3r/test_clipper_offset.cpp diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index b863b4712b..55bb4b446a 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -107,8 +107,7 @@ void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, ExPolygons* ex } } -ExPolygons -PolyTreeToExPolygons(ClipperLib::PolyTree& polytree) +ExPolygons PolyTreeToExPolygons(ClipperLib::PolyTree& polytree) { ExPolygons retval; for (int i = 0; i < polytree.ChildCount(); ++i) @@ -151,8 +150,7 @@ Slic3r::Polylines ClipperPaths_to_Slic3rPolylines(const ClipperLib::Paths &input return retval; } -ExPolygons -ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input) +ExPolygons ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input) { // init Clipper ClipperLib::Clipper clipper; @@ -167,8 +165,7 @@ ClipperPaths_to_Slic3rExPolygons(const ClipperLib::Paths &input) return PolyTreeToExPolygons(polytree); } -ClipperLib::Path -Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input) +ClipperLib::Path Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input) { ClipperLib::Path retval; for (Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit) @@ -176,8 +173,7 @@ Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input) return retval; } -ClipperLib::Path -Slic3rMultiPoint_to_ClipperPath_reversed(const Slic3r::MultiPoint &input) +ClipperLib::Path Slic3rMultiPoint_to_ClipperPath_reversed(const Slic3r::MultiPoint &input) { ClipperLib::Path output; output.reserve(input.points.size()); @@ -521,7 +517,7 @@ T _clipper_do(const ClipperLib::ClipType clipType, // Fix of #117: A large fractal pyramid takes ages to slice // The Clipper library has difficulties processing overlapping polygons. -// Namely, the function Clipper::JoinCommonEdges() has potentially a terrible time complexity if the output +// Namely, the function ClipperLib::JoinCommonEdges() has potentially a terrible time complexity if the output // of the operation is of the PolyTree type. // This function implmenets a following workaround: // 1) Peform the Clipper operation with the output to Paths. This method handles overlaps in a reasonable time. @@ -918,4 +914,304 @@ Polygons top_level_islands(const Slic3r::Polygons &polygons) return out; } +// Outer offset shall not split the input contour into multiples. It is expected, that the solution will be non empty and it will contain just a single polygon. +ClipperLib::Paths fix_after_outer_offset(const ClipperLib::Path &input, ClipperLib::PolyFillType filltype, bool reverse_result) +{ + ClipperLib::Paths solution; + if (! input.empty()) { + ClipperLib::Clipper clipper; + clipper.AddPath(input, ClipperLib::ptSubject, true); + clipper.ReverseSolution(reverse_result); + clipper.Execute(ClipperLib::ctUnion, solution, filltype, filltype); + } + return solution; +} + +// Inner offset may split the source contour into multiple contours, but one shall not be inside the other. +ClipperLib::Paths fix_after_inner_offset(const ClipperLib::Path &input, ClipperLib::PolyFillType filltype, bool reverse_result) +{ + ClipperLib::Paths solution; + if (! input.empty()) { + ClipperLib::Clipper clipper; + clipper.AddPath(input, ClipperLib::ptSubject, true); + ClipperLib::IntRect r = clipper.GetBounds(); + r.left -= 10; r.top -= 10; r.right += 10; r.bottom += 10; + if (filltype == ClipperLib::pftPositive) + clipper.AddPath({ ClipperLib::IntPoint(r.left, r.bottom), ClipperLib::IntPoint(r.left, r.top), ClipperLib::IntPoint(r.right, r.top), ClipperLib::IntPoint(r.right, r.bottom) }, ClipperLib::ptSubject, true); + else + clipper.AddPath({ ClipperLib::IntPoint(r.left, r.bottom), ClipperLib::IntPoint(r.right, r.bottom), ClipperLib::IntPoint(r.right, r.top), ClipperLib::IntPoint(r.left, r.top) }, ClipperLib::ptSubject, true); + clipper.ReverseSolution(reverse_result); + clipper.Execute(ClipperLib::ctUnion, solution, filltype, filltype); + if (! solution.empty()) + solution.erase(solution.begin()); + } + return solution; +} + +ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::vector &deltas, double miter_limit) +{ + assert(contour.size() == deltas.size()); +#ifndef NDEBUG + // Verify that the deltas are either all positive, or all negative. + bool positive = false; + bool negative = false; + for (float delta : deltas) + if (delta < 0.f) + negative = true; + else if (delta > 0.f) + positive = true; + assert(! (negative && positive)); +#endif /* NDEBUG */ + + ClipperLib::Path out; + + if (deltas.size() > 2) + { + out.reserve(contour.size() * 2); + + // Clamp miter limit to 2. + miter_limit = (miter_limit > 2.) ? 2. / (miter_limit * miter_limit) : 0.5; + + // perpenduclar vector + auto perp = [](const Vec2d &v) -> Vec2d { return Vec2d(v.y(), - v.x()); }; + + // Add a new point to the output, scale by CLIPPER_OFFSET_SCALE and round to ClipperLib::cInt. + auto add_offset_point = [&out](Vec2d pt) { + pt *= double(CLIPPER_OFFSET_SCALE); + pt += Vec2d(0.5 - (pt.x() < 0), 0.5 - (pt.y() < 0)); + out.emplace_back(ClipperLib::cInt(pt.x()), ClipperLib::cInt(pt.y())); + }; + + // Minimum edge length, squared. + double lmin = *std::max_element(deltas.begin(), deltas.end()) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR; + double l2min = lmin * lmin; + // Minimum angle to consider two edges to be parallel. + double sin_min_parallel = EPSILON + 1. / double(CLIPPER_OFFSET_SCALE); + + // Find the last point further from pt by l2min. + Vec2d pt = contour.front().cast(); + size_t iprev = contour.size() - 1; + Vec2d ptprev; + for (; iprev > 0; -- iprev) { + ptprev = contour[iprev].cast(); + if ((ptprev - pt).squaredNorm() > l2min) + break; + } + + if (iprev != 0) { + size_t ilast = iprev; + // Normal to the (pt - ptprev) segment. + Vec2d nprev = perp(pt - ptprev).normalized(); + for (size_t i = 0; ; ) { + // Find the next point further from pt by l2min. + size_t j = i + 1; + Vec2d ptnext; + for (; j <= ilast; ++ j) { + ptnext = contour[j].cast(); + double l2 = (ptnext - pt).squaredNorm(); + if (l2 > l2min) + break; + } + if (j > ilast) + ptnext = contour.front().cast(); + + // Normal to the (ptnext - pt) segment. + Vec2d nnext = perp(ptnext - pt).normalized(); + + double delta = deltas[i]; + double sin_a = clamp(-1., 1., cross2(nprev, nnext)); + double convex = sin_a * delta; + if (convex <= - sin_min_parallel) { + // Concave corner. + add_offset_point(pt + nprev * delta); + add_offset_point(pt); + add_offset_point(pt + nnext * delta); + } else if (convex < sin_min_parallel) { + // Nearly parallel. + add_offset_point((nprev.dot(nnext) > 0.) ? (pt + nprev * delta) : pt); + } else { + // Convex corner + double dot = nprev.dot(nnext); + double r = 1. + dot; + if (r >= miter_limit) + add_offset_point(pt + (nprev + nnext) * (delta / r)); + else { + double dx = std::tan(std::atan2(sin_a, dot) / 4.); + Vec2d newpt1 = pt + (nprev - perp(nprev) * dx) * delta; + Vec2d newpt2 = pt + (nnext + perp(nnext) * dx) * delta; +#ifndef NDEBUG + Vec2d vedge = 0.5 * (newpt1 + newpt2) - pt; + double dist_norm = vedge.norm(); + assert(std::abs(dist_norm - delta) < EPSILON); +#endif /* NDEBUG */ + add_offset_point(newpt1); + add_offset_point(newpt2); + } + } + + if (i == ilast) + break; + + ptprev = pt; + nprev = nnext; + pt = ptnext; + i = j; + } + } + } + + return out; +} + +Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit) +{ +#ifndef NDEBUG + // Verify that the deltas are all non positive. + for (const std::vector &ds : deltas) + for (float delta : ds) + assert(delta <= 0.); + assert(expoly.holes.size() + 1 == deltas.size()); +#endif /* NDEBUG */ + + // 1) Offset the outer contour. + ClipperLib::Paths contours = fix_after_inner_offset(mittered_offset_path_scaled(expoly.contour.points, deltas.front(), miter_limit), ClipperLib::pftNegative, true); + + // 2) Offset the holes one by one, collect the results. + ClipperLib::Paths holes; + holes.reserve(expoly.holes.size()); + for (const Polygon& hole : expoly.holes) + append(holes, fix_after_outer_offset(mittered_offset_path_scaled(hole, deltas[1 + &hole - expoly.holes.data()], miter_limit), ClipperLib::pftPositive, false)); + + // 3) Subtract holes from the contours. + ClipperLib::Paths output; + if (holes.empty()) + output = std::move(contours); + else { + ClipperLib::Clipper clipper; + clipper.Clear(); + clipper.AddPaths(contours, ClipperLib::ptSubject, true); + clipper.AddPaths(holes, ClipperLib::ptClip, true); + clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + } + + // 4) Unscale the output. + unscaleClipperPolygons(output); + return ClipperPaths_to_Slic3rPolygons(output); +} + +Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit) +{ +#ifndef NDEBUG + // Verify that the deltas are all non positive. +for (const std::vector& ds : deltas) + for (float delta : ds) + assert(delta >= 0.); + assert(expoly.holes.size() + 1 == deltas.size()); +#endif /* NDEBUG */ + + // 1) Offset the outer contour. + ClipperLib::Paths contours = fix_after_outer_offset(mittered_offset_path_scaled(expoly.contour.points, deltas.front(), miter_limit), ClipperLib::pftPositive, false); + + // 2) Offset the holes one by one, collect the results. + ClipperLib::Paths holes; + holes.reserve(expoly.holes.size()); + for (const Polygon& hole : expoly.holes) + append(holes, fix_after_inner_offset(mittered_offset_path_scaled(hole, deltas[1 + &hole - expoly.holes.data()], miter_limit), ClipperLib::pftPositive, true)); + + // 3) Subtract holes from the contours. + ClipperLib::Paths output; + if (holes.empty()) + output = std::move(contours); + else { + ClipperLib::Clipper clipper; + clipper.Clear(); + clipper.AddPaths(contours, ClipperLib::ptSubject, true); + clipper.AddPaths(holes, ClipperLib::ptClip, true); + clipper.Execute(ClipperLib::ctDifference, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + } + + // 4) Unscale the output. + unscaleClipperPolygons(output); + return ClipperPaths_to_Slic3rPolygons(output); +} + +ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit) +{ +#ifndef NDEBUG + // Verify that the deltas are all non positive. +for (const std::vector& ds : deltas) + for (float delta : ds) + assert(delta >= 0.); + assert(expoly.holes.size() + 1 == deltas.size()); +#endif /* NDEBUG */ + + // 1) Offset the outer contour. + ClipperLib::Paths contours = fix_after_outer_offset(mittered_offset_path_scaled(expoly.contour.points, deltas.front(), miter_limit), ClipperLib::pftPositive, false); + + // 2) Offset the holes one by one, collect the results. + ClipperLib::Paths holes; + holes.reserve(expoly.holes.size()); + for (const Polygon& hole : expoly.holes) + append(holes, fix_after_inner_offset(mittered_offset_path_scaled(hole, deltas[1 + &hole - expoly.holes.data()], miter_limit), ClipperLib::pftPositive, true)); + + // 3) Subtract holes from the contours. + unscaleClipperPolygons(contours); + ExPolygons output; + if (holes.empty()) { + output.reserve(contours.size()); + for (ClipperLib::Path &path : contours) + output.emplace_back(ClipperPath_to_Slic3rPolygon(path)); + } else { + ClipperLib::Clipper clipper; + unscaleClipperPolygons(holes); + clipper.AddPaths(contours, ClipperLib::ptSubject, true); + clipper.AddPaths(holes, ClipperLib::ptClip, true); + ClipperLib::PolyTree polytree; + clipper.Execute(ClipperLib::ctDifference, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + output = PolyTreeToExPolygons(polytree); + } + + return output; +} + + +ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit) +{ +#ifndef NDEBUG + // Verify that the deltas are all non positive. +for (const std::vector& ds : deltas) + for (float delta : ds) + assert(delta <= 0.); + assert(expoly.holes.size() + 1 == deltas.size()); +#endif /* NDEBUG */ + + // 1) Offset the outer contour. + ClipperLib::Paths contours = fix_after_inner_offset(mittered_offset_path_scaled(expoly.contour.points, deltas.front(), miter_limit), ClipperLib::pftNegative, false); + + // 2) Offset the holes one by one, collect the results. + ClipperLib::Paths holes; + holes.reserve(expoly.holes.size()); + for (const Polygon& hole : expoly.holes) + append(holes, fix_after_outer_offset(mittered_offset_path_scaled(hole, deltas[1 + &hole - expoly.holes.data()], miter_limit), ClipperLib::pftNegative, true)); + + // 3) Subtract holes from the contours. + unscaleClipperPolygons(contours); + ExPolygons output; + if (holes.empty()) { + output.reserve(contours.size()); + for (ClipperLib::Path &path : contours) + output.emplace_back(ClipperPath_to_Slic3rPolygon(path)); + } else { + ClipperLib::Clipper clipper; + unscaleClipperPolygons(holes); + clipper.AddPaths(contours, ClipperLib::ptSubject, true); + clipper.AddPaths(holes, ClipperLib::ptClip, true); + ClipperLib::PolyTree polytree; + clipper.Execute(ClipperLib::ctDifference, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); + output = PolyTreeToExPolygons(polytree); + } + + return output; +} + } diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index d8f8a8f943..5a41a6a909 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -238,6 +238,11 @@ void safety_offset(ClipperLib::Paths* paths); Polygons top_level_islands(const Slic3r::Polygons &polygons); +Polygons variable_offset_inner(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit = 2.); +Polygons variable_offset_outer(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit = 2.); +ExPolygons variable_offset_outer_ex(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit = 2.); +ExPolygons variable_offset_inner_ex(const ExPolygon &expoly, const std::vector> &deltas, double miter_limit = 2.); + } #endif diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index c510b848ff..08c4f7a07c 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -301,6 +301,15 @@ inline bool expolygons_contain(ExPolygons &expolys, const Point &pt) return false; } +inline ExPolygons expolygons_simplify(const ExPolygons &expolys, double tolerance) +{ + ExPolygons out; + out.reserve(expolys.size()); + for (const ExPolygon &exp : expolys) + exp.simplify(tolerance, &out); + return out; +} + extern BoundingBox get_extents(const ExPolygon &expolygon); extern BoundingBox get_extents(const ExPolygons &expolygons); extern BoundingBox get_extents_rotated(const ExPolygon &poly, double angle); diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 19be3068b9..ad1b32feb9 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -102,6 +102,15 @@ inline void polygons_append(Polygons &dst, Polygons &&src) } } +inline Polygons polygons_simplify(const Polygons &polys, double tolerance) +{ + Polygons out; + out.reserve(polys.size()); + for (const Polygon &p : polys) + polygons_append(out, p.simplify(tolerance)); + return out; +} + inline void polygons_rotate(Polygons &polys, double angle) { const double cos_angle = cos(angle); diff --git a/tests/fff_print/test_flow.cpp b/tests/fff_print/test_flow.cpp index 4541868dcb..969ae3c828 100644 --- a/tests/fff_print/test_flow.cpp +++ b/tests/fff_print/test_flow.cpp @@ -95,7 +95,6 @@ SCENARIO(" Bridge flow specifics.", "[Flow]") { SCENARIO("Flow: Flow math for non-bridges", "[Flow]") { GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") { ConfigOptionFloatOrPercent width(1.0, false); - float spacing = 0.4f; float nozzle_diameter = 0.4f; float bridge_flow = 0.f; float layer_height = 0.5f; @@ -119,7 +118,6 @@ SCENARIO("Flow: Flow math for non-bridges", "[Flow]") { } /// Check the min/max GIVEN("Nozzle Diameter of 0.25") { - float spacing = 0.4f; float nozzle_diameter = 0.25f; float bridge_flow = 0.f; float layer_height = 0.5f; @@ -161,7 +159,6 @@ SCENARIO("Flow: Flow math for non-bridges", "[Flow]") { SCENARIO("Flow: Flow math for bridges", "[Flow]") { GIVEN("Nozzle Diameter of 0.4, a desired width of 1mm and layer height of 0.5") { auto width = ConfigOptionFloatOrPercent(1.0, false); - float spacing = 0.4f; float nozzle_diameter = 0.4f; float bridge_flow = 1.0f; float layer_height = 0.5f; diff --git a/tests/fff_print/test_skirt_brim.cpp b/tests/fff_print/test_skirt_brim.cpp index 9fabb7aa67..11a83fe295 100644 --- a/tests/fff_print/test_skirt_brim.cpp +++ b/tests/fff_print/test_skirt_brim.cpp @@ -14,8 +14,8 @@ using namespace Slic3r; /// Helper method to find the tool used for the brim (always the first extrusion) static int get_brim_tool(const std::string &gcode) { - int brim_tool = -1; - int tool = -1; + int brim_tool = -1; + int tool = -1; GCodeReader parser; parser.parse_buffer(gcode, [&tool, &brim_tool] (Slic3r::GCodeReader &self, const Slic3r::GCodeReader::GCodeLine &line) { @@ -29,7 +29,7 @@ static int get_brim_tool(const std::string &gcode) return brim_tool; } -TEST_CASE("Skirt height is honored") { +TEST_CASE("Skirt height is honored", "[Skirt]") { DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_deserialize({ { "skirts", 1 }, @@ -60,7 +60,7 @@ TEST_CASE("Skirt height is honored") { REQUIRE(layers_with_skirt.size() == (size_t)config.opt_int("skirt_height")); } -SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { +SCENARIO("Original Slic3r Skirt/Brim tests", "[SkirtBrim]") { GIVEN("A default configuration") { DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); config.set_num_extruders(4); @@ -73,7 +73,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { { "first_layer_speed", "100%" }, // remove noise from top/solid layers { "top_solid_layers", 0 }, - { "bottom_solid_layers", 1 } + { "bottom_solid_layers", 1 }, + { "start_gcode", "T[initial_tool]\n" } }); WHEN("Brim width is set to 5") { @@ -120,25 +121,29 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { WHEN("Perimeter extruder = 2 and support extruders = 3") { THEN("Brim is printed with the extruder used for the perimeters of first object") { - std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { + config.set_deserialize({ { "skirts", 0 }, { "brim_width", 5 }, { "perimeter_extruder", 2 }, - { "support_material_extruder", 3 } - }); + { "support_material_extruder", 3 }, + { "infill_extruder", 4 } + }); + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); int tool = get_brim_tool(gcode); REQUIRE(tool == config.opt_int("perimeter_extruder") - 1); } } WHEN("Perimeter extruder = 2, support extruders = 3, raft is enabled") { THEN("brim is printed with same extruder as skirt") { - std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, { - { "skirts", 0 }, - { "brim_width", 5 }, - { "perimeter_extruder", 2 }, - { "support_material_extruder", 3 }, - { "raft_layers", 1 } - }); + config.set_deserialize({ + { "skirts", 0 }, + { "brim_width", 5 }, + { "perimeter_extruder", 2 }, + { "support_material_extruder", 3 }, + { "infill_extruder", 4 }, + { "raft_layers", 1 } + }); + std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); int tool = get_brim_tool(gcode); REQUIRE(tool == config.opt_int("support_material_extruder") - 1); } @@ -200,6 +205,7 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[!mayfail]") { { "infill_extruder", 3 }, // ensure that a tool command gets emitted. { "cooling", false }, // to prevent speeds to be altered { "first_layer_speed", "100%" }, // to prevent speeds to be altered + { "start_gcode", "T[initial_tool]\n" } }); THEN("overhang generates?") { diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 2dd2b34a3e..b9d7fc8986 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -2,7 +2,9 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp test_3mf.cpp + test_clipper_offset.cpp test_config.cpp +# test_elephant_foot_compensation.cpp test_geometry.cpp test_polygon.cpp test_stl.cpp diff --git a/tests/libslic3r/test_clipper_offset.cpp b/tests/libslic3r/test_clipper_offset.cpp new file mode 100644 index 0000000000..fed89c66ce --- /dev/null +++ b/tests/libslic3r/test_clipper_offset.cpp @@ -0,0 +1,214 @@ +#include + +#include +#include + +#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/ExPolygon.hpp" +#include "libslic3r/SVG.hpp" + +using namespace Slic3r; + +#define TESTS_EXPORT_SVGS + +SCENARIO("Constant offset", "[ClipperUtils]") { + coord_t s = 1000000; + GIVEN("20mm box") { + ExPolygon box20mm; + box20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 20 * s, 20 * s}, { 0, 20 * s} }; + std::vector deltas_plus(box20mm.contour.points.size(), 1. * s); + std::vector deltas_minus(box20mm.contour.points.size(), - 1. * s); + Polygons output; + WHEN("Slic3r::offset()") { + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("plus 1mm, miter " << miter << "x") { + output = Slic3r::offset(box20mm, 1. * s, ClipperLib::jtMiter, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("constant_offset_box20mm_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 22^2mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(22. * 22. * s * s)); + } + } + DYNAMIC_SECTION("minus 1mm, miter " << miter << "x") { + output = Slic3r::offset(box20mm, - 1. * s, ClipperLib::jtMiter, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("constant_offset_box20mm_minus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 18^2mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(18. * 18. * s * s)); + } + } + } + } + WHEN("Slic3r::variable_offset_outer/inner") { + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("plus 1mm, miter " << miter << "x") { + output = Slic3r::variable_offset_outer(box20mm, { deltas_plus }, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("variable_offset_box20mm_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 22^2mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(22. * 22. * s * s)); + } + } + DYNAMIC_SECTION("minus 1mm, miter " << miter << "x") { + output = Slic3r::variable_offset_inner(box20mm, { deltas_minus }, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("variable_offset_box20mm_minus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 18^2mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(18. * 18. * s * s)); + } + } + } + } + } + + GIVEN("20mm box with 10mm hole") { + ExPolygon box20mm; + box20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 20 * s, 20 * s}, { 0, 20 * s} }; + box20mm.holes.emplace_back(Slic3r::Polygon({ { 5 * s, 5 * s }, { 5 * s, 15 * s}, { 15 * s, 15 * s}, { 15 * s, 5 * s } })); + std::vector deltas_plus(box20mm.contour.points.size(), 1. * s); + std::vector deltas_minus(box20mm.contour.points.size(), -1. * s); + ExPolygons output; + SECTION("Slic3r::offset()") { + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("miter " << miter << "x") { + WHEN("plus 1mm") { + output = Slic3r::offset_ex(box20mm, 1. * s, ClipperLib::jtMiter, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("constant_offset_box20mm_10mm_hole_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(to_polygons(output), "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 22^2-8^2 mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx((22. * 22. - 8. * 8.) * s * s)); + } + } + WHEN("minus 1mm") { + output = Slic3r::offset_ex(box20mm, - 1. * s, ClipperLib::jtMiter, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("constant_offset_box20mm_10mm_hole_minus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(to_polygons(output), "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 18^2-12^2 mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx((18. * 18. - 12. * 12.) * s * s)); + } + } + } + } + } + SECTION("Slic3r::variable_offset_outer()") { + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("miter " << miter << "x") { + WHEN("plus 1mm") { + output = Slic3r::variable_offset_outer_ex(box20mm, { deltas_plus, deltas_plus }, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("variable_offset_box20mm_10mm_hole_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(to_polygons(output), "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 22^2-8^2 mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx((22. * 22. - 8. * 8.) * s * s)); + } + } + WHEN("minus 1mm") { + output = Slic3r::variable_offset_inner_ex(box20mm, { deltas_minus, deltas_minus }, miter); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("variable_offset_box20mm_10mm_hole_minus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(box20mm, "blue"); + svg.draw_outline(to_polygons(output), "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area is 18^2-12^2 mm2") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx((18. * 18. - 12. * 12.) * s * s)); + } + } + } + } + } + } + + GIVEN("20mm right angle triangle") { + ExPolygon triangle20mm; + triangle20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 0, 20 * s} }; + Polygons output; + double offset = 1.; + // Angle of the sharp corner bisector. + double angle_bisector = M_PI / 8.; + // Area tapered by mitering one sharp corner. + double area_tapered = pow(offset * (1. / sin(angle_bisector) - 1.), 2.) * tan(angle_bisector); + double l_triangle_side_offsetted = 20. + offset * (1. + 1. / tan(angle_bisector)); + double area_offsetted = (0.5 * l_triangle_side_offsetted * l_triangle_side_offsetted - 2. * area_tapered) * s * s; + SECTION("Slic3r::offset()") { + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("Outer offset 1mm, miter " << miter << "x") { + output = Slic3r::offset(triangle20mm, offset * s, ClipperLib::jtMiter, 2.0); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("constant_offset_triangle20mm_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(triangle20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area matches") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(area_offsetted)); + } + } + } + } + SECTION("Slic3r::variable_offset_outer()") { + std::vector deltas(triangle20mm.contour.points.size(), 1. * s); + for (double miter : { 2.0, 1.5, 1.2 }) { + DYNAMIC_SECTION("Outer offset 1mm, miter " << miter << "x") { + output = Slic3r::variable_offset_outer(triangle20mm, { deltas }, 2.0); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("variable_offset_triangle20mm_plus1mm_miter%lf.svg", miter).c_str(), get_extents(output)); + svg.draw(triangle20mm, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif + THEN("Area matches") { + REQUIRE(output.size() == 1); + REQUIRE(output.front().area() == Approx(area_offsetted)); + } + } + } + } + } +} From 5c0cd06f2f37bec076d39ad932ca0a0fd40446b5 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 25 Oct 2019 13:38:18 +0200 Subject: [PATCH 35/82] Completely disable openvdb for now --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f76f1bb8df..2b22f10016 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -402,8 +402,8 @@ if(SLIC3R_STATIC) set(USE_BLOSC TRUE) endif() -find_package(OpenVDB 5.0 COMPONENTS openvdb) -slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) +#find_package(OpenVDB 5.0 COMPONENTS openvdb) +#slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release) # libslic3r, PrusaSlicer GUI and the PrusaSlicer executable. add_subdirectory(src) From 2d5c28d6d16b05cde3112b3ee4e92db634c975e0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 13:59:13 +0200 Subject: [PATCH 36/82] ENABLE_THUMBNAIL_GENERATOR -> Allow for multiple thumbnails into gcode and sl1 files --- src/libslic3r/GCode.cpp | 28 ++++++++++------ src/libslic3r/GCode.hpp | 4 +-- src/libslic3r/Print.cpp | 2 +- src/libslic3r/Print.hpp | 2 +- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 22 +++++++++--- src/slic3r/GUI/BackgroundSlicingProcess.hpp | 6 ++-- src/slic3r/GUI/Plater.cpp | 37 ++++++++++++++++----- 7 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index db493270a7..92f733787a 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -659,7 +659,7 @@ std::vector>> GCode::collec } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +void GCode::do_export(Print* print, const char* path, GCodePreviewData* preview_data, const std::vector* thumbnail_data) #else void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -757,7 +757,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_ } #if ENABLE_THUMBNAIL_GENERATOR -void GCode::_do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data) +void GCode::_do_export(Print& print, FILE* file, const std::vector* thumbnail_data) #else void GCode::_do_export(Print &print, FILE *file) #endif // ENABLE_THUMBNAIL_GENERATOR @@ -954,18 +954,24 @@ void GCode::_do_export(Print &print, FILE *file) _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); #if ENABLE_THUMBNAIL_GENERATOR - // Write thumbnail using base64 encoding - if ((thumbnail_data != nullptr) && thumbnail_data->is_valid()) + // Write thumbnails using base64 encoding + if (thumbnail_data != nullptr) { - _write_format(file, "\n;\n; thumbnail begin %dx%d\n", thumbnail_data->width, thumbnail_data->height); - - size_t row_size = 4 * thumbnail_data->width; - for (int r = (int)thumbnail_data->height - 1; r >= 0; --r) + for (const ThumbnailData& data : *thumbnail_data) { - _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(thumbnail_data->pixels.data() + r * row_size), row_size).c_str()); - } + if (data.is_valid()) + { + _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); - _write(file, "; thumbnail end\n;\n\n"); + size_t row_size = 4 * data.width; + for (int r = (int)data.height - 1; r >= 0; --r) + { + _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size).c_str()); + } + + _write(file, "; thumbnail end\n;\n\n"); + } + } } #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8116d06fc6..3183e8883e 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -166,7 +166,7 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). #if ENABLE_THUMBNAIL_GENERATOR - void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const ThumbnailData* thumbnail_data = nullptr); + void do_export(Print* print, const char* path, GCodePreviewData* preview_data = nullptr, const std::vector* thumbnail_data = nullptr); #else void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr); #endif // ENABLE_THUMBNAIL_GENERATOR @@ -198,7 +198,7 @@ public: protected: #if ENABLE_THUMBNAIL_GENERATOR - void _do_export(Print& print, FILE* file, const ThumbnailData* thumbnail_data); + void _do_export(Print& print, FILE* file, const std::vector* thumbnail_data); #else void _do_export(Print &print, FILE *file); #endif //ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index b2ed87ca01..74e541451e 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1537,7 +1537,7 @@ void Print::process() // write error into the G-code, cannot execute post-processing scripts). // It is up to the caller to show an error message. #if ENABLE_THUMBNAIL_GENERATOR -std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data) +std::string Print::export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data) #else std::string Print::export_gcode(const std::string &path_template, GCodePreviewData *preview_data) #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index aedeeff18c..7e7f875b0d 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -309,7 +309,7 @@ public: // Exports G-code into a file name based on the path_template, returns the file path of the generated G-code file. // If preview_data is not null, the preview_data is filled in for the G-code visualization (not used by the command line Slic3r). #if ENABLE_THUMBNAIL_GENERATOR - std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const ThumbnailData* thumbnail_data = nullptr); + std::string export_gcode(const std::string& path_template, GCodePreviewData* preview_data, const std::vector* thumbnail_data = nullptr); #else std::string export_gcode(const std::string &path_template, GCodePreviewData *preview_data); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index cedeab910c..18f593d77c 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -120,7 +120,7 @@ static void write_thumbnail(Zipper& zipper, const ThumbnailData& data) void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); if (png_data != nullptr) { - zipper.add_entry("thumbnail/thumbnail.png", (const std::uint8_t*)png_data, png_size); + zipper.add_entry("thumbnail/thumbnail" + std::to_string(data.width) + "x" + std::to_string(data.height) + ".png", (const std::uint8_t*)png_data, png_size); mz_free(png_data); } } @@ -138,8 +138,14 @@ void BackgroundSlicingProcess::process_sla() m_sla_print->export_raster(zipper); #if ENABLE_THUMBNAIL_GENERATOR - if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) - write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data != nullptr) + { + for (const ThumbnailData& data : *m_thumbnail_data) + { + if (data.is_valid()) + write_thumbnail(zipper, data); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR zipper.finalize(); @@ -458,8 +464,14 @@ void BackgroundSlicingProcess::prepare_upload() Zipper zipper{source_path.string()}; m_sla_print->export_raster(zipper, m_upload_job.upload_data.upload_path.string()); #if ENABLE_THUMBNAIL_GENERATOR - if ((m_thumbnail_data != nullptr) && m_thumbnail_data->is_valid()) - write_thumbnail(zipper, *m_thumbnail_data); + if (m_thumbnail_data != nullptr) + { + for (const ThumbnailData& data : *m_thumbnail_data) + { + if (data.is_valid()) + write_thumbnail(zipper, data); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR zipper.finalize(); } diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.hpp b/src/slic3r/GUI/BackgroundSlicingProcess.hpp index e51a4e961a..bf8cbc2359 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.hpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.hpp @@ -53,7 +53,7 @@ public: void set_sla_print(SLAPrint *print) { m_sla_print = print; } void set_gcode_preview_data(GCodePreviewData *gpd) { m_gcode_preview_data = gpd; } #if ENABLE_THUMBNAIL_GENERATOR - void set_thumbnail_data(const ThumbnailData* data) { m_thumbnail_data = data; } + void set_thumbnail_data(const std::vector* data) { m_thumbnail_data = data; } #endif // ENABLE_THUMBNAIL_GENERATOR // The following wxCommandEvent will be sent to the UI thread / Platter window, when the slicing is finished @@ -159,8 +159,8 @@ private: // Data structure, to which the G-code export writes its annotations. GCodePreviewData *m_gcode_preview_data = nullptr; #if ENABLE_THUMBNAIL_GENERATOR - // Data structure, used to write thumbnail into gcode. - const ThumbnailData *m_thumbnail_data = nullptr; + // Data structures, used to write thumbnails into gcode. + const std::vector* m_thumbnail_data = nullptr; #endif // ENABLE_THUMBNAIL_GENERATOR // Temporary G-code, there is one defined for the BackgroundSlicingProcess, differentiated from the other processes by a process ID. std::string m_temp_output_path; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 60a90f1f13..ccfa46abef 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -86,8 +86,8 @@ using Slic3r::Preset; using Slic3r::PrintHostJob; #if ENABLE_THUMBNAIL_GENERATOR -static const std::pair THUMBNAIL_SIZE_FFF = { 128, 128 }; -static const std::pair THUMBNAIL_SIZE_SLA = { 256, 256 }; +static const std::vector < std::pair> THUMBNAIL_SIZE_FFF = { { 240, 320 }, { 220, 165 }, { 16, 16 } }; +static const std::vector> THUMBNAIL_SIZE_SLA = { { 800, 480 } }; static const std::pair THUMBNAIL_SIZE_3MF = { 256, 256 }; #endif // ENABLE_THUMBNAIL_GENERATOR @@ -1371,7 +1371,7 @@ struct Plater::priv PrinterTechnology printer_technology = ptFFF; Slic3r::GCodePreviewData gcode_preview_data; #if ENABLE_THUMBNAIL_GENERATOR - Slic3r::ThumbnailData thumbnail_data; + std::vector thumbnail_data; #endif // ENABLE_THUMBNAIL_GENERATOR // GUI elements @@ -3050,12 +3050,26 @@ bool Plater::priv::restart_background_process(unsigned int state) { // update thumbnail data if (this->printer_technology == ptFFF) - // for ptFFF we need to generate the thumbnail before the export of gcode starts - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_FFF.first, THUMBNAIL_SIZE_FFF.second, true, true); + { + // for ptFFF we need to generate the thumbnails before the export of gcode starts + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_FFF) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + } + } else if (this->printer_technology == ptSLA) - // for ptSLA generate thumbnail without supports and pad (not yet calculated) + { + // for ptSLA generate thumbnails without supports and pad (not yet calculated) // to render also supports and pad see on_slicing_update() - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, true); + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_SLA) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + } + } } #endif // ENABLE_THUMBNAIL_GENERATOR // The print is valid and it can be started. @@ -3402,7 +3416,14 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) // update thumbnail data // for ptSLA generate the thumbnail after supports and pad have been calculated to have them rendered if ((this->printer_technology == ptSLA) && (evt.status.percent == -3)) - generate_thumbnail(this->thumbnail_data, THUMBNAIL_SIZE_SLA.first, THUMBNAIL_SIZE_SLA.second, true, false); + { + this->thumbnail_data.clear(); + for (const std::pair& size : THUMBNAIL_SIZE_SLA) + { + this->thumbnail_data.push_back(ThumbnailData()); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false); + } + } #endif // ENABLE_THUMBNAIL_GENERATOR */ } From 24aed8eb71ab3d983589d42fba347664466b223d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 25 Oct 2019 14:32:31 +0200 Subject: [PATCH 37/82] ENABLE_THUMBNAIL_GENERATOR -> Added missing include --- src/slic3r/GUI/GUI_App.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 0b2244d656..c35985f112 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -53,6 +53,7 @@ #if ENABLE_THUMBNAIL_GENERATOR #include +#include #endif // ENABLE_THUMBNAIL_GENERATOR namespace Slic3r { From f8dc74374c9f64e0f09c01b811deb3b4457598df Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 25 Oct 2019 17:07:55 +0200 Subject: [PATCH 38/82] Ported various clipper unit tests from Perl to C++, the clipper Perl unit tests were removed. --- src/libslic3r/ExPolygon.hpp | 5 + src/libslic3r/Polygon.hpp | 7 +- t/clipper.t | 89 ---------- tests/libslic3r/CMakeLists.txt | 1 + tests/libslic3r/test_clipper_utils.cpp | 225 +++++++++++++++++++++++++ xs/t/11_clipper.t | 193 --------------------- 6 files changed, 237 insertions(+), 283 deletions(-) delete mode 100644 t/clipper.t create mode 100644 tests/libslic3r/test_clipper_utils.cpp delete mode 100644 xs/t/11_clipper.t diff --git a/src/libslic3r/ExPolygon.hpp b/src/libslic3r/ExPolygon.hpp index 08c4f7a07c..7833c9c913 100644 --- a/src/libslic3r/ExPolygon.hpp +++ b/src/libslic3r/ExPolygon.hpp @@ -28,6 +28,8 @@ public: explicit ExPolygon(Polygon &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); } explicit ExPolygon(const Points &contour, const Points &hole) : contour(contour) { holes.emplace_back(hole); } explicit ExPolygon(Points &&contour, Polygon &&hole) : contour(std::move(contour)) { holes.emplace_back(std::move(hole)); } + ExPolygon(std::initializer_list contour) : contour(contour) {} + ExPolygon(std::initializer_list contour, std::initializer_list hole) : contour(contour), holes({ hole }) {} ExPolygon& operator=(const ExPolygon &other) { contour = other.contour; holes = other.holes; return *this; } ExPolygon& operator=(ExPolygon &&other) { contour = std::move(other.contour); holes = std::move(other.holes); return *this; } @@ -77,6 +79,9 @@ public: Lines lines() const; }; +inline bool operator==(const ExPolygon &lhs, const ExPolygon &rhs) { return lhs.contour == rhs.contour && lhs.holes == rhs.holes; } +inline bool operator!=(const ExPolygon &lhs, const ExPolygon &rhs) { return lhs.contour != rhs.contour || lhs.holes != rhs.holes; } + // Count a nuber of polygons stored inside the vector of expolygons. // Useful for allocating space for polygons when converting expolygons to polygons. inline size_t number_polygons(const ExPolygons &expolys) diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index ad1b32feb9..4d53e97e1c 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -22,7 +22,8 @@ public: const Point& operator[](Points::size_type idx) const { return this->points[idx]; } Polygon() {} - explicit Polygon(const Points &points): MultiPoint(points) {} + explicit Polygon(const Points &points) : MultiPoint(points) {} + Polygon(std::initializer_list points) : MultiPoint(points) {} Polygon(const Polygon &other) : MultiPoint(other.points) {} Polygon(Polygon &&other) : MultiPoint(std::move(other.points)) {} static Polygon new_scale(const std::vector &points) { @@ -66,6 +67,10 @@ public: Point point_projection(const Point &point) const; }; +inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; } +inline bool operator!=(const Polygon &lhs, const Polygon &rhs) { return lhs.points != rhs.points; } + + extern BoundingBox get_extents(const Polygon &poly); extern BoundingBox get_extents(const Polygons &polygons); extern BoundingBox get_extents_rotated(const Polygon &poly, double angle); diff --git a/t/clipper.t b/t/clipper.t deleted file mode 100644 index 3c9838143a..0000000000 --- a/t/clipper.t +++ /dev/null @@ -1,89 +0,0 @@ -use Test::More; -use strict; -use warnings; - -plan tests => 6; - -BEGIN { - use FindBin; - use lib "$FindBin::Bin/../lib"; - use local::lib "$FindBin::Bin/../local-lib"; -} - -use List::Util qw(sum); -use Slic3r; -use Slic3r::Geometry::Clipper qw(intersection_ex union_ex diff_ex diff_pl); - -{ - my $square = [ # ccw - [10, 10], - [20, 10], - [20, 20], - [10, 20], - ]; - my $hole_in_square = [ # cw - [14, 14], - [14, 16], - [16, 16], - [16, 14], - ]; - my $square2 = [ # ccw - [5, 12], - [25, 12], - [25, 18], - [5, 18], - ]; - my $intersection = intersection_ex([ $square, $hole_in_square ], [ $square2 ]); - - is sum(map $_->area, @$intersection), Slic3r::ExPolygon->new( - [ - [20, 18], - [10, 18], - [10, 12], - [20, 12], - ], - [ - [14, 16], - [16, 16], - [16, 14], - [14, 14], - ], - )->area, 'hole is preserved after intersection'; -} - -#========================================================== - -{ - my $contour1 = [ [0,0], [40,0], [40,40], [0,40] ]; # ccw - my $contour2 = [ [10,10], [30,10], [30,30], [10,30] ]; # ccw - my $hole = [ [15,15], [15,25], [25,25], [25,15] ]; # cw - - my $union = union_ex([ $contour1, $contour2, $hole ]); - - is_deeply [ map $_->pp, @$union ], [[ [ [40,40], [0,40], [0,0], [40,0] ] ]], - 'union of two ccw and one cw is a contour with no holes'; - - my $diff = diff_ex([ $contour1, $contour2 ], [ $hole ]); - is sum(map $_->area, @$diff), - Slic3r::ExPolygon->new([ [40,40], [0,40], [0,0], [40,0] ], [ [15,25], [25,25], [25,15], [15,15] ])->area, - 'difference of a cw from two ccw is a contour with one hole'; -} - -#========================================================== - -{ - my $square = Slic3r::Polygon->new_scale( # ccw - [10, 10], - [20, 10], - [20, 20], - [10, 20], - ); - my $square_pl = $square->split_at_first_point; - - my $res = diff_pl([$square_pl], []); - is scalar(@$res), 1, 'no-op diff_pl returns the right number of polylines'; - isa_ok $res->[0], 'Slic3r::Polyline', 'no-op diff_pl result'; - is scalar(@{$res->[0]}), scalar(@$square_pl), 'no-op diff_pl returns the unmodified input polyline'; -} - -__END__ diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index cdb20f3a42..c2a4b4f781 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp test_3mf.cpp test_clipper_offset.cpp + test_clipper_utils.cpp test_config.cpp # test_elephant_foot_compensation.cpp test_geometry.cpp diff --git a/tests/libslic3r/test_clipper_utils.cpp b/tests/libslic3r/test_clipper_utils.cpp new file mode 100644 index 0000000000..21d2c2cd40 --- /dev/null +++ b/tests/libslic3r/test_clipper_utils.cpp @@ -0,0 +1,225 @@ +#include + +#include +#include + +#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/ExPolygon.hpp" +#include "libslic3r/SVG.hpp" + +using namespace Slic3r; + +SCENARIO("Various Clipper operations - xs/t/11_clipper.t", "[ClipperUtils]") { + // CCW oriented contour + Slic3r::Polygon square{ { 200, 100 }, {200, 200}, {100, 200}, {100, 100} }; + // CW oriented contour + Slic3r::Polygon hole_in_square{ { 160, 140 }, { 140, 140 }, { 140, 160 }, { 160, 160 } }; + Slic3r::ExPolygon square_with_hole(square, hole_in_square); + GIVEN("square_with_hole") { + WHEN("offset") { + Polygons result = Slic3r::offset(square_with_hole, 5.f); + THEN("offset matches") { + REQUIRE(result == Polygons { + { { 205, 205 }, { 95, 205 }, { 95, 95 }, { 205, 95 }, }, + { { 145, 145 }, { 145, 155 }, { 155, 155 }, { 155, 145 } } }); + } + } + WHEN("offset_ex") { + ExPolygons result = Slic3r::offset_ex(square_with_hole, 5.f); + THEN("offset matches") { + REQUIRE(result == ExPolygons { { + { { 205, 205 }, { 95, 205 }, { 95, 95 }, { 205, 95 }, }, + { { 145, 145 }, { 145, 155 }, { 155, 155 }, { 155, 145 } } } } ); + } + } + WHEN("offset2_ex") { + ExPolygons result = Slic3r::offset2_ex(square_with_hole, 5.f, -2.f); + THEN("offset matches") { + REQUIRE(result == ExPolygons { { + { { 203, 203 }, { 97, 203 }, { 97, 97 }, { 203, 97 } }, + { { 143, 143 }, { 143, 157 }, { 157, 157 }, { 157, 143 } } } } ); + } + } + } + GIVEN("square_with_hole 2") { + Slic3r::ExPolygon square_with_hole( + { { 20000000, 20000000 }, { 0, 20000000 }, { 0, 0 }, { 20000000, 0 } }, + { { 5000000, 15000000 }, { 15000000, 15000000 }, { 15000000, 5000000 }, { 5000000, 5000000 } }); + WHEN("offset2_ex") { + Slic3r::ExPolygons result = Slic3r::offset2_ex(ExPolygons { square_with_hole }, -1.f, 1.f); + THEN("offset matches") { + REQUIRE(result.size() == 1); + REQUIRE(square_with_hole.area() == result.front().area()); + } + } + } + GIVEN("square and hole") { + WHEN("diff_ex") { + ExPolygons result = Slic3r::diff_ex({ square }, { hole_in_square }); + THEN("hole is created") { + REQUIRE(result.size() == 1); + REQUIRE(square_with_hole.area() == result.front().area()); + } + } + } + GIVEN("polyline") { + Polyline polyline { { 50, 150 }, { 300, 150 } }; + WHEN("intersection_pl") { + Polylines result = Slic3r::intersection_pl({ polyline }, { square, hole_in_square }); + THEN("correct number of result lines") { + REQUIRE(result.size() == 2); + } + THEN("result lines have correct length") { + // results are in no particular order + REQUIRE(result[0].length() == 40); + REQUIRE(result[1].length() == 40); + } + } + WHEN("diff_pl") { + Polylines result = Slic3r::diff_pl({ polyline }, { square, hole_in_square }); + THEN("correct number of result lines") { + REQUIRE(result.size() == 3); + } + // results are in no particular order + THEN("the left result line has correct length") { + REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 50; }) == 1); + } + THEN("the right result line has correct length") { + REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 100; }) == 1); + } + THEN("the central result line has correct length") { + REQUIRE(std::count_if(result.begin(), result.end(), [](const Polyline &pl) { return pl.length() == 20; }) == 1); + } + } + } + GIVEN("Clipper bug #96 / Slic3r issue #2028") { + Slic3r::Polyline subject{ + { 44735000, 31936670 }, { 55270000, 31936670 }, { 55270000, 25270000 }, { 74730000, 25270000 }, { 74730000, 44730000 }, { 68063296, 44730000 }, { 68063296, 55270000 }, { 74730000, 55270000 }, + { 74730000, 74730000 }, { 55270000, 74730000 }, { 55270000, 68063296 }, { 44730000, 68063296 }, { 44730000, 74730000 }, { 25270000, 74730000 }, { 25270000, 55270000 }, { 31936670, 55270000 }, + { 31936670, 44730000 }, { 25270000, 44730000 }, { 25270000, 25270000 }, { 44730000, 25270000 }, { 44730000, 31936670 } }; + Slic3r::Polygon clip { {75200000, 45200000}, {54800000, 45200000}, {54800000, 24800000}, {75200000, 24800000} }; + Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, { clip }); + THEN("intersection_pl - result is not empty") { + REQUIRE(result.size() == 1); + } + } + GIVEN("Clipper bug #122") { + Slic3r::Polyline subject { { 1975, 1975 }, { 25, 1975 }, { 25, 25 }, { 1975, 25 }, { 1975, 1975 } }; + Slic3r::Polygons clip { { { 2025, 2025 }, { -25, 2025 } , { -25, -25 }, { 2025, -25 } }, + { { 525, 525 }, { 525, 1475 }, { 1475, 1475 }, { 1475, 525 } } }; + Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, clip); + THEN("intersection_pl - result is not empty") { + REQUIRE(result.size() == 1); + REQUIRE(result.front().points.size() == 5); + } + } + GIVEN("Clipper bug #126") { + Slic3r::Polyline subject { { 200000, 19799999 }, { 200000, 200000 }, { 24304692, 200000 }, { 15102879, 17506106 }, { 13883200, 19799999 }, { 200000, 19799999 } }; + Slic3r::Polygon clip { { 15257205, 18493894 }, { 14350057, 20200000 }, { -200000, 20200000 }, { -200000, -200000 }, { 25196917, -200000 } }; + Slic3r::Polylines result = Slic3r::intersection_pl({ subject }, { clip }); + THEN("intersection_pl - result is not empty") { + REQUIRE(result.size() == 1); + } + THEN("intersection_pl - result has same length as subject polyline") { + REQUIRE(result.front().length() == Approx(subject.length())); + } + } + +#if 0 + { + # Clipper does not preserve polyline orientation + my $polyline = Slic3r::Polyline->new([50, 150], [300, 150]); + my $result = Slic3r::Geometry::Clipper::intersection_pl([$polyline], [$square]); + is scalar(@$result), 1, 'intersection_pl - correct number of result lines'; + is_deeply $result->[0]->pp, [[100, 150], [200, 150]], 'clipped line orientation is preserved'; + } + { + # Clipper does not preserve polyline orientation + my $polyline = Slic3r::Polyline->new([300, 150], [50, 150]); + my $result = Slic3r::Geometry::Clipper::intersection_pl([$polyline], [$square]); + is scalar(@$result), 1, 'intersection_pl - correct number of result lines'; + is_deeply $result->[0]->pp, [[200, 150], [100, 150]], 'clipped line orientation is preserved'; + } + { + # Disabled until Clipper bug #127 is fixed + my $subject = [ + Slic3r::Polyline->new([-90000000, -100000000], [-90000000, 100000000]), # vertical + Slic3r::Polyline->new([-100000000, -10000000], [100000000, -10000000]), # horizontal + Slic3r::Polyline->new([-100000000, 0], [100000000, 0]), # horizontal + Slic3r::Polyline->new([-100000000, 10000000], [100000000, 10000000]), # horizontal + ]; + my $clip = Slic3r::Polygon->new(# a circular, convex, polygon + [99452190, 10452846], [97814760, 20791169], [95105652, 30901699], [91354546, 40673664], [86602540, 50000000], + [80901699, 58778525], [74314483, 66913061], [66913061, 74314483], [58778525, 80901699], [50000000, 86602540], + [40673664, 91354546], [30901699, 95105652], [20791169, 97814760], [10452846, 99452190], [0, 100000000], + [-10452846, 99452190], [-20791169, 97814760], [-30901699, 95105652], [-40673664, 91354546], + [-50000000, 86602540], [-58778525, 80901699], [-66913061, 74314483], [-74314483, 66913061], + [-80901699, 58778525], [-86602540, 50000000], [-91354546, 40673664], [-95105652, 30901699], + [-97814760, 20791169], [-99452190, 10452846], [-100000000, 0], [-99452190, -10452846], + [-97814760, -20791169], [-95105652, -30901699], [-91354546, -40673664], [-86602540, -50000000], + [-80901699, -58778525], [-74314483, -66913061], [-66913061, -74314483], [-58778525, -80901699], + [-50000000, -86602540], [-40673664, -91354546], [-30901699, -95105652], [-20791169, -97814760], + [-10452846, -99452190], [0, -100000000], [10452846, -99452190], [20791169, -97814760], + [30901699, -95105652], [40673664, -91354546], [50000000, -86602540], [58778525, -80901699], + [66913061, -74314483], [74314483, -66913061], [80901699, -58778525], [86602540, -50000000], + [91354546, -40673664], [95105652, -30901699], [97814760, -20791169], [99452190, -10452846], [100000000, 0] + ); + my $result = Slic3r::Geometry::Clipper::intersection_pl($subject, [$clip]); + is scalar(@$result), scalar(@$subject), 'intersection_pl - expected number of polylines'; + is sum(map scalar(@$_), @$result), scalar(@$subject) * 2, 'intersection_pl - expected number of points in polylines'; + } +#endif +} + +SCENARIO("Various Clipper operations - t/clipper.t", "[ClipperUtils]") { + GIVEN("square with hole") { + // CCW oriented contour + Slic3r::Polygon square { { 10, 10 }, { 20, 10 }, { 20, 20 }, { 10, 20 } }; + Slic3r::Polygon square2 { { 5, 12 }, { 25, 12 }, { 25, 18 }, { 5, 18 } }; + // CW oriented contour + Slic3r::Polygon hole_in_square { { 14, 14 }, { 14, 16 }, { 16, 16 }, { 16, 14 } }; + WHEN("intersection_ex with another square") { + ExPolygons intersection = Slic3r::intersection_ex({ square, hole_in_square }, { square2 }); + THEN("intersection area matches (hole is preserved)") { + ExPolygon match({ { 20, 18 }, { 10, 18 }, { 10, 12 }, { 20, 12 } }, + { { 14, 16 }, { 16, 16 }, { 16, 14 }, { 14, 14 } }); + REQUIRE(intersection.size() == 1); + REQUIRE(intersection.front().area() == Approx(match.area())); + } + } + } + GIVEN("square with hole 2") { + // CCW oriented contour + Slic3r::Polygon square { { 0, 0 }, { 40, 0 }, { 40, 40 }, { 0, 40 } }; + Slic3r::Polygon square2 { { 10, 10 }, { 30, 10 }, { 30, 30 }, { 10, 30 } }; + // CW oriented contour + Slic3r::Polygon hole { { 15, 15 }, { 15, 25 }, { 25, 25 }, {25, 15 } }; + WHEN("union_ex with another square") { + ExPolygons union_ = Slic3r::union_ex({ square, square2, hole }); + THEN("union of two ccw and one cw is a contour with no holes") { + REQUIRE(union_.size() == 1); + REQUIRE(union_.front() == ExPolygon { { 40, 40 }, { 0, 40 }, { 0, 0 }, { 40, 0 } } ); + } + } + WHEN("diff_ex with another square") { + ExPolygons diff = Slic3r::diff_ex({ square, square2 }, { hole }); + THEN("difference of a cw from two ccw is a contour with one hole") { + REQUIRE(diff.size() == 1); + REQUIRE(diff.front().area() == Approx(ExPolygon({ {40, 40}, {0, 40}, {0, 0}, {40, 0} }, { {15, 25}, {25, 25}, {25, 15}, {15, 15} }).area())); + } + } + } + GIVEN("yet another square") { + Slic3r::Polygon square { { 10, 10 }, { 20, 10 }, { 20, 20 }, { 10, 20 } }; + Slic3r::Polyline square_pl = square.split_at_first_point(); + WHEN("no-op diff_pl") { + Slic3r::Polylines res = Slic3r::diff_pl({ square_pl }, {}); + THEN("returns the right number of polylines") { + REQUIRE(res.size() == 1); + } + THEN("returns the unmodified input polyline") { + REQUIRE(res.front().points.size() == square_pl.points.size()); + } + } + } +} diff --git a/xs/t/11_clipper.t b/xs/t/11_clipper.t deleted file mode 100644 index 321d3048cc..0000000000 --- a/xs/t/11_clipper.t +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use List::Util qw(sum); -use Slic3r::XS; -use Test::More tests => 16; - -my $square = Slic3r::Polygon->new( # ccw - [200, 100], - [200, 200], - [100, 200], - [100, 100], -); -my $hole_in_square = Slic3r::Polygon->new( # cw - [160, 140], - [140, 140], - [140, 160], - [160, 160], -); -my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square); - -{ - my $result = Slic3r::Geometry::Clipper::offset([ $square, $hole_in_square ], 5); - is_deeply [ map $_->pp, @$result ], [ [ - [205, 205], - [95, 205], - [95, 95], - [205, 95], - ], [ - [145, 145], - [145, 155], - [155, 155], - [155, 145], - ] ], 'offset'; -} - -{ - my $result = Slic3r::Geometry::Clipper::offset_ex([ @$expolygon ], 5); - is_deeply $result->[0]->pp, [ [ - [205, 205], - [95, 205], - [95, 95], - [205, 95], - ], [ - [145, 145], - [145, 155], - [155, 155], - [155, 145], - ] ], 'offset_ex'; -} - -{ - my $result = Slic3r::Geometry::Clipper::offset2_ex([ @$expolygon ], 5, -2); - is_deeply $result->[0]->pp, [ [ - [203, 203], - [97, 203], - [97, 97], - [203, 97], - ], [ - [143, 143], - [143, 157], - [157, 157], - [157, 143], - ] ], 'offset2_ex'; -} - -{ - my $expolygon2 = Slic3r::ExPolygon->new([ - [20000000, 20000000], - [0, 20000000], - [0, 0], - [20000000, 0], - ], [ - [5000000, 15000000], - [15000000, 15000000], - [15000000, 5000000], - [5000000, 5000000], - ]); - my $result = Slic3r::Geometry::Clipper::offset2_ex([ @$expolygon2 ], -1, +1); - is $result->[0]->area, $expolygon2->area, 'offset2_ex'; -} - -{ - my $polygon1 = Slic3r::Polygon->new(@$square); - my $polygon2 = Slic3r::Polygon->new(reverse @$hole_in_square); - my $result = Slic3r::Geometry::Clipper::diff_ex([$polygon1], [$polygon2]); - is $result->[0]->area, $expolygon->area, 'diff_ex'; -} - -{ - my $polyline = Slic3r::Polyline->new([50,150], [300,150]); - { - my $result = Slic3r::Geometry::Clipper::intersection_pl([$polyline], [$square, $hole_in_square]); - is scalar(@$result), 2, 'intersection_pl - correct number of result lines'; - # results are in no particular order - is scalar(grep $_->length == 40, @$result), 2, 'intersection_pl - result lines have correct length'; - } - { - my $result = Slic3r::Geometry::Clipper::diff_pl([$polyline], [$square, $hole_in_square]); - is scalar(@$result), 3, 'diff_pl - correct number of result lines'; - # results are in no particular order - is scalar(grep $_->length == 50, @$result), 1, 'diff_pl - the left result line has correct length'; - is scalar(grep $_->length == 100, @$result), 1, 'diff_pl - two right result line has correct length'; - is scalar(grep $_->length == 20, @$result), 1, 'diff_pl - the central result line has correct length'; - } -} - -if (0) { # Clipper does not preserve polyline orientation - my $polyline = Slic3r::Polyline->new([50,150], [300,150]); - my $result = Slic3r::Geometry::Clipper::intersection_pl([$polyline], [$square]); - is scalar(@$result), 1, 'intersection_pl - correct number of result lines'; - is_deeply $result->[0]->pp, [[100,150], [200,150]], 'clipped line orientation is preserved'; -} - -if (0) { # Clipper does not preserve polyline orientation - my $polyline = Slic3r::Polyline->new([300,150], [50,150]); - my $result = Slic3r::Geometry::Clipper::intersection_pl([$polyline], [$square]); - is scalar(@$result), 1, 'intersection_pl - correct number of result lines'; - is_deeply $result->[0]->pp, [[200,150], [100,150]], 'clipped line orientation is preserved'; -} - -{ - # Clipper bug #96 (our issue #2028) - my $subject = Slic3r::Polyline->new( - [44735000,31936670],[55270000,31936670],[55270000,25270000],[74730000,25270000],[74730000,44730000],[68063296,44730000],[68063296,55270000],[74730000,55270000],[74730000,74730000],[55270000,74730000],[55270000,68063296],[44730000,68063296],[44730000,74730000],[25270000,74730000],[25270000,55270000],[31936670,55270000],[31936670,44730000],[25270000,44730000],[25270000,25270000],[44730000,25270000],[44730000,31936670] - ); - my $clip = [ - Slic3r::Polygon->new([75200000,45200000],[54800000,45200000],[54800000,24800000],[75200000,24800000]), - ]; - my $result = Slic3r::Geometry::Clipper::intersection_pl([$subject], $clip); - is scalar(@$result), 1, 'intersection_pl - result is not empty'; -} - -{ - # Clipper bug #122 - my $subject = [ - Slic3r::Polyline->new([1975,1975],[25,1975],[25,25],[1975,25],[1975,1975]), - ]; - my $clip = [ - Slic3r::Polygon->new([2025,2025],[-25,2025],[-25,-25],[2025,-25]), - Slic3r::Polygon->new([525,525],[525,1475],[1475,1475],[1475,525]), - ]; - my $result = Slic3r::Geometry::Clipper::intersection_pl($subject, $clip); - is scalar(@$result), 1, 'intersection_pl - result is not empty'; - is scalar(@{$result->[0]}), 5, 'intersection_pl - result is not empty'; -} - -{ - # Clipper bug #126 - my $subject = Slic3r::Polyline->new( - [200000,19799999],[200000,200000],[24304692,200000],[15102879,17506106],[13883200,19799999],[200000,19799999], - ); - my $clip = [ - Slic3r::Polygon->new([15257205,18493894],[14350057,20200000],[-200000,20200000],[-200000,-200000],[25196917,-200000]), - ]; - my $result = Slic3r::Geometry::Clipper::intersection_pl([$subject], $clip); - is scalar(@$result), 1, 'intersection_pl - result is not empty'; - is $result->[0]->length, $subject->length, 'intersection_pl - result has same length as subject polyline'; -} - -if (0) { - # Disabled until Clipper bug #127 is fixed - my $subject = [ - Slic3r::Polyline->new([-90000000,-100000000],[-90000000,100000000]), # vertical - Slic3r::Polyline->new([-100000000,-10000000],[100000000,-10000000]), # horizontal - Slic3r::Polyline->new([-100000000,0],[100000000,0]), # horizontal - Slic3r::Polyline->new([-100000000,10000000],[100000000,10000000]), # horizontal - ]; - my $clip = Slic3r::Polygon->new( # a circular, convex, polygon - [99452190,10452846],[97814760,20791169],[95105652,30901699],[91354546,40673664],[86602540,50000000], - [80901699,58778525],[74314483,66913061],[66913061,74314483],[58778525,80901699],[50000000,86602540], - [40673664,91354546],[30901699,95105652],[20791169,97814760],[10452846,99452190],[0,100000000], - [-10452846,99452190],[-20791169,97814760],[-30901699,95105652],[-40673664,91354546], - [-50000000,86602540],[-58778525,80901699],[-66913061,74314483],[-74314483,66913061], - [-80901699,58778525],[-86602540,50000000],[-91354546,40673664],[-95105652,30901699], - [-97814760,20791169],[-99452190,10452846],[-100000000,0],[-99452190,-10452846], - [-97814760,-20791169],[-95105652,-30901699],[-91354546,-40673664],[-86602540,-50000000], - [-80901699,-58778525],[-74314483,-66913061],[-66913061,-74314483],[-58778525,-80901699], - [-50000000,-86602540],[-40673664,-91354546],[-30901699,-95105652],[-20791169,-97814760], - [-10452846,-99452190],[0,-100000000],[10452846,-99452190],[20791169,-97814760], - [30901699,-95105652],[40673664,-91354546],[50000000,-86602540],[58778525,-80901699], - [66913061,-74314483],[74314483,-66913061],[80901699,-58778525],[86602540,-50000000], - [91354546,-40673664],[95105652,-30901699],[97814760,-20791169],[99452190,-10452846],[100000000,0] - ); - my $result = Slic3r::Geometry::Clipper::intersection_pl($subject, [$clip]); - is scalar(@$result), scalar(@$subject), 'intersection_pl - expected number of polylines'; - is sum(map scalar(@$_), @$result), scalar(@$subject)*2, - 'intersection_pl - expected number of points in polylines'; -} - -__END__ From 2e7e95adaec3ce8b24e8d47f4432c392be7acb23 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 25 Oct 2019 18:23:42 +0200 Subject: [PATCH 39/82] Disabled broken tests, ported some more tests to C++, removed Perl tests that were already ported to C++. --- tests/fff_print/CMakeLists.txt | 1 + tests/fff_print/test_gcode.cpp | 22 +++++++++++++++ tests/fff_print/test_skirt_brim.cpp | 8 ++++++ tests/libslic3r/test_geometry.cpp | 43 +++++++++++++++++++++-------- xs/t/14_geometry.t | 40 --------------------------- xs/t/16_flow.t | 29 ------------------- xs/t/19_model.t | 22 --------------- xs/t/21_gcode.t | 17 ------------ xs/t/22_exception.t | 14 ---------- 9 files changed, 62 insertions(+), 134 deletions(-) create mode 100644 tests/fff_print/test_gcode.cpp delete mode 100644 xs/t/14_geometry.t delete mode 100644 xs/t/16_flow.t delete mode 100644 xs/t/19_model.t delete mode 100644 xs/t/21_gcode.t delete mode 100644 xs/t/22_exception.t diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 32ae9757a9..75a9c31372 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(${_TEST_NAME}_tests test_extrusion_entity.cpp test_fill.cpp test_flow.cpp + test_gcode.cpp test_gcodewriter.cpp test_model.cpp test_print.cpp diff --git a/tests/fff_print/test_gcode.cpp b/tests/fff_print/test_gcode.cpp new file mode 100644 index 0000000000..34b40d1ff4 --- /dev/null +++ b/tests/fff_print/test_gcode.cpp @@ -0,0 +1,22 @@ +#include + +#include + +#include "libslic3r/GCode.hpp" + +using namespace Slic3r; + +SCENARIO("Origin manipulation", "[GCode]") { + Slic3r::GCode gcodegen; + WHEN("set_origin to (10,0)") { + gcodegen.set_origin(Vec2d(10,0)); + REQUIRE(gcodegen.origin() == Vec2d(10, 0)); + } + WHEN("set_origin to (10,0) and translate by (5, 5)") { + gcodegen.set_origin(Vec2d(10,0)); + gcodegen.set_origin(gcodegen.origin() + Vec2d(5, 5)); + THEN("origin returns reference to point") { + REQUIRE(gcodegen.origin() == Vec2d(15,5)); + } + } +} diff --git a/tests/fff_print/test_skirt_brim.cpp b/tests/fff_print/test_skirt_brim.cpp index 11a83fe295..097f72dcc6 100644 --- a/tests/fff_print/test_skirt_brim.cpp +++ b/tests/fff_print/test_skirt_brim.cpp @@ -119,6 +119,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[SkirtBrim]") { } } +#if 0 + // This is a real error! One shall print the brim with the external perimeter extruder! WHEN("Perimeter extruder = 2 and support extruders = 3") { THEN("Brim is printed with the extruder used for the perimeters of first object") { config.set_deserialize({ @@ -148,6 +150,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[SkirtBrim]") { REQUIRE(tool == config.opt_int("support_material_extruder") - 1); } } +#endif + WHEN("brim width to 1 with layer_width of 0.5") { config.set_deserialize({ { "skirts", 0 }, @@ -215,6 +219,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[SkirtBrim]") { // config.set("support_material", true); // to prevent speeds to be altered +#if 0 + // This test is not finished. THEN("skirt length is large enough to contain object with support") { CHECK(config.opt_bool("support_material")); // test is not valid if support material is off std::string gcode = Slic3r::Test::slice({TestMesh::cube_20x20x20}, config); @@ -248,6 +254,8 @@ SCENARIO("Original Slic3r Skirt/Brim tests", "[SkirtBrim]") { double hull_perimeter = unscale(convex_hull.split_at_first_point().length()); REQUIRE(skirt_length > hull_perimeter); } +#endif + } WHEN("Large minimum skirt length is used.") { config.set("min_skirt_length", 20); diff --git a/tests/libslic3r/test_geometry.cpp b/tests/libslic3r/test_geometry.cpp index fce6a476c9..22755c2622 100644 --- a/tests/libslic3r/test_geometry.cpp +++ b/tests/libslic3r/test_geometry.cpp @@ -11,7 +11,7 @@ using namespace Slic3r; -TEST_CASE("Polygon::contains works properly", ""){ +TEST_CASE("Polygon::contains works properly", "[Geometry]"){ // this test was failing on Windows (GH #1950) Slic3r::Polygon polygon(std::vector({ Point(207802834,-57084522), @@ -29,7 +29,7 @@ TEST_CASE("Polygon::contains works properly", ""){ REQUIRE(polygon.contains(point)); } -SCENARIO("Intersections of line segments"){ +SCENARIO("Intersections of line segments", "[Geometry]"){ GIVEN("Integer coordinates"){ Line line1(Point(5,15),Point(30,15)); Line line2(Point(10,20), Point(10,10)); @@ -127,7 +127,7 @@ SCENARIO("polygon_is_convex works"){ }*/ -TEST_CASE("Creating a polyline generates the obvious lines"){ +TEST_CASE("Creating a polyline generates the obvious lines", "[Geometry]"){ Slic3r::Polyline polyline; polyline.points = std::vector({Point(0, 0), Point(10, 0), Point(20, 0)}); REQUIRE(polyline.lines().at(0).a == Point(0,0)); @@ -136,7 +136,7 @@ TEST_CASE("Creating a polyline generates the obvious lines"){ REQUIRE(polyline.lines().at(1).b == Point(20,0)); } -TEST_CASE("Splitting a Polygon generates a polyline correctly"){ +TEST_CASE("Splitting a Polygon generates a polyline correctly", "[Geometry]"){ Slic3r::Polygon polygon(std::vector({Point(0, 0), Point(10, 0), Point(5, 5)})); Slic3r::Polyline split = polygon.split_at_index(1); REQUIRE(split.points[0]==Point(10,0)); @@ -146,7 +146,7 @@ TEST_CASE("Splitting a Polygon generates a polyline correctly"){ } -TEST_CASE("Bounding boxes are scaled appropriately"){ +TEST_CASE("Bounding boxes are scaled appropriately", "[Geometry]"){ BoundingBox bb(std::vector({Point(0, 1), Point(10, 2), Point(20, 2)})); bb.scale(2); REQUIRE(bb.min == Point(0,2)); @@ -154,13 +154,13 @@ TEST_CASE("Bounding boxes are scaled appropriately"){ } -TEST_CASE("Offseting a line generates a polygon correctly"){ +TEST_CASE("Offseting a line generates a polygon correctly", "[Geometry]"){ Slic3r::Polyline tmp = { Point(10,10), Point(20,10) }; Slic3r::Polygon area = offset(tmp,5).at(0); REQUIRE(area.area() == Slic3r::Polygon(std::vector({Point(10,5),Point(20,5),Point(20,15),Point(10,15)})).area()); } -SCENARIO("Circle Fit, TaubinFit with Newton's method") { +SCENARIO("Circle Fit, TaubinFit with Newton's method", "[Geometry]") { GIVEN("A vector of Vec2ds arranged in a half-circle with approximately the same distance R from some point") { Vec2d expected_center(-6, 0); Vec2ds sample {Vec2d(6.0, 0), Vec2d(5.1961524, 3), Vec2d(3 ,5.1961524), Vec2d(0, 6.0), Vec2d(3, 5.1961524), Vec2d(-5.1961524, 3), Vec2d(-6.0, 0)}; @@ -252,7 +252,7 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") { } } -TEST_CASE("Chained path working correctly"){ +TEST_CASE("Chained path working correctly", "[Geometry]"){ // if chained_path() works correctly, these points should be joined with no diagonal paths // (thus 26 units long) std::vector points = {Point(26,26),Point(52,26),Point(0,26),Point(26,52),Point(26,0),Point(0,52),Point(52,52),Point(52,0)}; @@ -263,7 +263,7 @@ TEST_CASE("Chained path working correctly"){ } } -SCENARIO("Line distances"){ +SCENARIO("Line distances", "[Geometry]"){ GIVEN("A line"){ Line line(Point(0, 0), Point(20, 0)); THEN("Points on the line segment have 0 distance"){ @@ -279,7 +279,7 @@ SCENARIO("Line distances"){ } } -SCENARIO("Polygon convex/concave detection"){ +SCENARIO("Polygon convex/concave detection", "[Geometry]"){ GIVEN(("A Square with dimension 100")){ auto square = Slic3r::Polygon /*new_scale*/(std::vector({ Point(100,100), @@ -365,11 +365,30 @@ SCENARIO("Polygon convex/concave detection"){ } } -TEST_CASE("Triangle Simplification does not result in less than 3 points"){ +TEST_CASE("Triangle Simplification does not result in less than 3 points", "[Geometry]"){ auto triangle = Slic3r::Polygon(std::vector({ Point(16000170,26257364), Point(714223,461012), Point(31286371,461008) })); REQUIRE(triangle.simplify(250000).at(0).points.size() == 3); } - +SCENARIO("Ported from xs/t/14_geometry.t", "[Geometry]"){ + GIVEN(("square")){ + Slic3r::Points points { { 100, 100 }, {100, 200 }, { 200, 200 }, { 200, 100 }, { 150, 150 } }; + Slic3r::Polygon hull = Slic3r::Geometry::convex_hull(points); + SECTION("convex hull returns the correct number of points") { REQUIRE(hull.points.size() == 4); } + } + SECTION("arrange returns expected number of positions") { + Pointfs positions; + Slic3r::Geometry::arrange(4, Vec2d(20, 20), 5, nullptr, positions); + REQUIRE(positions.size() == 4); + } + SECTION("directions_parallel") { + REQUIRE(Slic3r::Geometry::directions_parallel(0, 0, 0)); + REQUIRE(Slic3r::Geometry::directions_parallel(0, M_PI, 0)); + REQUIRE(Slic3r::Geometry::directions_parallel(0, 0, M_PI / 180)); + REQUIRE(Slic3r::Geometry::directions_parallel(0, M_PI, M_PI / 180)); + REQUIRE(! Slic3r::Geometry::directions_parallel(M_PI /2, M_PI, 0)); + REQUIRE(! Slic3r::Geometry::directions_parallel(M_PI /2, PI, M_PI /180)); + } +} diff --git a/xs/t/14_geometry.t b/xs/t/14_geometry.t deleted file mode 100644 index 1debe8e2c1..0000000000 --- a/xs/t/14_geometry.t +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 9; - -use constant PI => 4 * atan2(1, 1); - -{ - my @points = ( - Slic3r::Point->new(100,100), - Slic3r::Point->new(100,200), - Slic3r::Point->new(200,200), - Slic3r::Point->new(200,100), - Slic3r::Point->new(150,150), - ); - my $hull = Slic3r::Geometry::convex_hull(\@points); - isa_ok $hull, 'Slic3r::Polygon', 'convex_hull returns a Polygon'; - is scalar(@$hull), 4, 'convex_hull returns the correct number of points'; -} - -# directions_parallel() and directions_parallel_within() are tested -# also with Slic3r::Line::parallel_to() tests in 10_line.t -{ - ok Slic3r::Geometry::directions_parallel_within(0, 0, 0), 'directions_parallel_within'; - ok Slic3r::Geometry::directions_parallel_within(0, PI, 0), 'directions_parallel_within'; - ok Slic3r::Geometry::directions_parallel_within(0, 0, PI/180), 'directions_parallel_within'; - ok Slic3r::Geometry::directions_parallel_within(0, PI, PI/180), 'directions_parallel_within'; - ok !Slic3r::Geometry::directions_parallel_within(PI/2, PI, 0), 'directions_parallel_within'; - ok !Slic3r::Geometry::directions_parallel_within(PI/2, PI, PI/180), 'directions_parallel_within'; -} - -{ - my $positions = Slic3r::Geometry::arrange(4, Slic3r::Pointf->new(20, 20), 5); - is scalar(@$positions), 4, 'arrange() returns expected number of positions'; -} - -__END__ diff --git a/xs/t/16_flow.t b/xs/t/16_flow.t deleted file mode 100644 index 5040d28c30..0000000000 --- a/xs/t/16_flow.t +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 2; - -{ - my $flow = Slic3r::Flow->new_from_width( - role => Slic3r::Flow::FLOW_ROLE_PERIMETER, - width => '1', - nozzle_diameter => 0.5, - layer_height => 0.3, - bridge_flow_ratio => 1, - ); - isa_ok $flow, 'Slic3r::Flow', 'new_from_width'; -} - -{ - my $flow = Slic3r::Flow->new( - width => 1, - height => 0.4, - nozzle_diameter => 0.5, - ); - isa_ok $flow, 'Slic3r::Flow', 'new'; -} - -__END__ diff --git a/xs/t/19_model.t b/xs/t/19_model.t deleted file mode 100644 index 48a000e463..0000000000 --- a/xs/t/19_model.t +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 3; - -{ - my $model = Slic3r::Model->new; - my $object = $model->_add_object; - isa_ok $object, 'Slic3r::Model::Object::Ref'; - isa_ok $object->origin_translation, 'Slic3r::Pointf3::Ref'; - $object->origin_translation->translate(10,0,0); - is_deeply \@{$object->origin_translation}, [10,0,0], 'origin_translation is modified by ref'; - -# my $lhr = [ [ 5, 10, 0.1 ] ]; -# $object->set_layer_height_ranges($lhr); -# is_deeply $object->layer_height_ranges, $lhr, 'layer_height_ranges roundtrip'; -} - -__END__ diff --git a/xs/t/21_gcode.t b/xs/t/21_gcode.t deleted file mode 100644 index 307de6421b..0000000000 --- a/xs/t/21_gcode.t +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 2; - -{ - my $gcodegen = Slic3r::GCode->new; - $gcodegen->set_origin(Slic3r::Pointf->new(10,0)); - is_deeply $gcodegen->origin->pp, [10,0], 'set_origin'; - $gcodegen->origin->translate(5,5); - is_deeply $gcodegen->origin->pp, [15,5], 'origin returns reference to point'; -} - -__END__ diff --git a/xs/t/22_exception.t b/xs/t/22_exception.t deleted file mode 100644 index fead8ddee7..0000000000 --- a/xs/t/22_exception.t +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 1; - -eval { - Slic3r::xspp_test_croak_hangs_on_strawberry(); -}; -is $@, "xspp_test_croak_hangs_on_strawberry: exception catched\n", 'croak from inside a C++ exception delivered'; - -__END__ From 9e8ce66f70ce29a4badd54a6e3d8688ed36f903f Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 25 Oct 2019 19:06:40 +0200 Subject: [PATCH 40/82] Fix / improvement of unit tests. --- src/libslic3r/GCode/SpiralVase.hpp | 4 ++-- tests/libslic3r/test_clipper_offset.cpp | 2 +- tests/libslic3r/test_polygon.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/GCode/SpiralVase.hpp b/src/libslic3r/GCode/SpiralVase.hpp index 7872b1d3c5..e35ca640c3 100644 --- a/src/libslic3r/GCode/SpiralVase.hpp +++ b/src/libslic3r/GCode/SpiralVase.hpp @@ -1,8 +1,8 @@ #ifndef slic3r_SpiralVase_hpp_ #define slic3r_SpiralVase_hpp_ -#include "libslic3r.h" -#include "GCodeReader.hpp" +#include "../libslic3r.h" +#include "../GCodeReader.hpp" namespace Slic3r { diff --git a/tests/libslic3r/test_clipper_offset.cpp b/tests/libslic3r/test_clipper_offset.cpp index fed89c66ce..f40856a633 100644 --- a/tests/libslic3r/test_clipper_offset.cpp +++ b/tests/libslic3r/test_clipper_offset.cpp @@ -9,7 +9,7 @@ using namespace Slic3r; -#define TESTS_EXPORT_SVGS +// #define TESTS_EXPORT_SVGS SCENARIO("Constant offset", "[ClipperUtils]") { coord_t s = 1000000; diff --git a/tests/libslic3r/test_polygon.cpp b/tests/libslic3r/test_polygon.cpp index 8e99758435..d45e37fb18 100644 --- a/tests/libslic3r/test_polygon.cpp +++ b/tests/libslic3r/test_polygon.cpp @@ -25,7 +25,7 @@ Slic3r::Points collinear_circle({ Slic3r::Point::new_scale(-5, 0) }); -SCENARIO("Remove collinear points from Polygon") { +SCENARIO("Remove collinear points from Polygon", "[Polygon]") { GIVEN("Polygon with collinear points"){ Slic3r::Polygon p(collinear_circle); WHEN("collinear points are removed") { From f36dd833d2fecebe86d351fe0f2933e1c920673c Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 07:32:15 +0100 Subject: [PATCH 41/82] ENABLE_THUMBNAIL_GENERATOR -> Reduce thumbnail size if exceeding 3D scene canvas size --- src/slic3r/GUI/GLCanvas3D.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 703321c3ca..139ee5fa43 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1658,6 +1658,16 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, static const float orange[] = { 0.99f, 0.49f, 0.26f }; static const float gray[] = { 0.64f, 0.64f, 0.64f }; + const Size& cnv_size = get_canvas_size(); + unsigned int cnv_w = (unsigned int)cnv_size.get_width(); + unsigned int cnv_h = (unsigned int)cnv_size.get_height(); + if ((w > cnv_w) || (h > cnv_h)) + { + float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); + w = (unsigned int)(ratio * (float)w); + h = (unsigned int)(ratio * (float)h); + } + thumbnail_data.set(w, h); GLVolumePtrs visible_volumes; @@ -1720,7 +1730,6 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, #endif // restore the framebuffer size to avoid flickering on the 3D scene - const Size& cnv_size = get_canvas_size(); m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } #endif // ENABLE_THUMBNAIL_GENERATOR From 3ff3eed2b1e0751e823559542975e63d51f62010 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 10:27:51 +0100 Subject: [PATCH 42/82] ENABLE_THUMBNAIL_GENERATOR -> Use off-screen framebuffer to render the thumbnail on graphic cards supporting it --- src/slic3r/GUI/GLCanvas3D.cpp | 219 +++++++++++++++++---------- src/slic3r/GUI/GLCanvas3D.hpp | 6 + src/slic3r/GUI/GLCanvas3DManager.cpp | 6 + src/slic3r/GUI/GLCanvas3DManager.hpp | 2 + 4 files changed, 151 insertions(+), 82 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 139ee5fa43..b40a836822 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1649,88 +1649,10 @@ void GLCanvas3D::render() #if ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) { - auto is_visible = [](const GLVolume& v) -> bool { - bool ret = v.printable; - ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); - return ret; - }; - - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; - - const Size& cnv_size = get_canvas_size(); - unsigned int cnv_w = (unsigned int)cnv_size.get_width(); - unsigned int cnv_h = (unsigned int)cnv_size.get_height(); - if ((w > cnv_w) || (h > cnv_h)) - { - float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); - w = (unsigned int)(ratio * (float)w); - h = (unsigned int)(ratio * (float)h); - } - - thumbnail_data.set(w, h); - - GLVolumePtrs visible_volumes; - - for (GLVolume* vol : m_volumes.volumes) - { - if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) - { - if (!printable_only || is_visible(*vol)) - visible_volumes.push_back(vol); - } - } - - if (visible_volumes.empty()) - return; - - BoundingBoxf3 box; - for (const GLVolume* vol : visible_volumes) - { - box.merge(vol->transformed_bounding_box()); - } - - Camera camera; - camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); - camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); - camera.apply_view_matrix(); - camera.apply_projection(box); - - glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); - glsafe(::glEnable(GL_DEPTH_TEST)); - - for (const GLVolume* vol : visible_volumes) - { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); - vol->render(); - } - - glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - -#if 0 - // debug export of generated image - wxImage image(thumbnail_data.width, thumbnail_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < thumbnail_data.height; ++r) - { - unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; - for (unsigned int c = 0; c < thumbnail_data.width; ++c) - { - unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - image.SaveFile("C:/test.png", wxBITMAP_TYPE_PNG); -#endif - - // restore the framebuffer size to avoid flickering on the 3D scene - m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); + if (GLCanvas3DManager::are_framebuffers_supported()) + _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only); + else + _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3644,6 +3566,139 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) imgui->end(); } +#if ENABLE_THUMBNAIL_GENERATOR +static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) +{ + auto is_visible = [](const GLVolume& v) -> bool + { + bool ret = v.printable; + ret &= (!v.shader_outside_printer_detection_enabled || !v.is_outside); + return ret; + }; + + static const float orange[] = { 0.99f, 0.49f, 0.26f }; + static const float gray[] = { 0.64f, 0.64f, 0.64f }; + + GLVolumePtrs visible_volumes; + + for (GLVolume* vol : volumes) + { + if (!vol->is_modifier && !vol->is_wipe_tower && (!parts_only || (vol->composite_id.volume_id >= 0))) + { + if (!printable_only || is_visible(*vol)) + visible_volumes.push_back(vol); + } + } + + if (visible_volumes.empty()) + return; + + BoundingBoxf3 box; + for (const GLVolume* vol : visible_volumes) + { + box.merge(vol->transformed_bounding_box()); + } + + Camera camera; + camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); + camera.apply_view_matrix(); + camera.apply_projection(box); + + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_LIGHTING)); + glsafe(::glEnable(GL_DEPTH_TEST)); + + for (const GLVolume* vol : visible_volumes) + { + glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); + } + + glsafe(::glDisable(GL_DEPTH_TEST)); + glsafe(::glDisable(GL_LIGHTING)); + glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if 0 + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); +#endif +} + +void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +{ + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + GLuint fbo; + glsafe(::glGenFramebuffers(1, &fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, fbo)); + + GLuint tex; + glsafe(::glGenTextures(1, &tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0)); + + GLuint depth; + glsafe(::glGenRenderbuffers(1, &depth)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, depth)); + glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth)); + + GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0)); + glsafe(::glDeleteRenderbuffers(1, &depth)); + glsafe(::glDeleteTextures(1, &tex)); + glsafe(::glDeleteFramebuffers(1, &fbo)); +} + +void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +{ + // check that thumbnail size does not exceed the default framebuffer size + const Size& cnv_size = get_canvas_size(); + unsigned int cnv_w = (unsigned int)cnv_size.get_width(); + unsigned int cnv_h = (unsigned int)cnv_size.get_height(); + if ((w > cnv_w) || (h > cnv_h)) + { + float ratio = std::min((float)cnv_w / (float)w, (float)cnv_h / (float)h); + w = (unsigned int)(ratio * (float)w); + h = (unsigned int)(ratio * (float)h); + } + + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + + // restore the default framebuffer size to avoid flickering on the 3D scene + m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + bool GLCanvas3D::_init_toolbars() { if (!_init_main_toolbar()) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 5b06b6311a..fce4661a4e 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -674,6 +674,12 @@ private: void _render_sla_slices() const; void _render_selection_sidebar_hints() const; void _render_undo_redo_stack(const bool is_undo, float pos_x); +#if ENABLE_THUMBNAIL_GENERATOR + // render thumbnail using an off-screen framebuffer + void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + // render thumbnail using the default framebuffer + void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); +#endif // ENABLE_THUMBNAIL_GENERATOR void _update_volumes_hover_state() const; diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 9690e8a8d6..03daa0b00e 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -189,6 +189,7 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown; bool GLCanvas3DManager::s_compressed_textures_supported = false; +bool GLCanvas3DManager::s_framebuffers_supported = false; GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; GLCanvas3DManager::GLCanvas3DManager() @@ -269,6 +270,11 @@ void GLCanvas3DManager::init_gl() else s_compressed_textures_supported = false; + if (s_gl_info.is_version_greater_or_equal_to(3, 0) && GLEW_ARB_framebuffer_object) + s_framebuffers_supported = true; + else + s_framebuffers_supported = false; + if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { // Complain about the OpenGL version. wxString message = wxString::Format( diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index 760266a274..a2e35f8111 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -77,6 +77,7 @@ private: bool m_gl_initialized; static EMultisampleState s_multisample; static bool s_compressed_textures_supported; + static bool s_framebuffers_supported; public: GLCanvas3DManager(); @@ -97,6 +98,7 @@ public: static bool can_multisample() { return s_multisample == MS_Enabled; } static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } + static bool are_framebuffers_supported() { return s_framebuffers_supported; } static wxGLCanvas* create_wxglcanvas(wxWindow *parent); From 8b5561aec7e6e2411396b3bf6b67cb333319687f Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 29 Oct 2019 10:40:34 +0100 Subject: [PATCH 43/82] Fixed several warnings --- src/libslic3r/LayerRegion.cpp | 1 - src/libslic3r/PolygonTrimmer.cpp | 1 - src/slic3r/Config/Version.cpp | 5 ++--- src/slic3r/GUI/BackgroundSlicingProcess.cpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 2 +- src/slic3r/GUI/GUI_App.hpp | 9 ++++----- src/slic3r/GUI/GUI_ObjectList.cpp | 4 ++-- src/slic3r/GUI/OptionsGroup.cpp | 2 +- src/slic3r/GUI/Plater.cpp | 4 ++-- src/slic3r/GUI/wxExtensions.cpp | 2 +- 10 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 658bcf7094..35acaf9983 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -88,7 +88,6 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec void LayerRegion::process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered) { - const Surfaces &surfaces = this->fill_surfaces.surfaces; const bool has_infill = this->region()->config().fill_density.value > 0.; const float margin = float(scale_(EXTERNAL_INFILL_MARGIN)); diff --git a/src/libslic3r/PolygonTrimmer.cpp b/src/libslic3r/PolygonTrimmer.cpp index 3e3c9b4982..a2779b6667 100644 --- a/src/libslic3r/PolygonTrimmer.cpp +++ b/src/libslic3r/PolygonTrimmer.cpp @@ -12,7 +12,6 @@ TrimmedLoop trim_loop(const Polygon &loop, const EdgeGrid::Grid &grid) TrimmedLoop out; if (loop.size() >= 2) { - size_t cnt = loop.points.size(); struct Visitor { Visitor(const EdgeGrid::Grid &grid, const Slic3r::Point *pt_prev, const Slic3r::Point *pt_this) : grid(grid), pt_prev(pt_prev), pt_this(pt_this) {} diff --git a/src/slic3r/Config/Version.cpp b/src/slic3r/Config/Version.cpp index 3f8f960f10..da522dd5e5 100644 --- a/src/slic3r/Config/Version.cpp +++ b/src/slic3r/Config/Version.cpp @@ -235,9 +235,9 @@ size_t Index::load(const boost::filesystem::path &path) value = left_trim(value + 1); *key_end = 0; boost::optional semver; - if (maybe_semver) + if (maybe_semver) semver = Semver::parse(key); - if (key_value_pair) { + if (key_value_pair) { if (semver) throw file_parser_error("Key cannot be a semantic version", path, idx_line);\ // Verify validity of the key / value pair. @@ -288,7 +288,6 @@ Index::const_iterator Index::find(const Semver &ver) const Index::const_iterator Index::recommended() const { - int idx = -1; const_iterator highest = this->end(); for (const_iterator it = this->begin(); it != this->end(); ++ it) if (it->is_current_slic3r_supported() && diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index a1db6884ee..6c138d4d02 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -55,6 +55,7 @@ bool BackgroundSlicingProcess::select_technology(PrinterTechnology tech) switch (tech) { case ptFFF: m_print = m_fff_print; break; case ptSLA: m_print = m_sla_print; break; + default: assert(false); break; } changed = true; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c55d64b472..268b4dc30b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1926,7 +1926,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re if (it->new_geometry()) { // New volume. unsigned int old_id = find_old_volume_id(it->composite_id); - if (old_id != -1) + if (old_id != (unsigned int)-1) map_glvolume_old_to_new[old_id] = m_volumes.volumes.size(); m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_initialized); m_volumes.volumes.back()->geometry_id = key.geometry_id; diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index c5ddc01528..9bfc345439 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -87,7 +87,7 @@ class GUI_App : public wxApp wxFont m_bold_font; wxFont m_normal_font; - size_t m_em_unit; // width of a "m"-symbol in pixels for current system font + int m_em_unit; // width of a "m"-symbol in pixels for current system font // Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls std::unique_ptr m_wxLocale; @@ -105,7 +105,7 @@ public: bool initialized() const { return m_initialized; } GUI_App(); - ~GUI_App(); + ~GUI_App() override; static unsigned get_colour_approx_luma(const wxColour &colour); static bool dark_mode(); @@ -124,8 +124,7 @@ public: const wxFont& small_font() { return m_small_font; } const wxFont& bold_font() { return m_bold_font; } const wxFont& normal_font() { return m_normal_font; } - size_t em_unit() const { return m_em_unit; } - void set_em_unit(const size_t em_unit) { m_em_unit = em_unit; } + int em_unit() const { return m_em_unit; } float toolbar_icon_scale(const bool is_limited = false) const; void recreate_GUI(); @@ -155,7 +154,7 @@ public: // Translate the language code to a code, for which Prusa Research maintains translations. Defaults to "en_US". wxString current_language_code_safe() const; - virtual bool OnExceptionInMainLoop(); + virtual bool OnExceptionInMainLoop() override; #ifdef __APPLE__ // wxWidgets override to get an event on open files. diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc48a218c0..a88980a8d4 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -445,7 +445,7 @@ void ObjectList::update_extruder_values_for_items(const size_t max_extruder) auto object = (*m_objects)[i]; wxString extruder; if (!object->config.has("extruder") || - object->config.option("extruder")->value > max_extruder) + size_t(object->config.option("extruder")->value) > max_extruder) extruder = _(L("default")); else extruder = wxString::Format("%d", object->config.option("extruder")->value); @@ -457,7 +457,7 @@ void ObjectList::update_extruder_values_for_items(const size_t max_extruder) item = m_objects_model->GetItemByVolumeId(i, id); if (!item) continue; if (!object->volumes[id]->config.has("extruder") || - object->volumes[id]->config.option("extruder")->value > max_extruder) + size_t(object->volumes[id]->config.option("extruder")->value) > max_extruder) extruder = _(L("default")); else extruder = wxString::Format("%d", object->volumes[id]->config.option("extruder")->value); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 698c1e0348..8b6f5bc304 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -233,7 +233,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n add_undo_buttuns_to_sizer(sizer, field); if (is_window_field(field)) - sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, //(option.opt.full_width ? wxEXPAND : 0) | + sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, //(option.opt.full_width ? wxEXPAND : 0) | wxBOTTOM | wxTOP | (option.opt.full_width ? wxEXPAND : wxALIGN_CENTER_VERTICAL), (wxOSX || !staticbox) ? 0 : 2); if (is_sizer_field(field)) sizer->Add(field->getSizer(), 1, /*(*/option.opt.full_width ? wxEXPAND : /*0) |*/ wxALIGN_CENTER_VERTICAL, 0); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index cca164ca30..90529f88c9 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4791,7 +4791,7 @@ bool Plater::undo_redo_string_getter(const bool is_undo, int idx, const char** o const std::vector& ss_stack = p->undo_redo_stack().snapshots(); const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -(++idx) : idx); - if (0 < idx_in_ss_stack && idx_in_ss_stack < ss_stack.size() - 1) { + if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) { *out_text = ss_stack[idx_in_ss_stack].name.c_str(); return true; } @@ -4804,7 +4804,7 @@ void Plater::undo_redo_topmost_string_getter(const bool is_undo, std::string& ou const std::vector& ss_stack = p->undo_redo_stack().snapshots(); const int idx_in_ss_stack = p->get_active_snapshot_index() + (is_undo ? -1 : 0); - if (0 < idx_in_ss_stack && idx_in_ss_stack < ss_stack.size() - 1) { + if (0 < idx_in_ss_stack && (size_t)idx_in_ss_stack < ss_stack.size() - 1) { out_text = ss_stack[idx_in_ss_stack].name; return; } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 06e37fb4f6..eb47fd2083 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1020,7 +1020,7 @@ wxDataViewItem ObjectDataViewModel::Delete(const wxDataViewItem &item) node_parent->GetChildren().Remove(node); if (id > 0) { - if(id == node_parent->GetChildCount()) id--; + if (size_t(id) == node_parent->GetChildCount()) id--; ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); } From ffcf25e5cb0fab7b527c9bbffe34fc65d9a6d38b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 Oct 2019 13:07:57 +0100 Subject: [PATCH 44/82] Fix for #3108 --- src/slic3r/GUI/Field.cpp | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 07d75c9472..42e3448fc1 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -150,7 +150,13 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true case coFloat:{ if (m_opt.type == coPercent && !str.IsEmpty() && str.Last() == '%') str.RemoveLast(); - else if (check_value && !str.IsEmpty() && str.Last() == '%') { + else if (!str.IsEmpty() && str.Last() == '%') + { + if (!check_value) { + m_value.clear(); + break; + } + wxString label = m_Label->GetLabel(); if (label.Last() == '\n') label.RemoveLast(); while (label.Last() == ' ') label.RemoveLast(); @@ -169,13 +175,21 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true { if (m_opt.nullable && str == na_value()) val = ConfigOptionFloatsNullable::nil_value(); - else if (check_value && !str.ToCDouble(&val)) + else if (!str.ToCDouble(&val)) { + if (!check_value) { + m_value.clear(); + break; + } show_error(m_parent, _(L("Invalid numeric input."))); set_value(double_to_string(val), true); } - if (check_value && (m_opt.min > val || val > m_opt.max)) + if (m_opt.min > val || val > m_opt.max) { + if (!check_value) { + m_value.clear(); + break; + } show_error(m_parent, _(L("Input value is out of range"))); if (m_opt.min > val) val = m_opt.min; if (val > m_opt.max) val = m_opt.max; @@ -192,15 +206,24 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true double val = 0.; // Replace the first occurence of comma in decimal number. str.Replace(",", ".", false); - if (check_value && !str.ToCDouble(&val)) + if (!str.ToCDouble(&val)) { + if (!check_value) { + m_value.clear(); + break; + } show_error(m_parent, _(L("Invalid numeric input."))); set_value(double_to_string(val), true); } - else if (check_value && ((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) || + else if (((m_opt.sidetext.rfind("mm/s") != std::string::npos && val > m_opt.max) || (m_opt.sidetext.rfind("mm ") != std::string::npos && val > 1)) && (m_value.empty() || std::string(str.ToUTF8().data()) != boost::any_cast(m_value))) { + if (!check_value) { + m_value.clear(); + break; + } + const std::string sidetext = m_opt.sidetext.rfind("mm/s") != std::string::npos ? "mm/s" : "mm"; const wxString stVal = double_to_string(val, 2); const wxString msg_text = wxString::Format(_(L("Do you mean %s%% instead of %s %s?\n" @@ -351,6 +374,7 @@ bool TextCtrl::value_was_changed() boost::any val = m_value; wxString ret_str = static_cast(window)->GetValue(); // update m_value! + // ret_str might be changed inside get_value_by_opt_type get_value_by_opt_type(ret_str); switch (m_opt.type) { @@ -396,8 +420,10 @@ void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) if (!change_event) { wxString ret_str = static_cast(window)->GetValue(); - // update m_value to correct work of next value_was_changed(), - // but don't check/change inputed value and don't show a warning message + /* Update m_value to correct work of next value_was_changed(). + * But after checking of entered value, don't fix the "incorrect" value and don't show a warning message, + * just clear m_value in this case. + */ get_value_by_opt_type(ret_str, false); } } From a7b4b232e95bbe2751631dcf2ef1bd192c4a18cf Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 29 Oct 2019 14:45:15 +0100 Subject: [PATCH 45/82] ENABLE_THUMBNAIL_GENERATOR -> Use multisampling when generating thumbnail using off-screen framebuffer --- src/slic3r/GUI/GLCanvas3D.cpp | 152 +++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 38 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b40a836822..ae2f4989f9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3567,6 +3567,29 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) } #if ENABLE_THUMBNAIL_GENERATOR +#define ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT 0 +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT +static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) +{ + // debug export of generated image + wxImage image(thumbnail_data.width, thumbnail_data.height); + image.InitAlpha(); + + for (unsigned int r = 0; r < thumbnail_data.height; ++r) + { + unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; + for (unsigned int c = 0; c < thumbnail_data.width; ++c) + { + unsigned char* px = (unsigned char*)thumbnail_data.pixels.data() + 4 * (rr + c); + image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); + image.SetAlpha((int)c, (int)r, px[3]); + } + } + + image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); +} +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool @@ -3617,26 +3640,6 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa glsafe(::glDisable(GL_DEPTH_TEST)); glsafe(::glDisable(GL_LIGHTING)); - glsafe(::glReadPixels(0, 0, thumbnail_data.width, thumbnail_data.height, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); - -#if 0 - // debug export of generated image - wxImage image(thumbnail_data.width, thumbnail_data.height); - image.InitAlpha(); - - for (unsigned int r = 0; r < thumbnail_data.height; ++r) - { - unsigned int rr = (thumbnail_data.height - 1 - r) * thumbnail_data.width; - for (unsigned int c = 0; c < thumbnail_data.width; ++c) - { - unsigned char* px = thumbnail_data.pixels.data() + 4 * (rr + c); - image.SetRGB((int)c, (int)r, px[0], px[1], px[2]); - image.SetAlpha((int)c, (int)r, px[3]); - } - } - - image.SaveFile("C:/prusa/test/test.png", wxBITMAP_TYPE_PNG); -#endif } void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3645,34 +3648,102 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (!thumbnail_data.is_valid()) return; - GLuint fbo; - glsafe(::glGenFramebuffers(1, &fbo)); - glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, fbo)); + bool multisample = m_multisample_allowed; + if (multisample) + glsafe(::glEnable(GL_MULTISAMPLE)); - GLuint tex; - glsafe(::glGenTextures(1, &tex)); - glsafe(::glBindTexture(GL_TEXTURE_2D, tex)); - glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0)); + GLint max_samples; + glsafe(::glGetIntegerv(GL_MAX_SAMPLES, &max_samples)); + GLsizei num_samples = max_samples / 2; - GLuint depth; - glsafe(::glGenRenderbuffers(1, &depth)); - glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, depth)); - glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); - glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth)); + GLuint render_fbo; + glsafe(::glGenFramebuffers(1, &render_fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, render_fbo)); + + GLuint render_tex = 0; + GLuint render_tex_buffer = 0; + if (multisample) + { + // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 + glsafe(::glGenRenderbuffers(1, &render_tex_buffer)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_tex_buffer)); + glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_RGBA8, w, h)); + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_tex_buffer)); + } + else + { + glsafe(::glGenTextures(1, &render_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, render_tex, 0)); + } + + GLuint render_depth; + glsafe(::glGenRenderbuffers(1, &render_depth)); + glsafe(::glBindRenderbuffer(GL_RENDERBUFFER, render_depth)); + if (multisample) + glsafe(::glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_DEPTH_COMPONENT24, w, h)); + else + glsafe(::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h)); + + glsafe(::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth)); GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; glsafe(::glDrawBuffers(1, drawBufs)); if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + { render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + if (multisample) + { + GLuint resolve_fbo; + glsafe(::glGenFramebuffers(1, &resolve_fbo)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo)); + + GLuint resolve_tex; + glsafe(::glGenTextures(1, &resolve_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, resolve_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolve_tex, 0)); + + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) + { + glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, render_fbo)); + glsafe(::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo)); + glsafe(::glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR)); + + glsafe(::glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo)); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + } + + glsafe(::glDeleteTextures(1, &resolve_tex)); + glsafe(::glDeleteFramebuffers(1, &resolve_fbo)); + } + else + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + } + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0)); - glsafe(::glDeleteRenderbuffers(1, &depth)); - glsafe(::glDeleteTextures(1, &tex)); - glsafe(::glDeleteFramebuffers(1, &fbo)); + glsafe(::glDeleteRenderbuffers(1, &render_depth)); + if (render_tex_buffer != 0) + glsafe(::glDeleteRenderbuffers(1, &render_tex_buffer)); + if (render_tex != 0) + glsafe(::glDeleteTextures(1, &render_tex)); + glsafe(::glDeleteFramebuffers(1, &render_fbo)); + + if (multisample) + glsafe(::glDisable(GL_MULTISAMPLE)); } void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3694,6 +3765,11 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + // restore the default framebuffer size to avoid flickering on the 3D scene m_camera.apply_viewport(0, 0, cnv_size.get_width(), cnv_size.get_height()); } From b3f53c96c7a5cad8ccaf60b0047d1b195826a32b Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 Oct 2019 08:28:40 +0100 Subject: [PATCH 46/82] Fixed update of 3D preview layout after changing printer after slicing --- src/slic3r/GUI/GUI_Preview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index b6350bcabc..d89ac1bcbb 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -375,6 +375,8 @@ void Preview::load_print(bool keep_z_range) load_print_as_fff(keep_z_range); else if (tech == ptSLA) load_print_as_sla(); + + Layout(); } void Preview::reload_print(bool keep_volumes) From f6453aab1b1569fd5ac7df02232ff4dff37159a7 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 30 Oct 2019 10:09:58 +0100 Subject: [PATCH 47/82] ENABLE_THUMBNAIL_GENERATOR -> Fixed potential race condition when generating thumbnails --- src/libslic3r/GCode.cpp | 1 + src/slic3r/GUI/Plater.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 92f733787a..ebb82cfb25 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -971,6 +971,7 @@ void GCode::_do_export(Print &print, FILE *file) _write(file, "; thumbnail end\n;\n\n"); } + print.throw_if_canceled(); } } #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f56d6fc278..464093712e 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3046,7 +3046,8 @@ bool Plater::priv::restart_background_process(unsigned int state) (state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) != 0 || (state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ) ) { #if ENABLE_THUMBNAIL_GENERATOR - if ((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) + if (((state & UPDATE_BACKGROUND_PROCESS_FORCE_EXPORT) == 0) && + (this->background_process.state() != BackgroundSlicingProcess::STATE_RUNNING)) { // update thumbnail data if (this->printer_technology == ptFFF) From ba39ee6f12821af35a1c5623d772f1f0a5c98e1b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 30 Oct 2019 10:18:56 +0100 Subject: [PATCH 48/82] EdgeGrid::signed_distance_edges() to provide the pedal point. Removed 20_print.t test. --- src/libslic3r/EdgeGrid.cpp | 138 ++++++++++++++++++++++++++++++++++++- src/libslic3r/EdgeGrid.hpp | 14 +++- xs/t/20_print.t | 16 ----- 3 files changed, 148 insertions(+), 20 deletions(-) delete mode 100644 xs/t/20_print.t diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index a97210da63..5e19c3b082 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -113,6 +113,7 @@ void EdgeGrid::Grid::create(const ExPolygonCollection &expolygons, coord_t resol // m_contours has been initialized. Now fill in the edge grid. void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) { + assert(resolution > 0); // 1) Measure the bounding box. for (size_t i = 0; i < m_contours.size(); ++ i) { const Slic3r::Points &pts = *m_contours[i]; @@ -1017,8 +1018,139 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const return f; } - -bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const { + +EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt, coord_t search_radius) const +{ + BoundingBox bbox; + bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1)); + bbox.defined = true; + // Upper boundary, round to grid and test validity. + bbox.max(0) += search_radius; + bbox.max(1) += search_radius; + ClosestPointResult result; + if (bbox.max(0) < 0 || bbox.max(1) < 0) + return result; + bbox.max(0) /= m_resolution; + bbox.max(1) /= m_resolution; + if ((size_t)bbox.max(0) >= m_cols) + bbox.max(0) = m_cols - 1; + if ((size_t)bbox.max(1) >= m_rows) + bbox.max(1) = m_rows - 1; + // Lower boundary, round to grid and test validity. + bbox.min(0) -= search_radius; + bbox.min(1) -= search_radius; + if (bbox.min(0) < 0) + bbox.min(0) = 0; + if (bbox.min(1) < 0) + bbox.min(1) = 0; + bbox.min(0) /= m_resolution; + bbox.min(1) /= m_resolution; + // Is the interval empty? + if (bbox.min(0) > bbox.max(0) || + bbox.min(1) > bbox.max(1)) + return result; + // Traverse all cells in the bounding box. + double d_min = double(search_radius); + // Signum of the distance field at pt. + int sign_min = 0; + double l2_seg_min = 1.; + for (int r = bbox.min(1); r <= bbox.max(1); ++ r) { + for (int c = bbox.min(0); c <= bbox.max(0); ++ c) { + const Cell &cell = m_cells[r * m_cols + c]; + for (size_t i = cell.begin; i < cell.end; ++ i) { + const size_t contour_idx = m_cell_data[i].first; + const Slic3r::Points &pts = *m_contours[contour_idx]; + size_t ipt = m_cell_data[i].second; + // End points of the line segment. + const Slic3r::Point &p1 = pts[ipt]; + const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1]; + const Slic3r::Point v_seg = p2 - p1; + const Slic3r::Point v_pt = pt - p1; + // dot(p2-p1, pt-p1) + int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1)); + // l2 of seg + int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1)); + if (t_pt < 0) { + // Closest to p1. + double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); + if (dabs < d_min) { + // Previous point. + const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1]; + Slic3r::Point v_seg_prev = p1 - p0; + int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1)); + if (t2_pt > 0) { + // Inside the wedge between the previous and the next segment. + d_min = dabs; + // Set the signum depending on whether the vertex is convex or reflex. + int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0)); + assert(det != 0); + sign_min = (det > 0) ? 1 : -1; + result.contour_idx = contour_idx; + result.start_point_idx = ipt; + result.t = 0.; +#ifndef NDEBUG + Vec2d vfoot = (p1 - pt).cast(); + double dist_foot = vfoot.norm(); + double dist_foot_err = dist_foot - d_min; + assert(std::abs(dist_foot_err) < 1e-7 * d_min); +#endif /* NDEBUG */ + } + } + } + else if (t_pt > l2_seg) { + // Closest to p2. Then p2 is the starting point of another segment, which shall be discovered in the same cell. + continue; + } else { + // Closest to the segment. + assert(t_pt >= 0 && t_pt <= l2_seg); + int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1)); + double d = double(d_seg) / sqrt(double(l2_seg)); + double dabs = std::abs(d); + if (dabs < d_min) { + d_min = dabs; + sign_min = (d_seg < 0) ? -1 : ((d_seg == 0) ? 0 : 1); + l2_seg_min = l2_seg; + result.contour_idx = contour_idx; + result.start_point_idx = ipt; + result.t = t_pt; +#ifndef NDEBUG + Vec2d foot = p1.cast() * (1. - result.t / l2_seg_min) + p2.cast() * (result.t / l2_seg_min); + Vec2d vfoot = foot - pt.cast(); + double dist_foot = vfoot.norm(); + double dist_foot_err = dist_foot - d_min; + assert(std::abs(dist_foot_err) < 1e-7 * d_min); +#endif /* NDEBUG */ + } + } + } + } + } + if (result.contour_idx != -1 && d_min <= double(search_radius)) { + result.distance = d_min * sign_min; + result.t /= l2_seg_min; + assert(result.t >= 0. && result.t < 1.); +#ifndef NDEBUG + { + const Slic3r::Points &pts = *m_contours[result.contour_idx]; + const Slic3r::Point &p1 = pts[result.start_point_idx]; + const Slic3r::Point &p2 = pts[(result.start_point_idx + 1 == pts.size()) ? 0 : result.start_point_idx + 1]; + Vec2d vfoot; + if (result.t == 0) + vfoot = p1.cast() - pt.cast(); + else + vfoot = p1.cast() * (1. - result.t) + p2.cast() * result.t - pt.cast(); + double dist_foot = vfoot.norm(); + double dist_foot_err = dist_foot - std::abs(result.distance); + assert(std::abs(dist_foot_err) < 1e-7 * std::abs(result.distance)); + } +#endif /* NDEBUG */ + } else + result = ClosestPointResult(); + return result; +} + +bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const +{ BoundingBox bbox; bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1)); bbox.defined = true; @@ -1047,7 +1179,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu bbox.min(1) > bbox.max(1)) return false; // Traverse all cells in the bounding box. - float d_min = search_radius; + double d_min = double(search_radius); // Signum of the distance field at pt. int sign_min = 0; bool on_segment = false; diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp index cad20e07bb..38a7d85428 100644 --- a/src/libslic3r/EdgeGrid.hpp +++ b/src/libslic3r/EdgeGrid.hpp @@ -46,7 +46,19 @@ public: float signed_distance_bilinear(const Point &pt) const; // Calculate a signed distance to the contours in search_radius from the point. - bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = NULL) const; + struct ClosestPointResult { + size_t contour_idx = size_t(-1); + size_t start_point_idx = size_t(-1); + // Signed distance to the closest point. + double distance = std::numeric_limits::max(); + // Parameter of the closest point on edge starting with start_point_idx <0, 1) + double t = 0.; + + bool valid() const { return contour_idx != size_t(-1); } + }; + ClosestPointResult closest_point(const Point &pt, coord_t search_radius) const; + + bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = nullptr) const; // Calculate a signed distance to the contours in search_radius from the point. If no edge is found in search_radius, // return an interpolated value from m_signed_distance_field, if it exists. diff --git a/xs/t/20_print.t b/xs/t/20_print.t deleted file mode 100644 index 68ec1e7195..0000000000 --- a/xs/t/20_print.t +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Slic3r::XS; -use Test::More tests => 3; - -{ - my $print = Slic3r::Print->new; - isa_ok $print, 'Slic3r::Print'; - isa_ok $print->config, 'Slic3r::Config::Static::Ref'; - isa_ok $print->placeholder_parser, 'Slic3r::GCode::PlaceholderParser::Ref'; -} - -__END__ From b928cca54c666036f9d66074930761d416063cd4 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 29 Oct 2019 13:33:29 +0100 Subject: [PATCH 49/82] Useful verbose test output on console with Catch2 --- tests/CMakeLists.txt | 2 +- tests/catch_main.hpp | 51 ++++++++++++++++++++++++ tests/example/example_tests_main.cpp | 2 +- tests/fff_print/fff_print_tests.cpp | 3 +- tests/libnest2d/libnest2d_tests_main.cpp | 4 +- tests/libslic3r/libslic3r_tests.cpp | 3 +- tests/sla_print/sla_print_tests.cpp | 3 +- tests/timeutils/timeutils_tests_main.cpp | 3 +- 8 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 tests/catch_main.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e8db00bf3..cab2030fe6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) add_library(Catch2::Catch2 ALIAS Catch2) include(Catch) -set(CATCH_EXTRA_ARGS "--durations yes" CACHE STRING "Extra arguments for catch2 test suites.") +set(CATCH_EXTRA_ARGS "-r usefulconsole" CACHE STRING "Extra arguments for catch2 test suites.") add_library(test_common INTERFACE) target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE) diff --git a/tests/catch_main.hpp b/tests/catch_main.hpp new file mode 100644 index 0000000000..e49ff40b4a --- /dev/null +++ b/tests/catch_main.hpp @@ -0,0 +1,51 @@ +#ifndef CATCH_MAIN +#define CATCH_MAIN + +#define CATCH_CONFIG_EXTERNAL_INTERFACES +#define CATCH_CONFIG_MAIN +#include + +namespace Catch { +struct VerboseConsoleReporter : public ConsoleReporter { + double duration = 0.; + using ConsoleReporter::ConsoleReporter; + + void testCaseStarting(TestCaseInfo const& _testInfo) override + { + Colour::use(Colour::Cyan); + stream << "Testing "; + Colour::use(Colour::None); + stream << _testInfo.name << std::endl; + ConsoleReporter::testCaseStarting(_testInfo); + } + + void sectionStarting(const SectionInfo &_sectionInfo) override + { + if (_sectionInfo.name != currentTestCaseInfo->name) + stream << _sectionInfo.name << std::endl; + + ConsoleReporter::sectionStarting(_sectionInfo); + } + + void sectionEnded(const SectionStats &_sectionStats) override { + duration += _sectionStats.durationInSeconds; + ConsoleReporter::sectionEnded(_sectionStats); + } + + void testCaseEnded(TestCaseStats const& stats) override + { + if (stats.totals.assertions.allOk()) { + Colour::use(Colour::BrightGreen); + stream << "Passed"; + Colour::use(Colour::None); + stream << " in " << duration << " [seconds]\n" << std::endl; + } + + duration = 0.; + ConsoleReporter::testCaseEnded(stats); + } +}; +CATCH_REGISTER_REPORTER( "verboseconsole", VerboseConsoleReporter ) +} + +#endif // CATCH_MAIN diff --git a/tests/example/example_tests_main.cpp b/tests/example/example_tests_main.cpp index d612f323cb..32e8d02b76 100644 --- a/tests/example/example_tests_main.cpp +++ b/tests/example/example_tests_main.cpp @@ -1,5 +1,5 @@ #define CATCH_CONFIG_MAIN -#include +#include TEST_CASE("Is example succesful", "[example]") { REQUIRE(true); diff --git a/tests/fff_print/fff_print_tests.cpp b/tests/fff_print/fff_print_tests.cpp index 5e9b82f80b..46358e5eba 100644 --- a/tests/fff_print/fff_print_tests.cpp +++ b/tests/fff_print/fff_print_tests.cpp @@ -1,4 +1,3 @@ -#define CATCH_CONFIG_MAIN -#include +#include #include "libslic3r/libslic3r.h" diff --git a/tests/libnest2d/libnest2d_tests_main.cpp b/tests/libnest2d/libnest2d_tests_main.cpp index 252bea47fe..c7259ae537 100644 --- a/tests/libnest2d/libnest2d_tests_main.cpp +++ b/tests/libnest2d/libnest2d_tests_main.cpp @@ -1,9 +1,7 @@ -#define CATCH_CONFIG_MAIN -#include +#include #include - #include #include "printer_parts.hpp" //#include diff --git a/tests/libslic3r/libslic3r_tests.cpp b/tests/libslic3r/libslic3r_tests.cpp index 907304f57a..caf5b3b9ac 100644 --- a/tests/libslic3r/libslic3r_tests.cpp +++ b/tests/libslic3r/libslic3r_tests.cpp @@ -1,5 +1,4 @@ -#define CATCH_CONFIG_MAIN -#include +#include #include "libslic3r/libslic3r.h" diff --git a/tests/sla_print/sla_print_tests.cpp b/tests/sla_print/sla_print_tests.cpp index f41fd3200a..229eb42676 100644 --- a/tests/sla_print/sla_print_tests.cpp +++ b/tests/sla_print/sla_print_tests.cpp @@ -1,5 +1,4 @@ -#define CATCH_CONFIG_MAIN -#include +#include #include #include diff --git a/tests/timeutils/timeutils_tests_main.cpp b/tests/timeutils/timeutils_tests_main.cpp index c3827374e5..9989f98716 100644 --- a/tests/timeutils/timeutils_tests_main.cpp +++ b/tests/timeutils/timeutils_tests_main.cpp @@ -1,5 +1,4 @@ -#define CATCH_CONFIG_MAIN -#include +#include #include "libslic3r/Time.hpp" From 4594ce77b058225a60f153ab3ee94ca4408136ff Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 30 Oct 2019 10:47:04 +0100 Subject: [PATCH 50/82] Make verboseconsole the default reporter. --- tests/CMakeLists.txt | 2 +- tests/catch_main.hpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cab2030fe6..f77b4bd25f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories(Catch2 INTERFACE ${CMAKE_CURRENT_LIST_DIR}) add_library(Catch2::Catch2 ALIAS Catch2) include(Catch) -set(CATCH_EXTRA_ARGS "-r usefulconsole" CACHE STRING "Extra arguments for catch2 test suites.") +set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.") add_library(test_common INTERFACE) target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE) diff --git a/tests/catch_main.hpp b/tests/catch_main.hpp index e49ff40b4a..5ab71fdd74 100644 --- a/tests/catch_main.hpp +++ b/tests/catch_main.hpp @@ -3,6 +3,7 @@ #define CATCH_CONFIG_EXTERNAL_INTERFACES #define CATCH_CONFIG_MAIN +#define CATCH_CONFIG_DEFAULT_REPORTER "verboseconsole" #include namespace Catch { @@ -45,7 +46,9 @@ struct VerboseConsoleReporter : public ConsoleReporter { ConsoleReporter::testCaseEnded(stats); } }; + CATCH_REGISTER_REPORTER( "verboseconsole", VerboseConsoleReporter ) -} + +} // namespace Catch #endif // CATCH_MAIN From 2e7ac3bfa6af0875e55d0e3ccb9d447e14593a7a Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 30 Oct 2019 17:21:28 +0100 Subject: [PATCH 51/82] fix openvdb dependency build bugs Fixes for release only build of dependencies on windows Omit blosc packing in deps build Try to fix patching by reverting to git repos in download steps Patching does not remove or rename files. --- deps/blosc-mods.patch | 135 +++++++------- deps/deps-windows.cmake | 45 +++-- deps/openvdb-mods.patch | 379 +++++++++++++++++++++------------------- 3 files changed, 284 insertions(+), 275 deletions(-) diff --git a/deps/blosc-mods.patch b/deps/blosc-mods.patch index 2289459ab5..9a91b4974c 100644 --- a/deps/blosc-mods.patch +++ b/deps/blosc-mods.patch @@ -1,23 +1,22 @@ -From 24640a466b28dfda26069096554676e8c0b6d090 Mon Sep 17 00:00:00 2001 +From 5669891dfaaa4c814f3ec667ca6bf4e693aea978 Mon Sep 17 00:00:00 2001 From: tamasmeszaros -Date: Tue, 22 Oct 2019 11:29:05 +0200 -Subject: [PATCH] Install.dll in prefix/bin and add config export to cmake - build +Date: Wed, 30 Oct 2019 12:54:52 +0100 +Subject: [PATCH] Blosc 1.17 fixes and cmake config script --- - CMakeLists.txt | 112 ++++++++++++++++++++---------------- - blosc/CMakeLists.txt | 121 ++++++++++----------------------------- + CMakeLists.txt | 105 +++++++++++++++++----------------- + blosc/CMakeLists.txt | 118 +++++++++------------------------------ cmake/FindLZ4.cmake | 6 +- cmake/FindSnappy.cmake | 8 ++- cmake/FindZstd.cmake | 8 ++- - cmake_config.cmake.in | 33 +++++++++++ - internal-complibs/CMakeLists.txt | 30 ++++++++++ - 7 files changed, 173 insertions(+), 145 deletions(-) + cmake_config.cmake.in | 24 ++++++++ + internal-complibs/CMakeLists.txt | 35 ++++++++++++ + 7 files changed, 157 insertions(+), 147 deletions(-) create mode 100644 cmake_config.cmake.in create mode 100644 internal-complibs/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt -index 59d9fab..bdc0dda 100644 +index 59d9fab..e9134c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ @@ -29,36 +28,11 @@ index 59d9fab..bdc0dda 100644 if (NOT CMAKE_VERSION VERSION_LESS 3.3) cmake_policy(SET CMP0063 NEW) endif() -@@ -124,55 +124,37 @@ option(PREFER_EXTERNAL_ZSTD +@@ -124,55 +124,30 @@ option(PREFER_EXTERNAL_ZSTD set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") -+set(PRIVATE_LIBS "") -+set(PUBLIC_LIBS "") -+set(PUBLIC_PACKAGES "" CACHE INTERNAL "") -+macro(use_package _pkg _tgt) -+ string(TOUPPER ${_pkg} _PKG) -+ if(NOT DEACTIVATE_${_PKG}) -+ if(PREFER_EXTERNAL_${_PKG}) -+ find_package(${_pkg}) -+ if (NOT ${_pkg}_FOUND ) -+ message(STATUS "No ${_pkg} found. Using internal sources.") -+ endif() -+ else() -+ message(STATUS "Using ${_pkg} internal sources.") -+ endif(PREFER_EXTERNAL_${_PKG}) -+ # HAVE_${_pkg} will be set to true because even if the library is -+ # not found, we will use the included sources for it -+ set(HAVE_${_PKG} TRUE) -+ if (${_pkg}_FOUND) -+ list(APPEND PUBLIC_LIBS ${_pkg}::${_tgt}) -+ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};${_pkg}" CACHE INTERNAL "") -+ else() -+ list(APPEND PRIVATE_LIBS ${_pkg}::${_tgt}) -+ endif() -+ endif(NOT DEACTIVATE_${_PKG}) -+endmacro() - +- -if(NOT DEACTIVATE_LZ4) - if(PREFER_EXTERNAL_LZ4) - find_package(LZ4) @@ -107,6 +81,25 @@ index 59d9fab..bdc0dda 100644 - # not found, we will use the included sources for it - set(HAVE_ZSTD TRUE) -endif (NOT DEACTIVATE_ZSTD) ++set(LIBS "") ++macro(use_package _pkg _tgt) ++ string(TOUPPER ${_pkg} _PKG) ++ if(NOT DEACTIVATE_${_PKG}) ++ if(PREFER_EXTERNAL_${_PKG}) ++ find_package(${_pkg}) ++ if (NOT ${_pkg}_FOUND ) ++ message(STATUS "No ${_pkg} found. Using internal sources.") ++ endif() ++ else() ++ message(STATUS "Using ${_pkg} internal sources.") ++ endif(PREFER_EXTERNAL_${_PKG}) ++ # HAVE_${_pkg} will be set to true because even if the library is ++ # not found, we will use the included sources for it ++ set(HAVE_${_PKG} TRUE) ++ list(APPEND LIBS ${_pkg}::${_tgt}) ++ endif(NOT DEACTIVATE_${_PKG}) ++endmacro() ++ +set(ZLIB_ROOT $ENV{ZLIB_ROOT}) +use_package(ZLIB ZLIB) +use_package(LZ4 LZ4) @@ -115,7 +108,7 @@ index 59d9fab..bdc0dda 100644 # create the config.h file configure_file ("blosc/config.h.in" "blosc/config.h" ) -@@ -316,6 +298,7 @@ endif() +@@ -316,6 +291,7 @@ endif() # subdirectories @@ -123,7 +116,15 @@ index 59d9fab..bdc0dda 100644 add_subdirectory(blosc) if(BUILD_TESTS) -@@ -338,10 +321,41 @@ if (BLOSC_INSTALL) +@@ -328,7 +304,6 @@ if(BUILD_BENCHMARKS) + add_subdirectory(bench) + endif(BUILD_BENCHMARKS) + +- + # uninstall target + if (BLOSC_INSTALL) + configure_file( +@@ -338,10 +313,38 @@ if (BLOSC_INSTALL) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/blosc.pc" DESTINATION lib/pkgconfig COMPONENT DEV) @@ -157,16 +158,13 @@ index 59d9fab..bdc0dda 100644 + install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmakeexports/BloscConfigVersion.cmake" -+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLZ4.cmake" -+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindZstd.cmake" -+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindSnappy.cmake" + DESTINATION lib/cmake/Blosc COMPONENT DEV) + add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) endif() diff --git a/blosc/CMakeLists.txt b/blosc/CMakeLists.txt -index 1d1bebe..16aff02 100644 +index 1d1bebe..f554abe 100644 --- a/blosc/CMakeLists.txt +++ b/blosc/CMakeLists.txt @@ -1,52 +1,11 @@ @@ -222,19 +220,17 @@ index 1d1bebe..16aff02 100644 # library sources set(SOURCES blosc.c blosclz.c fastcopy.c shuffle-generic.c bitshuffle-generic.c -@@ -73,53 +32,15 @@ if(WIN32) +@@ -73,53 +32,13 @@ if(WIN32) message(STATUS "using the internal pthread library for win32 systems.") set(SOURCES ${SOURCES} win32/pthread.c) else(NOT Threads_FOUND) - set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) -+ list(APPEND PUBLIC_LIBS Threads::Threads) -+ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};Threads" CACHE INTERNAL "") ++ list(APPEND LIBS Threads::Threads) endif(NOT Threads_FOUND) else(WIN32) find_package(Threads REQUIRED) - set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) -+ list(APPEND PUBLIC_LIBS Threads::Threads) -+ set(PUBLIC_PACKAGES "${PUBLIC_PACKAGES};Threads" CACHE INTERNAL "") ++ list(APPEND LIBS Threads::Threads) endif(WIN32) -if(NOT DEACTIVATE_LZ4) @@ -280,7 +276,7 @@ index 1d1bebe..16aff02 100644 # targets if (BUILD_SHARED) add_library(blosc_shared SHARED ${SOURCES}) -@@ -191,14 +112,18 @@ if (BUILD_TESTS) +@@ -191,14 +110,17 @@ if (BUILD_TESTS) endif() endif() @@ -289,8 +285,7 @@ index 1d1bebe..16aff02 100644 if (BUILD_SHARED) - target_link_libraries(blosc_shared ${LIBS}) - target_include_directories(blosc_shared PUBLIC ${BLOSC_INCLUDE_DIRS}) -+ target_link_libraries(blosc_shared PUBLIC ${PUBLIC_LIBS}) -+ target_link_libraries(blosc_shared PRIVATE ${PRIVATE_LIBS}) ++ target_link_libraries(blosc_shared PRIVATE ${LIBS}) + target_include_directories(blosc_shared PUBLIC $) + target_link_libraries(blosc INTERFACE blosc_shared) endif() @@ -298,19 +293,19 @@ index 1d1bebe..16aff02 100644 if (BUILD_TESTS) - target_link_libraries(blosc_shared_testing ${LIBS}) - target_include_directories(blosc_shared_testing PUBLIC ${BLOSC_INCLUDE_DIRS}) -+ target_link_libraries(blosc_shared_testing ${PUBLIC_LIBS} ${PRIVATE_LIBS}) ++ target_link_libraries(blosc_shared_testing PRIVATE ${LIBS}) + target_include_directories(blosc_shared_testing PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) endif() if(BUILD_STATIC) -@@ -207,17 +132,31 @@ if(BUILD_STATIC) +@@ -207,17 +129,31 @@ if(BUILD_STATIC) if (MSVC) set_target_properties(blosc_static PROPERTIES PREFIX lib) endif() - target_link_libraries(blosc_static ${LIBS}) - target_include_directories(blosc_static PUBLIC ${BLOSC_INCLUDE_DIRS}) -+ target_link_libraries(blosc_static PUBLIC ${PUBLIC_LIBS}) -+ target_link_libraries(blosc_static PRIVATE ${PRIVATE_LIBS}) ++ # With the static library, cmake has to deal with transitive dependencies ++ target_link_libraries(blosc_static PRIVATE ${LIBS}) + target_include_directories(blosc_static PUBLIC $) + if (NOT BUILD_SHARED) + target_link_libraries(blosc INTERFACE blosc_static) @@ -398,24 +393,15 @@ index 7db4bb9..cabc2f8 100644 \ No newline at end of file diff --git a/cmake_config.cmake.in b/cmake_config.cmake.in new file mode 100644 -index 0000000..b4ede30 +index 0000000..0f6af24 --- /dev/null +++ b/cmake_config.cmake.in -@@ -0,0 +1,33 @@ +@@ -0,0 +1,24 @@ +include(CMakeFindDependencyMacro) + -+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) -+ -+set(_deps "@PUBLIC_PACKAGES@") -+ -+foreach(pkg ${_deps}) -+ # no minimum versions are required by upstream -+ find_dependency(${pkg}) -+endforeach() -+ +include("${CMAKE_CURRENT_LIST_DIR}/BloscTargets.cmake") + -+function(remap_configs from_Cfg to_Cfg) ++function(_blosc_remap_configs from_Cfg to_Cfg) + string(TOUPPER ${from_Cfg} from_CFG) + string(TOLOWER ${from_Cfg} from_cfg) + @@ -432,21 +418,25 @@ index 0000000..b4ede30 +# MSVC will try to link RelWithDebInfo or MinSizeRel target with debug config +# if no matching installation is present which would result in link errors. +if(MSVC) -+ remap_configs(RelWithDebInfo Release) -+ remap_configs(MinSizeRel Release) ++ _blosc_remap_configs(RelWithDebInfo Release) ++ _blosc_remap_configs(MinSizeRel Release) +endif() diff --git a/internal-complibs/CMakeLists.txt b/internal-complibs/CMakeLists.txt new file mode 100644 -index 0000000..5b23484 +index 0000000..4586efa --- /dev/null +++ b/internal-complibs/CMakeLists.txt -@@ -0,0 +1,30 @@ +@@ -0,0 +1,35 @@ +macro(add_lib_target pkg tgt incdir files) + string(TOUPPER ${pkg} TGT) + if(NOT DEACTIVATE_${TGT} AND NOT ${pkg}_FOUND) ++ add_library(${tgt}_objs OBJECT ${files}) + add_library(${tgt} INTERFACE) ++ target_include_directories(${tgt}_objs PRIVATE $) + target_include_directories(${tgt} INTERFACE $) -+ target_sources(${tgt} INTERFACE "$") ++ #set_target_properties(${tgt} PROPERTIES INTERFACE_SOURCES "$") ++ set_target_properties(${tgt}_objs PROPERTIES POSITION_INDEPENDENT_CODE ON) ++ target_sources(${tgt} INTERFACE "$>") + add_library(${pkg}::${tgt} ALIAS ${tgt}) + + # This creates dummy (empty) interface targets in the exported config. @@ -471,6 +461,7 @@ index 0000000..5b23484 +file(GLOB ZSTD_FILES ${ZSTD_DIR}/common/*.c ${ZSTD_DIR}/compress/*.c ${ZSTD_DIR}/decompress/*.c) +add_lib_target(Zstd Zstd ${ZSTD_DIR} "${ZSTD_FILES}") +target_include_directories(Zstd INTERFACE $) ++target_include_directories(Zstd_objs PRIVATE $) \ No newline at end of file -- 2.16.2.windows.1 diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 08e10758d3..4f8bbc1ab5 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -81,7 +81,6 @@ ExternalProject_Add(dep_boost INSTALL_COMMAND "" # b2 does that already ) - ExternalProject_Add(dep_tbb EXCLUDE_FROM_ALL 1 URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz" @@ -99,22 +98,22 @@ ExternalProject_Add(dep_tbb add_debug_dep(dep_tbb) -ExternalProject_Add(dep_gtest - EXCLUDE_FROM_ALL 1 - URL "https://github.com/google/googletest/archive/release-1.8.1.tar.gz" - URL_HASH SHA256=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c - CMAKE_GENERATOR "${DEP_MSVC_GEN}" - CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" - CMAKE_ARGS - -DBUILD_GMOCK=OFF - -Dgtest_force_shared_crt=ON - -DCMAKE_POSITION_INDEPENDENT_CODE=ON - "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" - BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj - INSTALL_COMMAND "" -) +# ExternalProject_Add(dep_gtest +# EXCLUDE_FROM_ALL 1 +# URL "https://github.com/google/googletest/archive/release-1.8.1.tar.gz" +# URL_HASH SHA256=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c +# CMAKE_GENERATOR "${DEP_MSVC_GEN}" +# CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" +# CMAKE_ARGS +# -DBUILD_GMOCK=OFF +# -Dgtest_force_shared_crt=ON +# -DCMAKE_POSITION_INDEPENDENT_CODE=ON +# "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local" +# BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj +# INSTALL_COMMAND "" +# ) -add_debug_dep(dep_gtest) +# add_debug_dep(dep_gtest) ExternalProject_Add(dep_cereal EXCLUDE_FROM_ALL 1 @@ -181,7 +180,6 @@ if (${DEP_DEBUG}) ) endif () - if (${DEPS_BITS} EQUAL 32) set(DEP_LIBCURL_TARGET "x86") else () @@ -305,10 +303,13 @@ endif () ExternalProject_Add(dep_blosc EXCLUDE_FROM_ALL 1 + #URL https://github.com/Blosc/c-blosc/archive/v1.17.0.zip + #URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9 GIT_REPOSITORY https://github.com/Blosc/c-blosc.git GIT_TAG v1.17.0 DEPENDS dep_zlib CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local -DBUILD_SHARED_LIBS=OFF @@ -319,6 +320,8 @@ ExternalProject_Add(dep_blosc -DBUILD_TESTS=OFF -DBUILD_BENCHMARKS=OFF -DPREFER_EXTERNAL_ZLIB=ON + -DBLOSC_IS_SUBPROJECT:BOOL=ON + -DBLOSC_INSTALL:BOOL=ON PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" @@ -330,8 +333,9 @@ ExternalProject_Add(dep_openexr EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/openexr/openexr.git GIT_TAG v2.4.0 - DEPENDS dep_zlib + DEPENDS CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local -DBUILD_SHARED_LIBS=OFF @@ -348,10 +352,13 @@ add_debug_dep(dep_openexr) ExternalProject_Add(dep_openvdb EXCLUDE_FROM_ALL 1 + #URL https://github.com/AcademySoftwareFoundation/openvdb/archive/v6.2.1.zip + #URL_HASH SHA256=dc337399dce8e1c9f21f20e97b1ce7e4933cb0a63bb3b8b734d8fcc464aa0c48 GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git GIT_TAG v6.2.1 - DEPENDS dep_blosc dep_openexr dep_tbb + DEPENDS dep_blosc dep_openexr dep_tbb dep_boost CMAKE_GENERATOR "${DEP_MSVC_GEN}" + CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local -DCMAKE_DEBUG_POSTFIX=d diff --git a/deps/openvdb-mods.patch b/deps/openvdb-mods.patch index a05076e986..60687b8d17 100644 --- a/deps/openvdb-mods.patch +++ b/deps/openvdb-mods.patch @@ -1,4 +1,4 @@ -From ee867b9f226412c0f3b83fa01cd43539acc4ed95 Mon Sep 17 00:00:00 2001 +From e48f4a835fe7cb391f9f90945472bd367fb4c4f1 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 16 Oct 2019 17:42:50 +0200 Subject: [PATCH] Build fixes for PrusaSlicer integration @@ -7,17 +7,17 @@ Subject: [PATCH] Build fixes for PrusaSlicer integration CMakeLists.txt | 3 - cmake/FindBlosc.cmake | 218 --------------- cmake/FindCppUnit.cmake | 4 +- - cmake/FindIlmBase.cmake | 337 ----------------------- + cmake/FindIlmBase.cmake | 337 ---------------------- cmake/FindOpenEXR.cmake | 329 ---------------------- cmake/FindOpenVDB.cmake | 19 +- - cmake/FindTBB.cmake | 593 ++++++++++++++++++++-------------------- + cmake/FindTBB.cmake | 605 ++++++++++++++++++++-------------------- openvdb/CMakeLists.txt | 13 +- openvdb/Grid.cc | 3 + openvdb/PlatformConfig.h | 9 +- openvdb/cmd/CMakeLists.txt | 4 +- openvdb/unittest/CMakeLists.txt | 3 +- openvdb/unittest/TestFile.cc | 2 +- - 13 files changed, 325 insertions(+), 1212 deletions(-) + 13 files changed, 336 insertions(+), 1213 deletions(-) delete mode 100644 cmake/FindBlosc.cmake delete mode 100644 cmake/FindIlmBase.cmake delete mode 100644 cmake/FindOpenEXR.cmake @@ -1011,10 +1011,10 @@ index 63a2eda..6211071 100644 endforeach() diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake -index bdf9c81..ffdee03 100644 +index bdf9c81..c6bdec9 100644 --- a/cmake/FindTBB.cmake +++ b/cmake/FindTBB.cmake -@@ -1,333 +1,322 @@ +@@ -1,333 +1,332 @@ -# Copyright (c) DreamWorks Animation LLC +# The MIT License (MIT) # @@ -1205,10 +1205,6 @@ index bdf9c81..ffdee03 100644 +# +# This module will also create the "tbb" target that may be used when building +# executables and libraries. -+ -+include(FindPackageHandleStandardArgs) -+ -+if(NOT TBB_FOUND) -mark_as_advanced( - Tbb_INCLUDE_DIR @@ -1227,6 +1223,39 @@ index bdf9c81..ffdee03 100644 - foreach(COMPONENT ${TBB_FIND_COMPONENTS}) - if(NOT ${COMPONENT} IN_LIST _TBB_COMPONENT_LIST) - list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) +- endif() +- endforeach() ++unset(TBB_FOUND CACHE) ++unset(TBB_INCLUDE_DIRS CACHE) ++unset(TBB_LIBRARIES) ++unset(TBB_LIBRARIES_DEBUG) ++unset(TBB_LIBRARIES_RELEASE) + +- if(_IGNORED_COMPONENTS) +- message(STATUS "Ignoring unknown components of TBB:") +- foreach(COMPONENT ${_IGNORED_COMPONENTS}) +- message(STATUS " ${COMPONENT}") +- endforeach() +- list(REMOVE_ITEM TBB_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) +- endif() +-else() +- set(_TBB_COMPONENTS_PROVIDED FALSE) +- set(TBB_FIND_COMPONENTS ${_TBB_COMPONENT_LIST}) +-endif() ++include(FindPackageHandleStandardArgs) ++ ++find_package(Threads QUIET REQUIRED) + +-# Append TBB_ROOT or $ENV{TBB_ROOT} if set (prioritize the direct cmake var) +-set(_TBB_ROOT_SEARCH_DIR "") ++if(NOT TBB_FOUND) + +-if(TBB_ROOT) +- list(APPEND _TBB_ROOT_SEARCH_DIR ${TBB_ROOT}) +-else() +- set(_ENV_TBB_ROOT $ENV{TBB_ROOT}) +- if(_ENV_TBB_ROOT) +- list(APPEND _TBB_ROOT_SEARCH_DIR ${_ENV_TBB_ROOT}) + ################################## + # Check the build type + ################################## @@ -1241,7 +1270,8 @@ index bdf9c81..ffdee03 100644 + set(TBB_BUILD_TYPE DEBUG) + else() + set(TBB_BUILD_TYPE RELEASE) -+ endif() + endif() +-endif() + + ################################## + # Set the TBB search directories @@ -1261,7 +1291,53 @@ index bdf9c81..ffdee03 100644 + else() + set(TBB_ARCHITECTURE "ia32") + endif() -+ + +-# Additionally try and use pkconfig to find Tbb +- +-find_package(PkgConfig) +-pkg_check_modules(PC_Tbb QUIET tbb) +- +-# ------------------------------------------------------------------------ +-# Search for tbb include DIR +-# ------------------------------------------------------------------------ +- +-set(_TBB_INCLUDE_SEARCH_DIRS "") +-list(APPEND _TBB_INCLUDE_SEARCH_DIRS +- ${TBB_INCLUDEDIR} +- ${_TBB_ROOT_SEARCH_DIR} +- ${PC_Tbb_INCLUDE_DIRS} +- ${SYSTEM_LIBRARY_PATHS} +-) +- +-# Look for a standard tbb header file. +-find_path(Tbb_INCLUDE_DIR tbb/tbb_stddef.h +- NO_DEFAULT_PATH +- PATHS ${_TBB_INCLUDE_SEARCH_DIRS} +- PATH_SUFFIXES include +-) +- +-if(EXISTS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h") +- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" +- _tbb_version_major_string REGEX "#define TBB_VERSION_MAJOR " +- ) +- string(REGEX REPLACE "#define TBB_VERSION_MAJOR" "" +- _tbb_version_major_string "${_tbb_version_major_string}" +- ) +- string(STRIP "${_tbb_version_major_string}" Tbb_VERSION_MAJOR) +- +- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" +- _tbb_version_minor_string REGEX "#define TBB_VERSION_MINOR " +- ) +- string(REGEX REPLACE "#define TBB_VERSION_MINOR" "" +- _tbb_version_minor_string "${_tbb_version_minor_string}" +- ) +- string(STRIP "${_tbb_version_minor_string}" Tbb_VERSION_MINOR) +- +- unset(_tbb_version_major_string) +- unset(_tbb_version_minor_string) +- +- set(Tbb_VERSION ${Tbb_VERSION_MAJOR}.${Tbb_VERSION_MINOR}) +-endif() + # Set the TBB search library path search suffix based on the version of VC + if(WINDOWS_STORE) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui") @@ -1273,15 +1349,11 @@ index bdf9c81..ffdee03 100644 + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11") + elseif(MSVC10) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10") - endif() -- endforeach() ++ endif() -- if(_IGNORED_COMPONENTS) -- message(STATUS "Ignoring unknown components of TBB:") -- foreach(COMPONENT ${_IGNORED_COMPONENTS}) -- message(STATUS " ${COMPONENT}") -- endforeach() -- list(REMOVE_ITEM TBB_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) +-# ------------------------------------------------------------------------ +-# Search for TBB lib DIR +-# ------------------------------------------------------------------------ + # Add the library path search suffix for the VC independent version of TBB + list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt") + @@ -1332,110 +1404,19 @@ index bdf9c81..ffdee03 100644 + string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_INTERFACE_VERSION "${_tbb_version_file}") + set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}") - endif() --else() -- set(_TBB_COMPONENTS_PROVIDED FALSE) -- set(TBB_FIND_COMPONENTS ${_TBB_COMPONENT_LIST}) --endif() ++ endif() --# Append TBB_ROOT or $ENV{TBB_ROOT} if set (prioritize the direct cmake var) --set(_TBB_ROOT_SEARCH_DIR "") +-set(_TBB_LIBRARYDIR_SEARCH_DIRS "") + ################################## + # Find TBB components + ################################## --if(TBB_ROOT) -- list(APPEND _TBB_ROOT_SEARCH_DIR ${TBB_ROOT}) --else() -- set(_ENV_TBB_ROOT $ENV{TBB_ROOT}) -- if(_ENV_TBB_ROOT) -- list(APPEND _TBB_ROOT_SEARCH_DIR ${_ENV_TBB_ROOT}) +-# Append to _TBB_LIBRARYDIR_SEARCH_DIRS in priority order + if(TBB_VERSION VERSION_LESS 4.3) + set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc tbb) + else() + set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc_proxy tbbmalloc tbb) - endif() --endif() - --# Additionally try and use pkconfig to find Tbb -- --find_package(PkgConfig) --pkg_check_modules(PC_Tbb QUIET tbb) -- --# ------------------------------------------------------------------------ --# Search for tbb include DIR --# ------------------------------------------------------------------------ -- --set(_TBB_INCLUDE_SEARCH_DIRS "") --list(APPEND _TBB_INCLUDE_SEARCH_DIRS -- ${TBB_INCLUDEDIR} -- ${_TBB_ROOT_SEARCH_DIR} -- ${PC_Tbb_INCLUDE_DIRS} -- ${SYSTEM_LIBRARY_PATHS} --) -- --# Look for a standard tbb header file. --find_path(Tbb_INCLUDE_DIR tbb/tbb_stddef.h -- NO_DEFAULT_PATH -- PATHS ${_TBB_INCLUDE_SEARCH_DIRS} -- PATH_SUFFIXES include --) -- --if(EXISTS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h") -- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" -- _tbb_version_major_string REGEX "#define TBB_VERSION_MAJOR " -- ) -- string(REGEX REPLACE "#define TBB_VERSION_MAJOR" "" -- _tbb_version_major_string "${_tbb_version_major_string}" -- ) -- string(STRIP "${_tbb_version_major_string}" Tbb_VERSION_MAJOR) -- -- file(STRINGS "${Tbb_INCLUDE_DIR}/tbb/tbb_stddef.h" -- _tbb_version_minor_string REGEX "#define TBB_VERSION_MINOR " -- ) -- string(REGEX REPLACE "#define TBB_VERSION_MINOR" "" -- _tbb_version_minor_string "${_tbb_version_minor_string}" -- ) -- string(STRIP "${_tbb_version_minor_string}" Tbb_VERSION_MINOR) -- -- unset(_tbb_version_major_string) -- unset(_tbb_version_minor_string) -- -- set(Tbb_VERSION ${Tbb_VERSION_MAJOR}.${Tbb_VERSION_MINOR}) --endif() -+ if(TBB_STATIC) -+ set(TBB_STATIC_SUFFIX "_static") + endif() -+ -+ # Find each component -+ foreach(_comp ${TBB_SEARCH_COMPOMPONENTS}) -+ if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};") - --# ------------------------------------------------------------------------ --# Search for TBB lib DIR --# ------------------------------------------------------------------------ -+ # Search for the libraries -+ find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX} -+ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} -+ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH -+ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) - --set(_TBB_LIBRARYDIR_SEARCH_DIRS "") -+ find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}${TBB_STATIC_SUFFIX}_debug -+ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} -+ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH -+ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) - --# Append to _TBB_LIBRARYDIR_SEARCH_DIRS in priority order -+ if(TBB_${_comp}_LIBRARY_DEBUG) -+ list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}") -+ endif() -+ if(TBB_${_comp}_LIBRARY_RELEASE) -+ list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}") -+ endif() -+ if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY) -+ set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}") -+ endif() -set(_TBB_LIBRARYDIR_SEARCH_DIRS "") -list(APPEND _TBB_LIBRARYDIR_SEARCH_DIRS @@ -1444,41 +1425,35 @@ index bdf9c81..ffdee03 100644 - ${PC_Tbb_LIBRARY_DIRS} - ${SYSTEM_LIBRARY_PATHS} -) -+ if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}") -+ set(TBB_${_comp}_FOUND TRUE) -+ else() -+ set(TBB_${_comp}_FOUND FALSE) -+ endif() ++ if(TBB_STATIC) ++ set(TBB_STATIC_SUFFIX "_static") ++ endif() -set(TBB_PATH_SUFFIXES - lib64 - lib -) -+ # Mark internal variables as advanced -+ mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE) -+ mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG) -+ mark_as_advanced(TBB_${_comp}_LIBRARY) ++ # Find each component ++ foreach(_comp ${TBB_SEARCH_COMPOMPONENTS}) ++ if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};") -# platform branching -+ endif() -+ endforeach() ++ unset(TBB_${_comp}_LIBRARY_DEBUG CACHE) ++ unset(TBB_${_comp}_LIBRARY_RELEASE CACHE) -if(UNIX) - list(INSERT TBB_PATH_SUFFIXES 0 lib/x86_64-linux-gnu) -endif() -+ ################################## -+ # Set compile flags and libraries -+ ################################## ++ # Search for the libraries ++ find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX} ++ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} ++ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH ++ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) -if(APPLE) - if(TBB_FOR_CLANG) - list(INSERT TBB_PATH_SUFFIXES 0 lib/libc++) -+ set(TBB_DEFINITIONS_RELEASE "") -+ set(TBB_DEFINITIONS_DEBUG "TBB_USE_DEBUG=1") -+ -+ if(TBB_LIBRARIES_${TBB_BUILD_TYPE}) -+ set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") - endif() +- endif() -elseif(WIN32) - if(MSVC10) - set(TBB_VC_DIR vc10) @@ -1498,45 +1473,26 @@ index bdf9c81..ffdee03 100644 - else() - list(INSERT TBB_PATH_SUFFIXES 0 lib/intel64/gcc4.4) - endif() -+ -+ if(NOT MSVC AND NOT TBB_LIBRARIES) -+ set(TBB_LIBRARIES ${TBB_LIBRARIES_RELEASE}) - endif() +- endif() -endif() ++ find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}${TBB_STATIC_SUFFIX}_debug ++ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} ++ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH ++ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX}) -if(UNIX AND TBB_USE_STATIC_LIBS) - set(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") -endif() -+ if (MSVC AND TBB_STATIC) -+ set(TBB_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE) -+ endif () -+ -+ unset (TBB_STATIC_SUFFIX) -+ -+ find_package_handle_standard_args(TBB -+ REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES -+ HANDLE_COMPONENTS -+ VERSION_VAR TBB_VERSION) -+ -+ ################################## -+ # Create targets -+ ################################## -+ -+ if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND) -+ add_library(TBB::tbb UNKNOWN IMPORTED) -+ set_target_properties(TBB::tbb PROPERTIES -+ INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS} -+ IMPORTED_LOCATION ${TBB_LIBRARIES}) -+ if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) -+ set_target_properties(TBB::tbb PROPERTIES -+ INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_DEBUG}>;$<$:${TBB_DEFINITIONS_RELEASE}>" -+ IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG} -+ IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_RELEASE} -+ IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE} -+ IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE} -+ ) -+ endif() ++ if(TBB_${_comp}_LIBRARY_DEBUG) ++ list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}") ++ endif() ++ if(TBB_${_comp}_LIBRARY_RELEASE) ++ list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}") ++ endif() ++ if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY) ++ set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}") ++ endif() -set(Tbb_LIB_COMPONENTS "") - @@ -1559,19 +1515,84 @@ index bdf9c81..ffdee03 100644 - # Extract the directory and apply the matched text (in brackets) - get_filename_component(Tbb_${COMPONENT}_DIR "${Tbb_${COMPONENT}_LIBRARY}" DIRECTORY) - set(Tbb_${COMPONENT}_LIBRARY "${Tbb_${COMPONENT}_DIR}/${CMAKE_MATCH_1}") -- endif() -+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") -+ find_package(Threads QUIET REQUIRED) -+ set_target_properties(TBB::tbb PROPERTIES INTERFACE_LINK_LIBRARIES "${CMAKE_DL_LIBS};Threads::Threads") ++ if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}") ++ set(TBB_${_comp}_FOUND TRUE) ++ else() ++ set(TBB_${_comp}_FOUND FALSE) + endif() ++ ++ # Mark internal variables as advanced ++ mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE) ++ mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG) ++ mark_as_advanced(TBB_${_comp}_LIBRARY) ++ endif() - endif() +- endif() ++ endforeach() - list(APPEND Tbb_LIB_COMPONENTS ${Tbb_${COMPONENT}_LIBRARY}) -- ++ ################################## ++ # Set compile flags and libraries ++ ################################## + - if(Tbb_${COMPONENT}_LIBRARY) - set(TBB_${COMPONENT}_FOUND TRUE) - else() - set(TBB_${COMPONENT}_FOUND FALSE) ++ set(TBB_DEFINITIONS_RELEASE "") ++ set(TBB_DEFINITIONS_DEBUG "TBB_USE_DEBUG=1") ++ ++ if(TBB_LIBRARIES_${TBB_BUILD_TYPE}) ++ set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") ++ endif() ++ ++ if(NOT MSVC AND NOT TBB_LIBRARIES) ++ set(TBB_LIBRARIES ${TBB_LIBRARIES_RELEASE}) + endif() +-endforeach() + +-if(UNIX AND TBB_USE_STATIC_LIBS) +- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +- unset(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +-endif() ++ set(TBB_DEFINITIONS "") ++ if (MSVC AND TBB_STATIC) ++ set(TBB_DEFINITIONS __TBB_NO_IMPLICIT_LINKAGE) ++ endif () ++ ++ unset (TBB_STATIC_SUFFIX) ++ ++ find_package_handle_standard_args(TBB ++ REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES ++ FAIL_MESSAGE "TBB library cannot be found. Consider set TBBROOT environment variable." ++ HANDLE_COMPONENTS ++ VERSION_VAR TBB_VERSION) ++ ++ ################################## ++ # Create targets ++ ################################## ++ ++ if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND) ++ add_library(TBB::tbb UNKNOWN IMPORTED) ++ set_target_properties(TBB::tbb PROPERTIES ++ INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS}" ++ INTERFACE_LINK_LIBRARIES "Threads::Threads;${CMAKE_DL_LIBS}" ++ INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS} ++ IMPORTED_LOCATION ${TBB_LIBRARIES}) ++ if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG) ++ set_target_properties(TBB::tbb PROPERTIES ++ INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS};$<$,$>:${TBB_DEFINITIONS_DEBUG}>;$<$:${TBB_DEFINITIONS_RELEASE}>" ++ IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG} ++ IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_RELEASE} ++ IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE} ++ IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE} ++ ) ++ endif() ++ endif() + +-# ------------------------------------------------------------------------ +-# Cache and set TBB_FOUND +-# ------------------------------------------------------------------------ + mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES) + + unset(TBB_ARCHITECTURE) @@ -1588,18 +1609,8 @@ index bdf9c81..ffdee03 100644 + message(STATUS " TBB_LIBRARIES_DEBUG = ${TBB_LIBRARIES_DEBUG}") + message(STATUS " TBB_DEFINITIONS_RELEASE = ${TBB_DEFINITIONS_RELEASE}") + message(STATUS " TBB_LIBRARIES_RELEASE = ${TBB_LIBRARIES_RELEASE}") - endif() --endforeach() ++ endif() --if(UNIX AND TBB_USE_STATIC_LIBS) -- set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) -- unset(_TBB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) --endif() -- --# ------------------------------------------------------------------------ --# Cache and set TBB_FOUND --# ------------------------------------------------------------------------ -- -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(TBB - FOUND_VAR TBB_FOUND From 89801f00c58a820e50511ba2429e911bd75244f9 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Wed, 30 Oct 2019 18:08:16 +0100 Subject: [PATCH 52/82] Add explicit ZLIB system package requirement on Unix systems. We already depended on that but is wasn't stated in the deps script. --- deps/deps-unix-common.cmake | 4 +++- deps/deps-windows.cmake | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index 0df535fc31..c6caab987c 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -7,6 +7,8 @@ else () set(TBB_MINGW_WORKAROUND "") endif () +find_package(ZLIB REQUIRED) + ExternalProject_Add(dep_tbb EXCLUDE_FROM_ALL 1 URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz" @@ -105,7 +107,7 @@ ExternalProject_Add(dep_blosc -DBUILD_STATIC=ON -DBUILD_TESTS=OFF -DBUILD_BENCHMARKS=OFF - -DPREFER_EXTERNAL_ZLIB=OFF + -DPREFER_EXTERNAL_ZLIB=ON PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch ) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 4f8bbc1ab5..3f722ea992 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -333,7 +333,7 @@ ExternalProject_Add(dep_openexr EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/openexr/openexr.git GIT_TAG v2.4.0 - DEPENDS + DEPENDS dep_zlib CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS From 844994885b074785b7142bb4b915187bc676161f Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Thu, 31 Oct 2019 15:05:45 +0100 Subject: [PATCH 53/82] Update doc/Dependencies.md --- doc/Dependencies.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/Dependencies.md b/doc/Dependencies.md index b4b0c348cb..3f6335cb73 100644 --- a/doc/Dependencies.md +++ b/doc/Dependencies.md @@ -1,6 +1,6 @@ # Dependency report for PrusaSlicer ## Possible dynamic linking on Linux -* zlib: This should not be even mentioned in our cmake scripts but due to a bug in the system libraries of gtk it has to be linked to PrusaSlicer. +* zlib: Strict dependency required from the system, linked dynamically. Many other libs depend on zlib. * wxWidgets: searches for wx-3.1 by default, but with cmake option `SLIC3R_WX_STABLE=ON` it will use wx-3.0 bundled with most distros. * libcurl * tbb @@ -10,13 +10,13 @@ * expat * openssl * nlopt -* gtest +* openvdb: This library depends on other libs, namely boost, zlib, openexr, blosc (not strictly), etc... ## External libraries in source tree * ad-mesh: Lots of customization, have to be bundled in the source tree. * avrdude: Like ad-mesh, many customization, need to be in the source tree. * clipper: An important library we have to have full control over it. We also have some slicer specific modifications. -* glu-libtess: This is an extract of the mesa/glu library not oficially available as a package. +* glu-libtess: This is an extract of the mesa/glu library not officially available as a package. * imgui: no packages for debian, author suggests using in the source tree * miniz: No packages, author suggests using in the source tree * qhull: libqhull-dev does not contain libqhullcpp => link errors. Until it is fixed, we will use the builtin version. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925540 @@ -29,5 +29,6 @@ * igl * nanosvg * agg +* catch2: Only Arch has packages for catch2, other distros at most catch (v1.x). Being strictly header only, we bundle this in the source tree. Used for the unit-test suites. From d632d91e798686a6e46abd7ba2a823eda7ac64ae Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 31 Oct 2019 15:05:39 +0100 Subject: [PATCH 54/82] WipeTower.cpp: The M220 B/R gcode is only emitted for Marlin firmware flavor The extended gcode is now only supported by Prusa (https://github.com/prusa3d/PrusaSlicer/issues/3114) A pull request https://github.com/MarlinFirmware/Marlin/pull/15739 aims to extend the gcode in upstream Marlin as well --- src/libslic3r/GCode/WipeTower.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index b464a39b82..73dc91c405 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -331,15 +331,18 @@ public: // Let the firmware back up the active speed override value. WipeTowerWriter& speed_override_backup() - { - m_gcode += "M220 B\n"; + { + // This is only supported by Prusa at this point (https://github.com/prusa3d/PrusaSlicer/issues/3114) + if (m_gcode_flavor == gcfMarlin) + m_gcode += "M220 B\n"; return *this; } // Let the firmware restore the active speed override value. WipeTowerWriter& speed_override_restore() { - m_gcode += "M220 R\n"; + if (m_gcode_flavor == gcfMarlin) + m_gcode += "M220 R\n"; return *this; } From 636e446da169940956a27e1d2fa0f240c8929adb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Oct 2019 16:40:38 +0100 Subject: [PATCH 55/82] ENABLE_THUMBNAIL_GENERATOR -> Changes to zoom factor and centering algorithm when rendering thumbnails --- src/slic3r/GUI/Camera.cpp | 102 +++++++++++++++++++++++++++++++++- src/slic3r/GUI/Camera.hpp | 17 ++++++ src/slic3r/GUI/GLCanvas3D.cpp | 15 ++++- src/slic3r/GUI/GLCanvas3D.hpp | 8 +++ 4 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 8e3a6d1f12..b5aac32ed1 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -1,7 +1,9 @@ #include "libslic3r/libslic3r.h" #include "Camera.hpp" +#if !ENABLE_THUMBNAIL_GENERATOR #include "3DScene.hpp" +#endif // !ENABLE_THUMBNAIL_GENERATOR #include "GUI_App.hpp" #include "AppConfig.hpp" @@ -22,6 +24,10 @@ namespace Slic3r { namespace GUI { const double Camera::DefaultDistance = 1000.0; +#if ENABLE_THUMBNAIL_GENERATOR +const double Camera::DefaultZoomToBoxMarginFactor = 1.0; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.1; +#endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; double Camera::FrustrumZMargin = 10.0; @@ -266,10 +272,18 @@ void Camera::apply_projection(const BoundingBoxf3& box) const glsafe(::glMatrixMode(GL_MODELVIEW)); } +#if ENABLE_THUMBNAIL_GENERATOR +void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) +#else void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h) +#endif // ENABLE_THUMBNAIL_GENERATOR { // Calculate the zoom factor needed to adjust the view around the given box. +#if ENABLE_THUMBNAIL_GENERATOR + double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h, margin_factor); +#else double zoom = calc_zoom_to_bounding_box_factor(box, canvas_w, canvas_h); +#endif // ENABLE_THUMBNAIL_GENERATOR if (zoom > 0.0) { m_zoom = zoom; @@ -278,6 +292,20 @@ void Camera::zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h) } } +#if ENABLE_THUMBNAIL_GENERATOR +void Camera::zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor) +{ + Vec3d center; + double zoom = calc_zoom_to_volumes_factor(volumes, canvas_w, canvas_h, center, margin_factor); + if (zoom > 0.0) + { + m_zoom = zoom; + // center view around the calculated center + m_target = center; + } +} +#endif // ENABLE_THUMBNAIL_GENERATOR + #if ENABLE_CAMERA_STATISTICS void Camera::debug_render() const { @@ -372,7 +400,11 @@ std::pair Camera::calc_tight_frustrum_zs_around(const BoundingBo return ret; } +#if ENABLE_THUMBNAIL_GENERATOR +double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor) const +#else double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const +#endif // ENABLE_THUMBNAIL_GENERATOR { double max_bb_size = box.max_size(); if (max_bb_size == 0.0) @@ -405,13 +437,15 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca double max_x = 0.0; double max_y = 0.0; +#if !ENABLE_THUMBNAIL_GENERATOR // margin factor to give some empty space around the box double margin_factor = 1.25; +#endif // !ENABLE_THUMBNAIL_GENERATOR for (const Vec3d& v : vertices) { // project vertex on the plane perpendicular to camera forward axis - Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2)); + Vec3d pos = v - bb_center; Vec3d proj_on_plane = pos - pos.dot(forward) * forward; // calculates vertex coordinate along camera xy axes @@ -431,6 +465,72 @@ double Camera::calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int ca return std::min((double)canvas_w / (2.0 * max_x), (double)canvas_h / (2.0 * max_y)); } +#if ENABLE_THUMBNAIL_GENERATOR +double Camera::calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor) const +{ + if (volumes.empty()) + return -1.0; + + // project the volumes vertices on a plane perpendicular to the camera forward axis + // then calculates the vertices coordinate on this plane along the camera xy axes + + // ensure that the view matrix is updated + apply_view_matrix(); + + Vec3d right = get_dir_right(); + Vec3d up = get_dir_up(); + Vec3d forward = get_dir_forward(); + + BoundingBoxf3 box; + for (const GLVolume* volume : volumes) + { + box.merge(volume->transformed_bounding_box()); + } + center = box.center(); + + double min_x = DBL_MAX; + double min_y = DBL_MAX; + double max_x = -DBL_MAX; + double max_y = -DBL_MAX; + + for (const GLVolume* volume : volumes) + { + const Transform3d& transform = volume->world_matrix(); + const TriangleMesh* hull = volume->convex_hull(); + if (hull == nullptr) + continue; + + for (const Vec3f& vertex : hull->its.vertices) + { + Vec3d v = transform * vertex.cast(); + + // project vertex on the plane perpendicular to camera forward axis + Vec3d pos = v - center; + Vec3d proj_on_plane = pos - pos.dot(forward) * forward; + + // calculates vertex coordinate along camera xy axes + double x_on_plane = proj_on_plane.dot(right); + double y_on_plane = proj_on_plane.dot(up); + + min_x = std::min(min_x, x_on_plane); + min_y = std::min(min_y, y_on_plane); + max_x = std::max(max_x, x_on_plane); + max_y = std::max(max_y, y_on_plane); + } + } + + center += 0.5 * (max_x + min_x) * right + 0.5 * (max_y + min_y) * up; + + double dx = margin_factor * (max_x - min_x); + double dy = margin_factor * (max_y - min_y); + + if ((dx == 0.0) || (dy == 0.0)) + return -1.0f; + + return std::min((double)canvas_w / dx, (double)canvas_h / dy); +} +#endif // ENABLE_THUMBNAIL_GENERATOR + void Camera::set_distance(double distance) const { m_distance = distance; diff --git a/src/slic3r/GUI/Camera.hpp b/src/slic3r/GUI/Camera.hpp index 839d0d6cf1..cb634138f2 100644 --- a/src/slic3r/GUI/Camera.hpp +++ b/src/slic3r/GUI/Camera.hpp @@ -2,6 +2,9 @@ #define slic3r_Camera_hpp_ #include "libslic3r/BoundingBox.hpp" +#if ENABLE_THUMBNAIL_GENERATOR +#include "3DScene.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR #include namespace Slic3r { @@ -10,6 +13,10 @@ namespace GUI { struct Camera { static const double DefaultDistance; +#if ENABLE_THUMBNAIL_GENERATOR + static const double DefaultZoomToBoxMarginFactor; + static const double DefaultZoomToVolumesMarginFactor; +#endif // ENABLE_THUMBNAIL_GENERATOR static double FrustrumMinZRange; static double FrustrumMinNearZ; static double FrustrumZMargin; @@ -90,7 +97,12 @@ public: void apply_view_matrix() const; void apply_projection(const BoundingBoxf3& box) const; +#if ENABLE_THUMBNAIL_GENERATOR + void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor); + void zoom_to_volumes(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToVolumesMarginFactor); +#else void zoom_to_box(const BoundingBoxf3& box, int canvas_w, int canvas_h); +#endif // ENABLE_THUMBNAIL_GENERATOR #if ENABLE_CAMERA_STATISTICS void debug_render() const; @@ -100,7 +112,12 @@ private: // returns tight values for nearZ and farZ plane around the given bounding box // the camera MUST be outside of the bounding box in eye coordinate of the given box std::pair calc_tight_frustrum_zs_around(const BoundingBoxf3& box) const; +#if ENABLE_THUMBNAIL_GENERATOR + double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h, double margin_factor = DefaultZoomToBoxMarginFactor) const; + double calc_zoom_to_volumes_factor(const GLVolumePtrs& volumes, int canvas_w, int canvas_h, Vec3d& center, double margin_factor = DefaultZoomToVolumesMarginFactor) const; +#else double calc_zoom_to_bounding_box_factor(const BoundingBoxf3& box, int canvas_w, int canvas_h) const; +#endif // ENABLE_THUMBNAIL_GENERATOR void set_distance(double distance) const; }; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cddae1f866..a49c772d39 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1119,6 +1119,10 @@ wxDEFINE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent); wxDEFINE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); +#if ENABLE_THUMBNAIL_GENERATOR +const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25; +#endif // ENABLE_THUMBNAIL_GENERATOR + GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar) : m_canvas(canvas) , m_context(nullptr) @@ -3623,7 +3627,7 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa } Camera camera; - camera.zoom_to_box(box, thumbnail_data.width, thumbnail_data.height); + camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_view_matrix(); camera.apply_projection(box); @@ -4086,12 +4090,21 @@ BoundingBoxf3 GLCanvas3D::_max_bounding_box(bool include_gizmos, bool include_be return bb; } +#if ENABLE_THUMBNAIL_GENERATOR +void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box, double margin_factor) +{ + const Size& cnv_size = get_canvas_size(); + m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height(), margin_factor); + m_dirty = true; +} +#else void GLCanvas3D::_zoom_to_box(const BoundingBoxf3& box) { const Size& cnv_size = get_canvas_size(); m_camera.zoom_to_box(box, cnv_size.get_width(), cnv_size.get_height()); m_dirty = true; } +#endif // ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::_refresh_if_shown_on_screen() { diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index fce4661a4e..850e851fa0 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -107,6 +107,10 @@ wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent); class GLCanvas3D { +#if ENABLE_THUMBNAIL_GENERATOR + static const double DefaultCameraZoomToBoxMarginFactor; +#endif // ENABLE_THUMBNAIL_GENERATOR + public: struct GCodePreviewVolumeIndex { @@ -646,7 +650,11 @@ private: BoundingBoxf3 _max_bounding_box(bool include_gizmos, bool include_bed_model) const; +#if ENABLE_THUMBNAIL_GENERATOR + void _zoom_to_box(const BoundingBoxf3& box, double margin_factor = DefaultCameraZoomToBoxMarginFactor); +#else void _zoom_to_box(const BoundingBoxf3& box); +#endif // ENABLE_THUMBNAIL_GENERATOR void _refresh_if_shown_on_screen(); From bf8fcabb29836321dc5252439cd1b4ead0e2537f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 31 Oct 2019 17:03:33 +0100 Subject: [PATCH 56/82] ENABLE_THUMBNAIL_GENERATOR -> Use orthographic camera when rendering thumbnails --- src/slic3r/GUI/Camera.cpp | 2 +- src/slic3r/GUI/GLCanvas3D.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index b5aac32ed1..94d673e82b 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -26,7 +26,7 @@ namespace GUI { const double Camera::DefaultDistance = 1000.0; #if ENABLE_THUMBNAIL_GENERATOR const double Camera::DefaultZoomToBoxMarginFactor = 1.0; -const double Camera::DefaultZoomToVolumesMarginFactor = 1.1; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.0; #endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index a49c772d39..4e36739ac0 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3627,6 +3627,7 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa } Camera camera; + camera.set_type(Camera::Ortho); camera.zoom_to_volumes(visible_volumes, thumbnail_data.width, thumbnail_data.height); camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height); camera.apply_view_matrix(); From 581bbc85d64c7949eeb2efb26e35c1a63af958a1 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 14 Oct 2019 16:23:03 +0200 Subject: [PATCH 57/82] deps: Fix boost build on MacOS --- deps/CMakeLists.txt | 2 +- deps/deps-macos.cmake | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 09e6c75982..49e8ee7bab 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -72,7 +72,7 @@ elseif (APPLE) message(FATAL_ERROR "Could not determine OS X SDK version. Please use -DCMAKE_OSX_DEPLOYMENT_TARGET=") endif () - message("OS X Deployment Target (inferred from default): ${DEP_OSX_TARGET}") + message("OS X Deployment Target (inferred from SDK): ${DEP_OSX_TARGET}") endif () include("deps-macos.cmake") diff --git a/deps/deps-macos.cmake b/deps/deps-macos.cmake index e6fca8a726..fc08c62903 100644 --- a/deps/deps-macos.cmake +++ b/deps/deps-macos.cmake @@ -6,7 +6,7 @@ set(DEP_WERRORS_SDK "-Werror=partial-availability -Werror=unguarded-availability set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON" "-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}" - "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}" + "-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEP_OSX_TARGET}" "-DCMAKE_CXX_FLAGS=${DEP_WERRORS_SDK}" "-DCMAKE_C_FLAGS=${DEP_WERRORS_SDK}" ) @@ -14,28 +14,27 @@ set(DEP_CMAKE_OPTS include("deps-unix-common.cmake") -set(DEP_BOOST_OSX_TARGET "") -if (CMAKE_OSX_DEPLOYMENT_TARGET) - set(DEP_BOOST_OSX_TARGET "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") -endif () - ExternalProject_Add(dep_boost EXCLUDE_FROM_ALL 1 - URL "https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz" - URL_HASH SHA256=bd0df411efd9a585e5a2212275f8762079fed8842264954675a4fddc46cfcf60 + URL "https://dl.bintray.com/boostorg/release/1.71.0/source/boost_1_71_0.tar.gz" + URL_HASH SHA256=96b34f7468f26a141f6020efb813f1a2f3dfb9797ecf76a7d7cbd843cc95f5bd BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./bootstrap.sh + --with-toolset=clang --with-libraries=system,iostreams,filesystem,thread,log,locale,regex "--prefix=${DESTDIR}/usr/local" BUILD_COMMAND ./b2 -j ${NPROC} --reconfigure + toolset=clang link=static variant=release threading=multi boost.locale.icu=off - "cflags=-fPIC ${DEP_BOOST_OSX_TARGET}" - "cxxflags=-fPIC ${DEP_BOOST_OSX_TARGET}" + "cflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" + "cxxflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" + "mflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" + "mmflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}" install INSTALL_COMMAND "" # b2 does that already ) From add2b34d0607d2ea25dc8b07245d343c30cee10e Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 14 Oct 2019 16:30:07 +0200 Subject: [PATCH 58/82] build: Fix linking on Mac OS with ASAN on --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b22f10016..b6d40a0346 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,6 +191,7 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP add_compile_options(-fsanitize=address -fno-omit-frame-pointer) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan") From 85b6c6d2dd68a0cf5054ad40c0687f5b1e7fb5d2 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 21 Oct 2019 17:14:08 +0200 Subject: [PATCH 59/82] doc: Add missing file in the Linux howto, fix #3071 --- doc/How to build - Linux et al.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/How to build - Linux et al.md b/doc/How to build - Linux et al.md index 715b1388b3..9206ae1ed2 100644 --- a/doc/How to build - Linux et al.md +++ b/doc/How to build - Linux et al.md @@ -2,7 +2,7 @@ # Building PrusaSlicer on UNIX/Linux PrusaSlicer uses the CMake build system and requires several dependencies. -The dependencies can be listed in `deps/deps-linux.cmake`, although they don't necessarily need to be as recent +The dependencies can be listed in `deps/deps-linux.cmake` and `deps/deps-unix-common.cmake`, although they don't necessarily need to be as recent as the versions listed - generally versions available on conservative Linux distros such as Debian stable or CentOS should suffice. Perl is not required any more. From d729315de389533103a1d6f298c34da3e86a6ff2 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Fri, 1 Nov 2019 10:51:26 +0100 Subject: [PATCH 60/82] Fix g-code export to permissionless filesystems Fix #2521 Fix #3102 --- src/libslic3r/utils.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 8d2a6a8662..678ad9ed28 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -424,14 +424,19 @@ int copy_file(const std::string &from, const std::string &to) static const auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write | boost::filesystem::group_read | boost::filesystem::others_read; // aka 644 // Make sure the file has correct permission both before and after we copy over it. - try { - if (boost::filesystem::exists(target)) - boost::filesystem::permissions(target, perms); - boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists); - boost::filesystem::permissions(target, perms); - } catch (std::exception & /* ex */) { + // NOTE: error_code variants are used here to supress expception throwing. + // Error code of permission() calls is ignored on purpose - if they fail, + // the copy_file() function will fail appropriately and we don't want the permission() + // calls to cause needless failures on permissionless filesystems (ie. FATs on SD cards etc.) + // or when the target file doesn't exist. + boost::system::error_code ec; + boost::filesystem::permissions(target, perms, ec); + boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec); + if (ec) { return -1; } + boost::filesystem::permissions(target, perms, ec); + return 0; } From f94f75d481c5739ceae297aa76aa5602920c642d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 1 Nov 2019 12:19:27 +0100 Subject: [PATCH 61/82] ENABLE_THUMBNAIL_GENERATOR -> Render thumbnails using shader --- src/slic3r/GUI/Camera.cpp | 4 ++-- src/slic3r/GUI/GLCanvas3D.cpp | 35 +++++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 94d673e82b..9fbabe930d 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -25,8 +25,8 @@ namespace GUI { const double Camera::DefaultDistance = 1000.0; #if ENABLE_THUMBNAIL_GENERATOR -const double Camera::DefaultZoomToBoxMarginFactor = 1.0; -const double Camera::DefaultZoomToVolumesMarginFactor = 1.0; +const double Camera::DefaultZoomToBoxMarginFactor = 1.025; +const double Camera::DefaultZoomToVolumesMarginFactor = 1.025; #endif // ENABLE_THUMBNAIL_GENERATOR double Camera::FrustrumMinZRange = 50.0; double Camera::FrustrumMinNearZ = 100.0; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4e36739ac0..f8e7b1f940 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3594,7 +3594,8 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) } #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT -static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) + +static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) { auto is_visible = [](const GLVolume& v) -> bool { @@ -3603,8 +3604,8 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa return ret; }; - static const float orange[] = { 0.99f, 0.49f, 0.26f }; - static const float gray[] = { 0.64f, 0.64f, 0.64f }; + static const GLfloat orange[] = { 0.923f, 0.504f, 0.264f, 1.0f }; + static const GLfloat gray[] = { 0.64f, 0.64f, 0.64f, 1.0f }; GLVolumePtrs visible_volumes; @@ -3634,17 +3635,31 @@ static void render_volumes_in_thumbnail(const GLVolumePtrs& volumes, ThumbnailDa camera.apply_projection(box); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); - glsafe(::glEnable(GL_LIGHTING)); glsafe(::glEnable(GL_DEPTH_TEST)); + shader.start_using(); + + GLint shader_id = shader.get_shader_program_id(); + GLint color_id = ::glGetUniformLocation(shader_id, "uniform_color"); + GLint print_box_detection_id = ::glGetUniformLocation(shader_id, "print_box.volume_detection"); + glcheck(); + + if (print_box_detection_id != -1) + glsafe(::glUniform1i(print_box_detection_id, 0)); + for (const GLVolume* vol : visible_volumes) { - glsafe(::glColor3fv((vol->printable && !vol->is_outside) ? orange : gray)); + if (color_id >= 0) + glsafe(::glUniform4fv(color_id, 1, (vol->printable && !vol->is_outside) ? orange : gray)); + else + glsafe(::glColor4fv((vol->printable && !vol->is_outside) ? orange : gray)); + vol->render(); } + shader.stop_using(); + glsafe(::glDisable(GL_DEPTH_TEST)); - glsafe(::glDisable(GL_LIGHTING)); } void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) @@ -3700,7 +3715,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); if (multisample) { @@ -3768,7 +3783,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne if (!thumbnail_data.is_valid()) return; - render_volumes_in_thumbnail(m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); #if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT @@ -4302,7 +4317,9 @@ void GLCanvas3D::_render_objects() const if (m_volumes.empty()) return; +#if !ENABLE_THUMBNAIL_GENERATOR glsafe(::glEnable(GL_LIGHTING)); +#endif // !ENABLE_THUMBNAIL_GENERATOR glsafe(::glEnable(GL_DEPTH_TEST)); m_camera_clipping_plane = m_gizmos.get_sla_clipping_plane(); @@ -4346,7 +4363,9 @@ void GLCanvas3D::_render_objects() const m_shader.stop_using(); m_camera_clipping_plane = ClippingPlane::ClipsNothing(); +#if !ENABLE_THUMBNAIL_GENERATOR glsafe(::glDisable(GL_LIGHTING)); +#endif // !ENABLE_THUMBNAIL_GENERATOR } void GLCanvas3D::_render_selection() const From 59c128d9fdcd602aecdf52337932c40e60bda13e Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 1 Nov 2019 15:13:05 +0100 Subject: [PATCH 62/82] Fix broken partial arrange --- src/libslic3r/Arrange.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index aed6e41f73..3fa7e1841a 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -375,7 +375,7 @@ public: for(unsigned idx = 0; idx < fixeditems.size(); ++idx) { Item& itm = fixeditems[idx]; - itm.markAsFixedInBin(0); + itm.markAsFixedInBin(itm.binId()); } m_pck.configure(m_pconf); From 91829f9a357c30b9a12141b11b46fa90694d2193 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Fri, 1 Nov 2019 10:56:39 +0100 Subject: [PATCH 63/82] Remove git update step from deps where patch is applied. --- deps/deps-unix-common.cmake | 45 +++---------- deps/deps-windows.cmake | 49 +++----------- deps/igl-mods.patch | 128 ------------------------------------ 3 files changed, 19 insertions(+), 203 deletions(-) delete mode 100644 deps/igl-mods.patch diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index c6caab987c..eae319efc6 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -61,42 +61,14 @@ ExternalProject_Add(dep_qhull -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local ${DEP_CMAKE_OPTS} - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch + UPDATE_COMMAND "" + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch ) -ExternalProject_Add(dep_libigl - EXCLUDE_FROM_ALL 1 - URL "https://github.com/libigl/libigl/archive/v2.0.0.tar.gz" - URL_HASH SHA256=42518e6b106c7209c73435fd260ed5d34edeb254852495b4c95dce2d95401328 - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local - -DLIBIGL_BUILD_PYTHON=OFF - -DLIBIGL_BUILD_TESTS=OFF - -DLIBIGL_BUILD_TUTORIALS=OFF - -DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC} - -DLIBIGL_WITHOUT_COPYLEFT=OFF - -DLIBIGL_WITH_CGAL=OFF - -DLIBIGL_WITH_COMISO=OFF - -DLIBIGL_WITH_CORK=OFF - -DLIBIGL_WITH_EMBREE=OFF - -DLIBIGL_WITH_MATLAB=OFF - -DLIBIGL_WITH_MOSEK=OFF - -DLIBIGL_WITH_OPENGL=OFF - -DLIBIGL_WITH_OPENGL_GLFW=OFF - -DLIBIGL_WITH_OPENGL_GLFW_IMGUI=OFF - -DLIBIGL_WITH_PNG=OFF - -DLIBIGL_WITH_PYTHON=OFF - -DLIBIGL_WITH_TETGEN=OFF - -DLIBIGL_WITH_TRIANGLE=OFF - -DLIBIGL_WITH_XML=OFF - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch -) - - ExternalProject_Add(dep_blosc EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/Blosc/c-blosc.git - GIT_TAG v1.17.0 + GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0 DEPENDS CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -108,13 +80,14 @@ ExternalProject_Add(dep_blosc -DBUILD_TESTS=OFF -DBUILD_BENCHMARKS=OFF -DPREFER_EXTERNAL_ZLIB=ON - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch + UPDATE_COMMAND "" + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch ) ExternalProject_Add(dep_openexr EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/openexr/openexr.git - GIT_TAG v2.4.0 + GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0 CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local -DBUILD_SHARED_LIBS=OFF @@ -123,12 +96,13 @@ ExternalProject_Add(dep_openexr -DPYILMBASE_ENABLE:BOOL=OFF -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF -DOPENEXR_BUILD_UTILS:BOOL=OFF + UPDATE_COMMAND "" ) ExternalProject_Add(dep_openvdb EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git - GIT_TAG v6.2.1 + GIT_TAG aebaf8d95be5e57fd33949281ec357db4a576c2e #v6.2.1 DEPENDS dep_blosc dep_openexr dep_tbb CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local @@ -142,5 +116,6 @@ ExternalProject_Add(dep_openvdb -DOPENVDB_CORE_STATIC=ON -DTBB_STATIC=ON -DOPENVDB_BUILD_VDB_PRINT=ON - PATCH_COMMAND ${GIT_EXECUTABLE} apply ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch + UPDATE_COMMAND "" + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch ) \ No newline at end of file diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 3f722ea992..514a90a9ec 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -226,7 +226,8 @@ ExternalProject_Add(dep_qhull -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_DEBUG_POSTFIX=d - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch + UPDATE_COMMAND "" + PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/qhull-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) @@ -243,41 +244,6 @@ endif () find_package(Git REQUIRED) -ExternalProject_Add(dep_libigl - EXCLUDE_FROM_ALL 1 - URL "https://github.com/libigl/libigl/archive/v2.0.0.tar.gz" - URL_HASH SHA256=42518e6b106c7209c73435fd260ed5d34edeb254852495b4c95dce2d95401328 - CMAKE_GENERATOR "${DEP_MSVC_GEN}" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local - -DLIBIGL_BUILD_PYTHON=OFF - -DLIBIGL_BUILD_TESTS=OFF - -DLIBIGL_BUILD_TUTORIALS=OFF - -DLIBIGL_USE_STATIC_LIBRARY=OFF #${DEP_BUILD_IGL_STATIC} - -DLIBIGL_WITHOUT_COPYLEFT=OFF - -DLIBIGL_WITH_CGAL=OFF - -DLIBIGL_WITH_COMISO=OFF - -DLIBIGL_WITH_CORK=OFF - -DLIBIGL_WITH_EMBREE=OFF - -DLIBIGL_WITH_MATLAB=OFF - -DLIBIGL_WITH_MOSEK=OFF - -DLIBIGL_WITH_OPENGL=OFF - -DLIBIGL_WITH_OPENGL_GLFW=OFF - -DLIBIGL_WITH_OPENGL_GLFW_IMGUI=OFF - -DLIBIGL_WITH_PNG=OFF - -DLIBIGL_WITH_PYTHON=OFF - -DLIBIGL_WITH_TETGEN=OFF - -DLIBIGL_WITH_TRIANGLE=OFF - -DLIBIGL_WITH_XML=OFF - -DCMAKE_POSITION_INDEPENDENT_CODE=ON - -DCMAKE_DEBUG_POSTFIX=d - PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/igl-mods.patch - BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj - INSTALL_COMMAND "" -) - -add_debug_dep(dep_libigl) - ExternalProject_Add(dep_wxwidgets EXCLUDE_FROM_ALL 1 GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets" @@ -306,7 +272,7 @@ ExternalProject_Add(dep_blosc #URL https://github.com/Blosc/c-blosc/archive/v1.17.0.zip #URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9 GIT_REPOSITORY https://github.com/Blosc/c-blosc.git - GIT_TAG v1.17.0 + GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0 DEPENDS dep_zlib CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" @@ -322,6 +288,7 @@ ExternalProject_Add(dep_blosc -DPREFER_EXTERNAL_ZLIB=ON -DBLOSC_IS_SUBPROJECT:BOOL=ON -DBLOSC_INSTALL:BOOL=ON + UPDATE_COMMAND "" PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" @@ -332,7 +299,7 @@ add_debug_dep(dep_blosc) ExternalProject_Add(dep_openexr EXCLUDE_FROM_ALL 1 GIT_REPOSITORY https://github.com/openexr/openexr.git - GIT_TAG v2.4.0 + GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0 DEPENDS dep_zlib CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" @@ -344,6 +311,7 @@ ExternalProject_Add(dep_openexr -DPYILMBASE_ENABLE:BOOL=OFF -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF -DOPENEXR_BUILD_UTILS:BOOL=OFF + UPDATE_COMMAND "" BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj INSTALL_COMMAND "" ) @@ -355,8 +323,8 @@ ExternalProject_Add(dep_openvdb #URL https://github.com/AcademySoftwareFoundation/openvdb/archive/v6.2.1.zip #URL_HASH SHA256=dc337399dce8e1c9f21f20e97b1ce7e4933cb0a63bb3b8b734d8fcc464aa0c48 GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git - GIT_TAG v6.2.1 - DEPENDS dep_blosc dep_openexr dep_tbb dep_boost + GIT_TAG aebaf8d95be5e57fd33949281ec357db4a576c2e #v6.2.1 + DEPENDS dep_blosc dep_openexr #dep_tbb dep_boost CMAKE_GENERATOR "${DEP_MSVC_GEN}" CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}" CMAKE_ARGS @@ -372,6 +340,7 @@ ExternalProject_Add(dep_openvdb -DTBB_STATIC=ON -DOPENVDB_BUILD_VDB_PRINT=ON BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj + UPDATE_COMMAND "" PATCH_COMMAND ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch INSTALL_COMMAND "" ) diff --git a/deps/igl-mods.patch b/deps/igl-mods.patch deleted file mode 100644 index b0ff9205d0..0000000000 --- a/deps/igl-mods.patch +++ /dev/null @@ -1,128 +0,0 @@ -diff --git a/cmake/libigl-config.cmake.in b/cmake/libigl-config.cmake.in -index 317c745c..f9808e1e 100644 ---- a/cmake/libigl-config.cmake.in -+++ b/cmake/libigl-config.cmake.in -@@ -2,28 +2,28 @@ - - include(${CMAKE_CURRENT_LIST_DIR}/libigl-export.cmake) - --if (TARGET igl::core) -- if (NOT TARGET Eigen3::Eigen) -- find_package(Eigen3 QUIET) -- if (NOT Eigen3_FOUND) -- # try with PkgCOnfig -- find_package(PkgConfig REQUIRED) -- pkg_check_modules(Eigen3 QUIET IMPORTED_TARGET eigen3) -- endif() -- -- if (NOT Eigen3_FOUND) -- message(FATAL_ERROR "Could not find required dependency Eigen3") -- set(libigl_core_FOUND FALSE) -- else() -- target_link_libraries(igl::core INTERFACE PkgConfig::Eigen3) -- set(libigl_core_FOUND TRUE) -- endif() -- else() -- target_link_libraries(igl::core INTERFACE Eigen3::Eigen) -- set(libigl_core_FOUND TRUE) -- endif() -- --endif() -+# if (TARGET igl::core) -+# if (NOT TARGET Eigen3::Eigen) -+# find_package(Eigen3 QUIET) -+# if (NOT Eigen3_FOUND) -+# # try with PkgCOnfig -+# find_package(PkgConfig REQUIRED) -+# pkg_check_modules(Eigen3 QUIET IMPORTED_TARGET eigen3) -+# endif() -+# -+# if (NOT Eigen3_FOUND) -+# message(FATAL_ERROR "Could not find required dependency Eigen3") -+# set(libigl_core_FOUND FALSE) -+# else() -+# target_link_libraries(igl::core INTERFACE PkgConfig::Eigen3) -+# set(libigl_core_FOUND TRUE) -+# endif() -+# else() -+# target_link_libraries(igl::core INTERFACE Eigen3::Eigen) -+# set(libigl_core_FOUND TRUE) -+# endif() -+# -+# endif() - - check_required_components(libigl) - -diff --git a/cmake/libigl.cmake b/cmake/libigl.cmake -index 4b11007a..47e6c395 100644 ---- a/cmake/libigl.cmake -+++ b/cmake/libigl.cmake -@@ -445,6 +445,7 @@ function(install_dir_files dir_name) - if(NOT LIBIGL_USE_STATIC_LIBRARY) - file(GLOB public_sources - ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.cpp -+ ${CMAKE_CURRENT_SOURCE_DIR}/include/igl${subpath}/*.c - ) - endif() - list(APPEND files_to_install ${public_sources}) -diff --git a/include/igl/AABB.cpp b/include/igl/AABB.cpp -index 09537335..92e90cb7 100644 ---- a/include/igl/AABB.cpp -+++ b/include/igl/AABB.cpp -@@ -1071,5 +1071,11 @@ template void igl::AABB, 3>::init, 2>::init >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&); - template double igl::AABB, 3>::squared_distance >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix const&, double, int&, Eigen::PlainObjectBase >&) const; -+template float igl::AABB const, 0, Eigen::Stride<0, 0> >, 3>::squared_distance const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Matrix const&, int&, Eigen::PlainObjectBase >&) const; - template bool igl::AABB, 3>::intersect_ray >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix const&, Eigen::Matrix const&, igl::Hit&) const; -+template bool igl::AABB, 3>::intersect_ray >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix const&, Eigen::Matrix const&, std::vector&) const; -+ -+template void igl::AABB const, 0, Eigen::Stride<0, 0> >, 3>::init const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&); -+ -+template bool igl::AABB const, 0, Eigen::Stride<0, 0> >, 3>::intersect_ray const, 0, Eigen::Stride<0, 0> > >(Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Matrix const&, Eigen::Matrix const&, std::vector >&) const; - #endif -diff --git a/include/igl/barycenter.cpp b/include/igl/barycenter.cpp -index 065f82aa..ec2d96cd 100644 ---- a/include/igl/barycenter.cpp -+++ b/include/igl/barycenter.cpp -@@ -54,4 +54,6 @@ template void igl::barycenter, Eigen::M - template void igl::barycenter, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); - template void igl::barycenter, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); - template void igl::barycenter, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); -+ -+template void igl::barycenter const, 0, Eigen::Stride<0, 0> >, Eigen::Map const, 0, Eigen::Stride<0, 0> >, Eigen::Matrix >(Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::PlainObjectBase >&); - #endif -diff --git a/include/igl/point_simplex_squared_distance.cpp b/include/igl/point_simplex_squared_distance.cpp -index 2b98bd28..c66d9ae1 100644 ---- a/include/igl/point_simplex_squared_distance.cpp -+++ b/include/igl/point_simplex_squared_distance.cpp -@@ -178,4 +178,6 @@ template void igl::point_simplex_squared_distance<3, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, double, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix::Index, double&, Eigen::MatrixBase >&, Eigen::PlainObjectBase >&); - template void igl::point_simplex_squared_distance<2, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, double, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix::Index, double&, Eigen::MatrixBase >&, Eigen::PlainObjectBase >&); - template void igl::point_simplex_squared_distance<2, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, double, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix::Index, double&, Eigen::MatrixBase >&, Eigen::PlainObjectBase >&); -+ -+template void igl::point_simplex_squared_distance<3, Eigen::Matrix, Eigen::Map const, 0, Eigen::Stride<0, 0> >, Eigen::Map const, 0, Eigen::Stride<0, 0> >, float, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::Map const, 0, Eigen::Stride<0, 0> >::Index, float&, Eigen::MatrixBase >&); - #endif -diff --git a/include/igl/ray_box_intersect.cpp b/include/igl/ray_box_intersect.cpp -index 4a88b89e..b547f8f8 100644 ---- a/include/igl/ray_box_intersect.cpp -+++ b/include/igl/ray_box_intersect.cpp -@@ -147,4 +147,6 @@ IGL_INLINE bool igl::ray_box_intersect( - #ifdef IGL_STATIC_LIBRARY - // Explicit template instantiation - template bool igl::ray_box_intersect, Eigen::Matrix, double>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::AlignedBox const&, double const&, double const&, double&, double&); -+ -+template bool igl::ray_box_intersect, Eigen::Matrix, float>(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::AlignedBox const&, float const&, float const&, float&, float&); - #endif -diff --git a/include/igl/ray_mesh_intersect.cpp b/include/igl/ray_mesh_intersect.cpp -index 9a70a22b..4233e722 100644 ---- a/include/igl/ray_mesh_intersect.cpp -+++ b/include/igl/ray_mesh_intersect.cpp -@@ -83,4 +83,7 @@ IGL_INLINE bool igl::ray_mesh_intersect( - template bool igl::ray_mesh_intersect, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, std::vector >&); - template bool igl::ray_mesh_intersect, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, igl::Hit&); - template bool igl::ray_mesh_intersect, Eigen::Matrix, Eigen::Matrix, Eigen::Block const, 1, -1, false> >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase const, 1, -1, false> > const&, igl::Hit&); -+template bool igl::ray_mesh_intersect, Eigen::Matrix, Eigen::Matrix, Eigen::Block const, 1, -1, false> >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase const, 1, -1, false> > const&, std::vector >&); -+ -+template bool igl::ray_mesh_intersect, Eigen::Matrix, Eigen::Map const, 0, Eigen::Stride<0, 0> >, Eigen::Block const, 0, Eigen::Stride<0, 0> > const, 1, -1, true> >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > > const&, Eigen::MatrixBase const, 0, Eigen::Stride<0, 0> > const, 1, -1, true> > const&, std::vector >&); - #endif From a72ac57fab54771ab583aa573086ef547ff53431 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 1 Nov 2019 19:59:09 +0100 Subject: [PATCH 64/82] adaptive elpehant foot compensation, fixing GH issues #1757 #2085 #2132 #2423 #2502 #2156 #2773 #2828 #2998 #3001 --- src/libslic3r/CMakeLists.txt | 2 + src/libslic3r/ClipperUtils.cpp | 16 + src/libslic3r/EdgeGrid.cpp | 6 +- src/libslic3r/EdgeGrid.hpp | 19 +- src/libslic3r/ElephantFootCompensation.cpp | 320 ++++++++++++++++++ src/libslic3r/ElephantFootCompensation.hpp | 16 + src/libslic3r/GCode.cpp | 2 +- src/libslic3r/Layer.cpp | 8 +- src/libslic3r/Polygon.cpp | 5 + src/libslic3r/Polygon.hpp | 2 +- src/libslic3r/PolygonTrimmer.cpp | 4 +- src/libslic3r/PrintObject.cpp | 47 +-- src/libslic3r/SVG.cpp | 4 + src/libslic3r/SVG.hpp | 10 +- tests/libslic3r/CMakeLists.txt | 2 +- .../test_elephant_foot_compensation.cpp | 304 +++++++++++++++++ 16 files changed, 715 insertions(+), 52 deletions(-) create mode 100644 src/libslic3r/ElephantFootCompensation.cpp create mode 100644 src/libslic3r/ElephantFootCompensation.hpp create mode 100644 tests/libslic3r/test_elephant_foot_compensation.cpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 8b162a1d58..0388b1ac03 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -22,6 +22,8 @@ add_library(libslic3r STATIC Config.hpp EdgeGrid.cpp EdgeGrid.hpp + ElephantFootCompensation.cpp + ElephantFootCompensation.hpp ExPolygon.cpp ExPolygon.hpp ExPolygonCollection.cpp diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 55bb4b446a..3db2f1f009 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -1060,6 +1060,22 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v } } +#if 0 + { + ClipperLib::Path polytmp(out); + unscaleClipperPolygon(polytmp); + Slic3r::Polygon offsetted = ClipperPath_to_Slic3rPolygon(polytmp); + BoundingBox bbox = get_extents(contour); + bbox.merge(get_extents(offsetted)); + static int iRun = 0; + SVG svg(debug_out_path("mittered_offset_path_scaled-%d.svg", iRun ++).c_str(), bbox); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + svg.draw_outline(offsetted, "red", scale_(0.01)); + svg.draw(contour, "blue", scale_(0.03)); + svg.draw((Points)offsetted, "blue", scale_(0.03)); + } +#endif + return out; } diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index 5e19c3b082..52ac4a0aa6 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -282,7 +282,11 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution) Visitor(std::vector> &cell_data, std::vector &cells, size_t cols) : cell_data(cell_data), cells(cells), cols(cols), i(0), j(0) {} - void operator()(coord_t iy, coord_t ix) { cell_data[cells[iy*cols + ix].end++] = std::pair(i, j); } + inline bool operator()(coord_t iy, coord_t ix) { + cell_data[cells[iy*cols + ix].end++] = std::pair(i, j); + // Continue traversing the grid along the edge. + return true; + } std::vector> &cell_data; std::vector &cells; diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp index 38a7d85428..92cee83629 100644 --- a/src/libslic3r/EdgeGrid.hpp +++ b/src/libslic3r/EdgeGrid.hpp @@ -25,6 +25,8 @@ public: void create(const ExPolygons &expolygons, coord_t resolution); void create(const ExPolygonCollection &expolygons, coord_t resolution); + const std::vector& contours() const { return m_contours; } + #if 0 // Test, whether the edges inside the grid intersect with the polygons provided. bool intersect(const MultiPoint &polyline, bool closed); @@ -77,7 +79,7 @@ public: std::vector> intersecting_edges() const; bool has_intersecting_edges() const; - template void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, FUNCTION func) const + template void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, VISITOR &visitor) const { // End points of the line segment. p1(0) -= m_bbox.min(0); @@ -94,8 +96,7 @@ public: assert(ixb >= 0 && size_t(ixb) < m_cols); assert(iyb >= 0 && size_t(iyb) < m_rows); // Account for the end points. - func(iy, ix); - if (ix == ixb && iy == iyb) + if (! visitor(iy, ix) || (ix == ixb && iy == iyb)) // Both ends fall into the same cell. return; // Raster the centeral part of the line. @@ -125,7 +126,8 @@ public: ey = int64_t(dx) * m_resolution; iy += 1; } - func(iy, ix); + if (! visitor(iy, ix)) + return; } while (ix != ixb || iy != iyb); } else { @@ -143,7 +145,8 @@ public: ey = int64_t(dx) * m_resolution; iy -= 1; } - func(iy, ix); + if (! visitor(iy, ix)) + return; } while (ix != ixb || iy != iyb); } } @@ -165,7 +168,8 @@ public: ey = int64_t(dx) * m_resolution; iy += 1; } - func(iy, ix); + if (! visitor(iy, ix)) + return; } while (ix != ixb || iy != iyb); } else { @@ -197,7 +201,8 @@ public: ey = int64_t(dx) * m_resolution; iy -= 1; } - func(iy, ix); + if (! visitor(iy, ix)) + return; } while (ix != ixb || iy != iyb); } } diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp new file mode 100644 index 0000000000..b23854f113 --- /dev/null +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -0,0 +1,320 @@ +#include "clipper/clipper_z.hpp" + +#include "libslic3r.h" +#include "EdgeGrid.hpp" +#include "ExPolygon.hpp" +#include "ElephantFootCompensation.hpp" +#include "Flow.hpp" +#include "Geometry.hpp" +#include "SVG.hpp" + +#include +#include + +// #define CONTOUR_DISTANCE_DEBUG_SVG + +namespace Slic3r { + +struct ResampledPoint { + ResampledPoint(size_t idx_src, bool interpolated, double curve_parameter) : idx_src(idx_src), interpolated(interpolated), curve_parameter(curve_parameter) {} + + size_t idx_src; + // Is this point interpolated or initial? + bool interpolated; + // Euclidean distance along the curve from the 0th point. + double curve_parameter; +}; + +std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx_contour, const Slic3r::Points &contour, const std::vector &resampled_point_parameters, double search_radius) +{ + assert(! contour.empty()); + assert(contour.size() >= 2); + + std::vector out; + + if (contour.size() > 2) + { +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + static int iRun = 0; + ++ iRun; + BoundingBox bbox = get_extents(contour); + bbox.merge(grid.bbox()); + ExPolygon expoly_grid; + expoly_grid.contour = Polygon(*grid.contours().front()); + for (size_t i = 1; i < grid.contours().size(); ++ i) + expoly_grid.holes.emplace_back(Polygon(*grid.contours()[i])); +#endif + struct Visitor { + Visitor(const EdgeGrid::Grid &grid, const size_t idx_contour, const std::vector &resampled_point_parameters, double dist_same_contour_reject) : + grid(grid), idx_contour(idx_contour), resampled_point_parameters(resampled_point_parameters), dist_same_contour_reject(dist_same_contour_reject) {} + + void init(const size_t aidx_point_start, const Point &apt_start, Vec2d dir, const double radius) { + this->idx_point_start = aidx_point_start; + this->pt = apt_start.cast() + SCALED_EPSILON * dir; + dir *= radius; + this->pt_start = this->pt.cast(); + // Trim the vector by the grid's bounding box. + const BoundingBox &bbox = this->grid.bbox(); + double t = 1.; + for (size_t axis = 0; axis < 2; ++ axis) { + double dx = std::abs(dir(axis)); + if (dx >= EPSILON) { + double tedge = (dir(axis) > 0) ? (double(bbox.max(axis)) - EPSILON - this->pt(axis)) : (this->pt(axis) - double(bbox.min(axis)) - EPSILON); + if (tedge < dx) + t = tedge / dx; + } + } + this->dir = dir; + if (t < 1.) + dir *= t; + this->pt_end = (this->pt + dir).cast(); + this->t_min = 1.; + } + + bool operator()(coord_t iy, coord_t ix) { + // Called with a row and colum of the grid cell, which is intersected by a line. + auto cell_data_range = this->grid.cell_data_range(iy, ix); + bool valid = true; + for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) { + // End points of the line segment and their vector. + auto segment = this->grid.segment(*it_contour_and_segment); + if (Geometry::segments_intersect(segment.first, segment.second, this->pt_start, this->pt_end)) { + // The two segments intersect. Calculate the intersection. + Vec2d pt2 = segment.first.cast(); + Vec2d dir2 = segment.second.cast() - pt2; + Vec2d vptpt2 = pt - pt2; + double denom = dir(0) * dir2(1) - dir2(0) * dir(1); + + if (std::abs(denom) >= EPSILON) { + double t = cross2(dir2, vptpt2) / denom; + assert(t > 0. && t <= 1.); + bool this_valid = true; + if (it_contour_and_segment->first == idx_contour) { + // The intersected segment originates from the same contour as the starting point. + // Reject the intersection if it is close to the starting point. + // Find the start and end points of this segment + double param_lo = resampled_point_parameters[idx_point_start].curve_parameter; + double param_hi; + double param_end = resampled_point_parameters.back().curve_parameter; + { + const Slic3r::Points &ipts = *grid.contours()[it_contour_and_segment->first]; + size_t ipt = it_contour_and_segment->second; + ResampledPoint key(ipt, false, 0.); + auto lower = [](const ResampledPoint& l, const ResampledPoint r) { return l.idx_src < r.idx_src || (l.idx_src == r.idx_src && int(l.interpolated) > int(r.interpolated)); }; + auto it = std::lower_bound(resampled_point_parameters.begin(), resampled_point_parameters.end(), key, lower); + assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); + double t2 = cross2(dir, vptpt2) / denom; + assert(t2 >= 0. && t2 <= 1.); + if (++ ipt == ipts.size()) + param_hi = t2 * dir2.norm(); + else + param_hi = it->curve_parameter + t2 * dir2.norm(); + } + if (param_lo > param_hi) + std::swap(param_lo, param_hi); + assert(param_lo >= 0. && param_lo <= param_end); + assert(param_hi >= 0. && param_hi <= param_end); + this_valid = param_hi > param_lo + dist_same_contour_reject && param_hi - param_end < param_lo - dist_same_contour_reject; + } + if (t < this->t_min) { + this->t_min = t; + valid = this_valid; + } + } + } + if (! valid) + this->t_min = 1.; + } + // Continue traversing the grid along the edge. + return true; + } + + const EdgeGrid::Grid &grid; + const size_t idx_contour; + const std::vector &resampled_point_parameters; + const double dist_same_contour_reject; + + size_t idx_point_start; + Point pt_start; + Point pt_end; + Vec2d pt; + Vec2d dir; + // Minium parameter along the vector (pt_end - pt_start). + double t_min; + } visitor(grid, idx_contour, resampled_point_parameters, search_radius); + + const Point *pt_this = &contour.back(); + size_t idx_pt_this = contour.size() - 1; + const Point *pt_prev = pt_this - 1; + // perpenduclar vector + auto perp = [](const Vec2d& v) -> Vec2d { return Vec2d(v.y(), -v.x()); }; + Vec2d vprev = (*pt_this - *pt_prev).cast().normalized(); + out.reserve(contour.size() + 1); + for (const Point &pt_next : contour) { + Vec2d vnext = (pt_next - *pt_this).cast().normalized(); + Vec2d dir = - (perp(vprev) + perp(vnext)).normalized(); + Vec2d dir_perp = perp(dir); + double cross = cross2(vprev, vnext); + double dot = vprev.dot(vnext); + double a = (cross < 0 || dot > 0.5) ? (M_PI / 3.) : (0.48 * acos(std::min(1., - dot))); + // Throw rays, collect distances. + std::vector distances; + int num_rays = 15; + +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + SVG svg(debug_out_path("contour_distance_raycasted-%d-%d.svg", iRun, &pt_next - contour.data()).c_str(), bbox); + svg.draw(expoly_grid); + svg.draw_outline(Polygon(contour), "blue", scale_(0.01)); + svg.draw(*pt_this, "red", scale_(0.1)); +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + + for (int i = - num_rays + 1; i < num_rays; ++ i) { + double angle = a * i / (int)num_rays; + double c = cos(angle); + double s = sin(angle); + Vec2d v = c * dir + s * dir_perp; + visitor.init(idx_pt_this, *pt_this, v, search_radius); + grid.visit_cells_intersecting_line(visitor.pt_start, visitor.pt_end, visitor); + distances.emplace_back(visitor.t_min); +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + svg.draw(Line(visitor.pt_start, visitor.pt_end), "yellow", scale_(0.01)); + if (visitor.t_min < 1.) { + Vec2d pt = visitor.pt + visitor.dir * visitor.t_min; + svg.draw(Point(pt), "red", scale_(0.1)); + } +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + } +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + svg.Close(); +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + std::sort(distances.begin(), distances.end()); +#if 0 + double median = distances[distances.size() / 2]; + double standard_deviation = 0; + for (double d : distances) + standard_deviation += (d - median) * (d - median); + standard_deviation = sqrt(standard_deviation / (distances.size() - 1)); + double avg = 0; + size_t cnt = 0; + for (double d : distances) + if (d > median - standard_deviation - EPSILON && d < median + standard_deviation + EPSILON) { + avg += d; + ++ cnt; + } + avg /= double(cnt); + out.emplace_back(float(avg * search_radius)); +#else + out.emplace_back(float(distances.front() * search_radius)); +#endif +#ifdef CONTOUR_DISTANCE_DEBUG_SVG + printf("contour_distance_raycasted-%d-%d.svg - distance %lf\n", iRun, &pt_next - contour.data(), unscale(out.back())); +#endif /* CONTOUR_DISTANCE_DEBUG_SVG */ + pt_this = &pt_next; + idx_pt_this = &pt_next - contour.data(); + vprev = vnext; + } + // Rotate the vector by one item. + out.emplace_back(out.front()); + out.erase(out.begin()); + } + + return out; +} + +Points resample_polygon(const Points &contour, double dist, std::vector &resampled_point_parameters) +{ + Points out; + out.reserve(contour.size()); + resampled_point_parameters.reserve(contour.size()); + if (contour.size() > 2) { + Vec2d pt_prev = contour.back().cast(); + for (const Point &pt : contour) { + size_t idx_this = &pt - contour.data(); + const Vec2d pt_this = pt.cast(); + const Vec2d v = pt_this - pt_prev; + const double l = v.norm(); + const size_t n = size_t(ceil(l / dist)); + const double l_step = l / n; + for (size_t i = 1; i < n; ++ i) { + double interpolation_parameter = double(i) / n; + Vec2d new_pt = pt_prev + v * interpolation_parameter; + out.emplace_back(new_pt.cast()); + resampled_point_parameters.emplace_back(idx_this, true, l_step); + } + out.emplace_back(pt); + resampled_point_parameters.emplace_back(idx_this, false, l_step); + pt_prev = pt_this; + } + for (size_t i = 1; i < resampled_point_parameters.size(); ++i) + resampled_point_parameters[i].curve_parameter += resampled_point_parameters[i - 1].curve_parameter; + } + return out; +} + +static inline void smooth_compensation(std::vector &compensation, float strength, size_t num_iterations) +{ + std::vector out(compensation); + for (size_t iter = 0; iter < num_iterations; ++ iter) { + for (size_t i = 0; i < compensation.size(); ++ i) { + float prev = (i == 0) ? compensation.back() : compensation[i - 1]; + float next = (i + 1 == compensation.size()) ? compensation.front() : compensation[i + 1]; + float laplacian = compensation[i] * (1.f - strength) + 0.5f * strength * (prev + next); + // Compensations are negative. Only apply the laplacian if it leads to lower compensation. + out[i] = std::max(laplacian, compensation[i]); + } + out.swap(compensation); + } +} + +ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &external_perimeter_flow, const double compensation) +{ + // The contour shall be wide enough to apply the external perimeter plus compensation on both sides. + double min_contour_width = double(external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing()); + double scaled_compensation = scale_(compensation); + double min_contour_width_compensated = min_contour_width + 2. * scaled_compensation; + // Make the search radius a bit larger for the averaging in contour_distance over a fan of rays to work. + double search_radius = min_contour_width_compensated + min_contour_width * 0.5; + + EdgeGrid::Grid grid; + ExPolygon simplified = input_expoly.simplify(SCALED_EPSILON).front(); + BoundingBox bbox = get_extents(simplified.contour); + bbox.offset(SCALED_EPSILON); + grid.set_bbox(bbox); + grid.create(simplified, coord_t(0.7 * search_radius)); + std::vector> deltas; + deltas.reserve(simplified.holes.size() + 1); + ExPolygon resampled(simplified); + for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) { + Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; + std::vector resampled_point_parameters; + poly.points = resample_polygon(poly.points, scale_(0.5), resampled_point_parameters); + std::vector dists = contour_distance(grid, idx_contour, poly.points, resampled_point_parameters, search_radius); + for (float &d : dists) { +// printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale(d)); + // Convert contour width to available compensation distance. + if (d < min_contour_width) + d = 0.f; + else if (d > min_contour_width_compensated) + d = - float(scaled_compensation); + else + d = - (d - float(min_contour_width)) / 2.f; + assert(d >= - float(scaled_compensation) && d <= 0.f); + } + smooth_compensation(dists, 0.4f, 10); + deltas.emplace_back(dists); + } + + ExPolygons out = variable_offset_inner_ex(resampled, deltas, 2.); + return out.front(); +} + +ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation) +{ + ExPolygons out; + out.reserve(input.size()); + for (const ExPolygon &expoly : input) + out.emplace_back(elephant_foot_compensation(expoly, external_perimeter_flow, compensation)); + return out; +} + +} // namespace Slic3r diff --git a/src/libslic3r/ElephantFootCompensation.hpp b/src/libslic3r/ElephantFootCompensation.hpp new file mode 100644 index 0000000000..0119df1af5 --- /dev/null +++ b/src/libslic3r/ElephantFootCompensation.hpp @@ -0,0 +1,16 @@ +#ifndef slic3r_ElephantFootCompensation_hpp_ +#define slic3r_ElephantFootCompensation_hpp_ + +#include "libslic3r.h" +#include + +namespace Slic3r { + +class Flow; + +ExPolygon elephant_foot_compensation(const ExPolygon &input, const Flow &external_perimeter_flow, const double compensation); +ExPolygons elephant_foot_compensation(const ExPolygons &input, const Flow &external_perimeter_flow, const double compensation); + +} // Slic3r + +#endif /* slic3r_ElephantFootCompensation_hpp_ */ diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 26d9c90f8a..26d2fc649d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -543,7 +543,7 @@ std::vector GCode::collect_layers_to_print(const PrintObjec //FIXME should we use the printing extruders instead? double gap_over_supports = object.config().support_material_contact_distance; // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports. - assert(gap_over_supports != 0. || object.config().support_material_synchronize_layers); + assert(! object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers); if (gap_over_supports != 0.) { gap_over_supports = std::max(0., gap_over_supports); // Not a soluble support, diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 74deabf3e7..53a7f2fc45 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -88,8 +88,12 @@ ExPolygons Layer::merged(float offset_scaled) const offset_scaled2 = float(- EPSILON); } Polygons polygons; - for (LayerRegion *layerm : m_regions) - append(polygons, offset(to_expolygons(layerm->slices.surfaces), offset_scaled)); + for (LayerRegion *layerm : m_regions) { + const PrintRegionConfig &config = layerm->region()->config(); + // Our users learned to bend Slic3r to produce empty volumes to act as subtracters. Only add the region if it is non-empty. + if (config.bottom_solid_layers > 0 || config.top_solid_layers > 0 || config.fill_density > 0. || config.perimeters > 0) + append(polygons, offset(to_expolygons(layerm->slices.surfaces), offset_scaled)); + } ExPolygons out = union_ex(polygons); if (offset_scaled2 != 0.f) out = offset_ex(out, offset_scaled2); diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index bd5ec3de50..e1e2991444 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -254,6 +254,11 @@ Point Polygon::point_projection(const Point &point) const return proj; } +BoundingBox get_extents(const Points &points) +{ + return BoundingBox(points); +} + BoundingBox get_extents(const Polygon &poly) { return poly.bounding_box(); diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 4d53e97e1c..8230b49f8a 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -70,7 +70,7 @@ public: inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; } inline bool operator!=(const Polygon &lhs, const Polygon &rhs) { return lhs.points != rhs.points; } - +extern BoundingBox get_extents(const Points &points); extern BoundingBox get_extents(const Polygon &poly); extern BoundingBox get_extents(const Polygons &polygons); extern BoundingBox get_extents_rotated(const Polygon &poly, double angle); diff --git a/src/libslic3r/PolygonTrimmer.cpp b/src/libslic3r/PolygonTrimmer.cpp index a2779b6667..2c4e06fc58 100644 --- a/src/libslic3r/PolygonTrimmer.cpp +++ b/src/libslic3r/PolygonTrimmer.cpp @@ -16,7 +16,7 @@ TrimmedLoop trim_loop(const Polygon &loop, const EdgeGrid::Grid &grid) struct Visitor { Visitor(const EdgeGrid::Grid &grid, const Slic3r::Point *pt_prev, const Slic3r::Point *pt_this) : grid(grid), pt_prev(pt_prev), pt_this(pt_this) {} - void operator()(coord_t iy, coord_t ix) { + bool operator()(coord_t iy, coord_t ix) { // Called with a row and colum of the grid cell, which is intersected by a line. auto cell_data_range = grid.cell_data_range(iy, ix); for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) { @@ -26,6 +26,8 @@ TrimmedLoop trim_loop(const Polygon &loop, const EdgeGrid::Grid &grid) // The two segments intersect. Add them to the output. } } + // Continue traversing the grid along the edge. + return true; } const EdgeGrid::Grid &grid; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index d87e63c273..b334b70fc7 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1,6 +1,7 @@ #include "Print.hpp" #include "BoundingBox.hpp" #include "ClipperUtils.hpp" +#include "ElephantFootCompensation.hpp" #include "Geometry.hpp" #include "I18N.hpp" #include "SupportMaterial.hpp" @@ -1769,6 +1770,7 @@ end: Layer *layer = m_layers[layer_id]; // Apply size compensation and perform clipping of multi-part objects. float delta = float(scale_(m_config.xy_size_compensation.value)); + //FIXME only apply the compensation if no raft is enabled. float elephant_foot_compensation = 0.f; if (layer_id == 0) elephant_foot_compensation = float(scale_(m_config.elefant_foot_compensation.value)); @@ -1789,19 +1791,8 @@ end: to_expolygons(std::move(layerm->slices.surfaces)) : offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta); // Apply the elephant foot compensation. - if (elephant_foot_compensation > 0) { - float elephant_foot_spacing = float(layerm->flow(frExternalPerimeter).scaled_elephant_foot_spacing()); - float external_perimeter_nozzle = float(scale_(this->print()->config().nozzle_diameter.get_at(layerm->region()->config().perimeter_extruder.value - 1))); - // Apply the elephant foot compensation by steps of 1/10 nozzle diameter. - float steps = std::ceil(elephant_foot_compensation / (0.1f * external_perimeter_nozzle)); - size_t nsteps = size_t(steps); - float step = elephant_foot_compensation / steps; - for (size_t i = 0; i < nsteps; ++ i) { - Polygons tmp = offset(expolygons, - step); - append(tmp, diff(to_polygons(expolygons), offset(offset_ex(expolygons, -elephant_foot_spacing - step), elephant_foot_spacing + step))); - expolygons = union_ex(tmp); - } - } + if (elephant_foot_compensation > 0) + expolygons = union_ex(Slic3r::elephant_foot_compensation(expolygons, layerm->flow(frExternalPerimeter), unscale(elephant_foot_compensation))); layerm->slices.set(std::move(expolygons), stInternal); } } else { @@ -1825,33 +1816,17 @@ end: layerm->slices.set(std::move(slices), stInternal); } } - if (delta < 0.f) { + if (delta < 0.f || elephant_foot_compensation > 0.f) { // Apply the negative XY compensation. - Polygons trimming = offset(layer->merged(float(EPSILON)), delta - float(EPSILON)); + Polygons trimming; + if (elephant_foot_compensation > 0.f) { + trimming = to_polygons(Slic3r::elephant_foot_compensation(offset_ex(layer->merged(float(EPSILON)), std::min(delta, 0.f) - float(EPSILON)), + layer->m_regions.front()->flow(frExternalPerimeter), unscale(elephant_foot_compensation))); + } else + trimming = offset(layer->merged(float(EPSILON)), delta - float(EPSILON)); for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) layer->m_regions[region_id]->trim_surfaces(trimming); } - if (elephant_foot_compensation > 0.f) { - // Apply the elephant foot compensation. - std::vector elephant_foot_spacing; - elephant_foot_spacing.reserve(layer->m_regions.size()); - float external_perimeter_nozzle = 0.f; - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) { - LayerRegion *layerm = layer->m_regions[region_id]; - elephant_foot_spacing.emplace_back(float(layerm->flow(frExternalPerimeter).scaled_elephant_foot_spacing())); - external_perimeter_nozzle += float(scale_(this->print()->config().nozzle_diameter.get_at(layerm->region()->config().perimeter_extruder.value - 1))); - } - external_perimeter_nozzle /= (float)layer->m_regions.size(); - // Apply the elephant foot compensation by steps of 1/10 nozzle diameter. - float steps = std::ceil(elephant_foot_compensation / (0.1f * external_perimeter_nozzle)); - size_t nsteps = size_t(steps); - float step = elephant_foot_compensation / steps; - for (size_t i = 0; i < nsteps; ++ i) { - Polygons trimming_polygons = offset(layer->merged(float(EPSILON)), - step - float(EPSILON)); - for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) - layer->m_regions[region_id]->elephant_foot_compensation_step(elephant_foot_spacing[region_id] + step, trimming_polygons); - } - } } // Merge all regions' slices to get islands, chain them by a shortest path. layer->make_slices(); diff --git a/src/libslic3r/SVG.cpp b/src/libslic3r/SVG.cpp index 03f55802ef..6e4b973eac 100644 --- a/src/libslic3r/SVG.cpp +++ b/src/libslic3r/SVG.cpp @@ -368,6 +368,10 @@ void SVG::export_expolygons(const char *path, const std::vector 0) + for (const ExPolygon &expoly : exp_with_attr.first) + svg.draw((Points)expoly, exp_with_attr.second.color_points, exp_with_attr.second.radius_points); svg.Close(); } diff --git a/src/libslic3r/SVG.hpp b/src/libslic3r/SVG.hpp index 3a56021963..c1b387554c 100644 --- a/src/libslic3r/SVG.hpp +++ b/src/libslic3r/SVG.hpp @@ -105,19 +105,25 @@ public: const std::string &color_contour, const std::string &color_holes, const coord_t outline_width = scale_(0.05), - const float fill_opacity = 0.5f) : + const float fill_opacity = 0.5f, + const std::string &color_points = "black", + const coord_t radius_points = 0) : color_fill (color_fill), color_contour (color_contour), color_holes (color_holes), outline_width (outline_width), - fill_opacity (fill_opacity) + fill_opacity (fill_opacity), + color_points (color_points), + radius_points (radius_points) {} std::string color_fill; std::string color_contour; std::string color_holes; + std::string color_points; coord_t outline_width; float fill_opacity; + coord_t radius_points; }; static void export_expolygons(const char *path, const std::vector> &expolygons_with_attributes); diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index c2a4b4f781..02764589b0 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -5,7 +5,7 @@ add_executable(${_TEST_NAME}_tests test_clipper_offset.cpp test_clipper_utils.cpp test_config.cpp -# test_elephant_foot_compensation.cpp + test_elephant_foot_compensation.cpp test_geometry.cpp test_polygon.cpp test_stl.cpp diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp new file mode 100644 index 0000000000..a1b893975e --- /dev/null +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -0,0 +1,304 @@ +#include + +#include +#include + +#include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/ElephantFootCompensation.hpp" +#include "libslic3r/ExPolygon.hpp" +#include "libslic3r/Flow.hpp" +#include "libslic3r/SVG.hpp" + +#include "libslic3r/VoronoiOffset.hpp" + +using namespace Slic3r; + +// #define TESTS_EXPORT_SVGS + +namespace Slic3r { + ClipperLib::Path mittered_offset_path_scaled(const Points& contour, const std::vector& deltas, double miter_limit); + + static Points mittered_offset_path_scaled_points(const Points& contour, const std::vector& deltas, double miter_limit) + { + Points out; + ClipperLib::Path scaled = mittered_offset_path_scaled(contour, deltas, miter_limit); + for (ClipperLib::IntPoint& pt : scaled) { + pt.X += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; + pt.Y += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; + pt.X >>= CLIPPER_OFFSET_POWER_OF_2; + pt.Y >>= CLIPPER_OFFSET_POWER_OF_2; + out.emplace_back(coord_t(pt.X), coord_t(pt.Y)); + } + return out; + } +} + +static ExPolygon spirograph_gear_1mm() +{ + ExPolygon out; + out.contour.points = { { 8989059, 1015976 }, { 9012502, 1051010 }, { 9224741, 1786512 }, { 9232060, 1811874 }, { 9222459, 2132217 }, { 10263301, 2241715 }, { 10318693, 1936696 }, { 10320603, 1926178 }, { 10680972, 1250945 }, { 10693399, 1227661 }, { 10723616, 1198273 }, { 11599898, 346008 }, { 11616108, 351267 }, { 12086183, 503769 }, { 12293780, 1708518 }, { 12300939, 1750061 }, { 12195899, 2508234 }, { 12192277, 2534378 }, { 12053161, 2823089 }, { 12959357, 3346344 }, { 13133980, 3090414 }, { 13140002, 3081589 }, { 13160830, 3065371 }, { 13764842, 2595047 }, { 13804400, 2580484 }, { 14951581, 2158173 }, { 14964243, 2169573 }, { 15331439, 2500198 }, { 15031347, 3685330 }, { 15020999, 3726196 }, { 14616409, 4376044 }, { 14602458, 4398453 }, { 14594311, 4405358 }, { 14358060, 4605591 }, { 14973020, 5452271 }, { 15245662, 5283768 }, { 15271287, 5277427 }, { 16014420, 5093552 }, { 16056481, 5096336 }, { 17276242, 5177094 }, { 17477040, 5628611 }, { 17483964, 5644181 }, { 16727991, 6604475 }, { 16701923, 6637589 }, { 16680060, 6652386 }, { 16046043, 7081528 }, { 16035789, 7084529 }, { 15738421, 7171570 }, { 15955998, 8195191 }, { 16273777, 8152008 }, { 16299760, 8156636 }, { 17053280, 8290848 }, { 17090572, 8310500 }, { 18172024, 8880417 }, { 18172024, 9391815 }, { 18134732, 9411467 }, { 17053280, 9981369 }, { 17027297, 9985997 }, { 16273777, 10120209 }, { 16263184, 10118770 }, { 15955998, 10077026 }, { 15738421, 11100647 }, { 16046043, 11190704 }, { 16067906, 11205502 }, { 16701923, 11634644 }, { 17457896, 12594938 }, { 17483964, 12628052 }, { 17283166, 13079569 }, { 17276242, 13095139 }, { 17234181, 13097923 }, { 16014420, 13178665 }, { 15988795, 13172324 }, { 15245662, 12988449 }, { 15236574, 12982832 }, { 14973020, 12819946 }, { 14358060, 13666641 }, { 14602458, 13873764 }, { 15007048, 14523627 }, { 15020999, 14546036 }, { 15321091, 15731152 }, { 15331439, 15772018 }, { 15318777, 15783419 }, { 14951581, 16114059 }, { 14912023, 16099496 }, { 13764842, 15677170 }, { 13744014, 15660952 }, { 13140002, 15190628 }, { 12959357, 14925887 }, { 12053161, 15449127 }, { 12187640, 15728230 }, { 12192277, 15737854 }, { 12297317, 16496013 }, { 12300939, 16522156 }, { 12093342, 17726920 }, { 12086183, 17768464 }, { 12069973, 17773722 }, { 11599898, 17926208 }, { 11569681, 17896820 }, { 10693399, 17044556 }, { 10333030, 16369337 }, { 10320603, 16346054 }, { 10263301, 16030502 }, { 9222459, 16140015 }, { 9231740, 16449664 }, { 9232060, 16460342 }, { 9019821, 17195859 }, { 9012502, 17221222 }, { 8332646, 18237183 }, { 8309203, 18272216 }, { 8292260, 18270438 }, { 7800922, 18218872 }, { 7347225, 17083700 }, { 7331580, 17044556 }, { 7276730, 16280940 }, { 7274839, 16254608 }, { 7350758, 15943314 }, { 6355663, 15619904 }, { 6238078, 15906603 }, { 6234023, 15916489 }, { 5741039, 16501967 }, { 5724040, 16522156 }, { 5688377, 16544630 }, { 4654144, 17196380 }, { 4639383, 17187857 }, { 4211318, 16940704 }, { 4258533, 15719288 }, { 4260162, 15677170 }, { 4520697, 14957214 }, { 4529681, 14932388 }, { 4725821, 14678955 }, { 3948022, 13978775 }, { 3716296, 14200317 }, { 3692552, 14211841 }, { 3003980, 14546036 }, { 2962267, 14552057 }, { 1752599, 14726654 }, { 1462059, 14326969 }, { 1452041, 14313187 }, { 1991943, 13216482 }, { 2010560, 13178665 }, { 2541453, 12627039 }, { 2559760, 12608017 }, { 2569167, 12602956 }, { 2841979, 12456177 }, { 2416404, 11500290 }, { 2114701, 11608368 }, { 2088313, 11609244 }, { 1323058, 11634644 }, { 1282503, 11623175 }, { 106399, 11290588 }, { 3546, 10807167 }, { -1, 10790497 }, { 32389, 10763526 }, { 971700, 9981369 }, { 996159, 9971434 }, { 1705482, 9683334 }, { 1716131, 9682534 }, { 2024962, 9659348 }, { 2024962, 8612869 }, { 1705482, 8588898 }, { 1681022, 8578963 }, { 971700, 8290848 }, { 939310, 8263878 }, { -1, 7481735 }, { 102852, 6998299 }, { 106399, 6981629 }, { 146954, 6970160 }, { 1323058, 6637589 }, { 1349446, 6638464 }, { 2114701, 6663849 }, { 2124758, 6667452 }, { 2416404, 6771927 }, { 2841979, 5816056 }, { 2559760, 5664200 }, { 2028867, 5112573 }, { 2010560, 5093552 }, { 1470658, 3996848 }, { 1452041, 3959030 }, { 1742580, 3559360 }, { 1752599, 3545578 }, { 1794312, 3551599 }, { 3003980, 3726196 }, { 3027724, 3737720 }, { 3716296, 4071915 }, { 3724020, 4079299 }, { 3948022, 4293442 }, { 4725822, 3593262 }, { 4536219, 3348276 }, { 4529681, 3339829 }, { 4269146, 2619873 }, { 4260162, 2595047 }, { 4212946, 1373645 }, { 4211318, 1331528 }, { 4226079, 1323005 }, { 4654144, 1075852 }, { 4689807, 1098325 }, { 5724040, 1750061 }, { 6217024, 2335539 }, { 6234023, 2355728 }, { 6355663, 2652329 }, { 7350759, 2328903 }, { 7277369, 2027985 }, { 7274839, 2017609 }, { 7329689, 1253993 }, { 7331580, 1227661 }, { 7785277, 92503 }, { 7800922, 53360 }, { 7817864, 51581 }, { 8309203, 0 } }; + out.holes.emplace_back(Slic3r::Points({ {8982039, 9119734}, {8675233, 9160126}, {8654832, 9168577}, {8368934, 9287003}, {8351415, 9300446}, {8105907, 9488831}, {7917523, 9734328}, {7904081, 9751846}, {7785658, 10037750}, {7777208, 10058151}, {7736814, 10364949}, {7733932, 10386841}, {7774325, 10693653}, {7777208, 10715546}, {7895630, 11001450}, {7904081, 11021851}, {8092464, 11267363}, {8105907, 11284882}, {8123425, 11298325}, {8368934, 11486710}, {8389335, 11495160}, {8675233, 11613571}, {8697126, 11616453}, {9003932, 11656845}, {9025825, 11653963}, {9332633, 11613571}, {9353034, 11605121}, {9638932, 11486710}, {9656451, 11473267}, {9901958, 11284882}, {10090343, 11039370}, {10103786, 11021851}, {10222209, 10735947}, {10230659, 10715546}, {10271050, 10408734}, {10273932, 10386841}, {10233541, 10080043}, {10230659, 10058151}, {10112236, 9772247}, {10103786, 9751846}, {9915401, 9506349}, {9901958, 9488831}, {9884439, 9475388}, {9638932, 9287003}, {9618531, 9278552}, {9332633, 9160126}, {9310740, 9157244}, {9003932, 9116852} })); + out.holes.emplace_back(Slic3r::Points({ {5301863, 6863631}, {4995055, 6904022}, {4974654, 6912473}, {4688756, 7030899}, {4671237, 7044342}, {4425731, 7232727}, {4237345, 7478225}, {4223903, 7495743}, {4105480, 7781646}, {4097030, 7802048}, {4056638, 8108859}, {4053756, 8130753}, {4094147, 8437550}, {4097030, 8459442}, {4215452, 8745346}, {4223903, 8765747}, {4412288, 9011259}, {4425731, 9028778}, {4443249, 9042221}, {4688756, 9230606}, {4709157, 9239057}, {4995055, 9357483}, {5016948, 9360365}, {5323756, 9400757}, {5345649, 9397875}, {5652456, 9357483}, {5672856, 9349032}, {5958755, 9230606}, {5976273, 9217163}, {6221782, 9028778}, {6410165, 8783266}, {6423608, 8765747}, {6542031, 8479843}, {6550481, 8459442}, {6590874, 8152645}, {6593757, 8130753}, {6553363, 7823941}, {6550481, 7802048}, {6432058, 7516144}, {6423608, 7495743}, {6235224, 7250245}, {6221782, 7232727}, {6204263, 7219284}, {5958755, 7030899}, {5938354, 7022448}, {5652456, 6904022}, {5630563, 6901140}, {5323756, 6860749} })); + out.holes.emplace_back(Slic3r::Points({ {10306044, 5682112}, {9999236, 5722504}, {9978835, 5730953}, {9692937, 5849365}, {9675418, 5862808}, {9429912, 6051194}, {9241527, 6296691}, {9228084, 6314209}, {9109661, 6600113}, {9101211, 6620514}, {9060819, 6927326}, {9057937, 6949219}, {9098329, 7256016}, {9101211, 7277909}, {9219634, 7563812}, {9228084, 7584214}, {9416469, 7829725}, {9429912, 7847245}, {9447431, 7860687}, {9692937, 8049073}, {9713338, 8057523}, {9999236, 8175949}, {10021129, 8178831}, {10327937, 8219223}, {10349830, 8216341}, {10656638, 8175949}, {10677039, 8167498}, {10962937, 8049073}, {10980456, 8035630}, {11225963, 7847245}, {11414346, 7601733}, {11427789, 7584214}, {11546212, 7298310}, {11554662, 7277909}, {11595056, 6971111}, {11597938, 6949219}, {11557544, 6642407}, {11554662, 6620514}, {11436239, 6334610}, {11427789, 6314209}, {11239406, 6068712}, {11225963, 6051194}, {11208444, 6037751}, {10962937, 5849365}, {10942536, 5840915}, {10656638, 5722504}, {10634745, 5719621}, {10327937, 5679230} })); + return out; +} + +// Contour from GH issue #2998. +static ExPolygon box_with_hole_close_to_wall() +{ + ExPolygon out; + out.contour.points = { { 20000000, 20000000}, { 0, 20000000}, { 0, 0}, { 20000000, 0} }; + out.holes.emplace_back(Slic3r::Points( { + { 9905173, 501406}, { 9895707, 501967}, { 9715853, 512640}, { 9706437, 513762}, { 9527531, 535071}, { 9518198, 536749}, { 9340868, 568619}, { 9331651, 570846}, { 9156521, 613166}, + { 9147452, 615935}, { 8975137, 668555}, { 8966248, 671857}, { 8797352, 734593}, { 8788674, 738416}, { 8623792, 811047}, { 8615356, 815377}, { 8455065, 897648}, { 8446900, 902470}, + { 8291765, 994093}, { 8283900, 999390}, { 8134465, 1100042}, { 8126928, 1105796}, { 7983719, 1215124}, { 7976536, 1221315}, { 7840055, 1338934}, { 7833251, 1345539}, { 7703977, 1471037}, + { 7697576, 1478034}, { 7575964, 1610970}, { 7569989, 1618333}, { 7456466, 1758240}, { 7450937, 1765944}, { 7345902, 1912331}, { 7340840, 1920349}, { 7244661, 2072701}, { 7240082, 2081005}, + { 7153097, 2238787}, { 7149019, 2247348}, { 7071534, 2410005}, { 7067970, 2418793}, { 7000257, 2585755}, { 6997220, 2594738}, { 6939517, 2765418}, { 6937018, 2774565}, + { 6889527, 2948365}, { 6887574, 2957644}, { 6850462, 3133951}, { 6849062, 3143330}, { 6822461, 3321526}, { 6821618, 3330971}, { 6805620, 3510430}, { 6805339, 3519909}, + { 6800000, 3700000}, { 6800281, 3709478}, { 6805620, 3889570}, { 6806462, 3899015}, { 6822461, 4078474}, { 6823861, 4087853}, { 6850462, 4266049}, { 6852415, 4275328}, + { 6889527, 4451636}, { 6892027, 4460783}, { 6939517, 4634582}, { 6942554, 4643565}, { 7000257, 4814245}, { 7003821, 4823033}, { 7071534, 4989995}, { 7075612, 4998556}, + { 7153097, 5161214}, { 7157675, 5169518}, { 7244661, 5327300}, { 7249723, 5335318}, { 7345902, 5487670}, { 7351430, 5495374}, { 7456466, 5641761}, { 7462440, 5649124}, + { 7575964, 5789031}, { 7582365, 5796027}, { 7703977, 5928963}, { 7710780, 5935568}, { 7840055, 6061067}, { 7847238, 6067257}, { 7983719, 6184877}, { 7991256, 6190631}, + { 8134465, 6299958}, { 8142330, 6305255}, { 8291765, 6405907}, { 8299930, 6410729}, { 8455065, 6502352}, { 8463501, 6506682}, { 8623792, 6588953}, { 8632470, 6592776}, + { 8797352, 6665407}, { 8806241, 6668708}, { 8975137, 6731445}, { 8984206, 6734214}, { 9156521, 6786834}, { 9165738, 6789061}, { 9340868, 6831381}, { 9350201, 6833058}, + { 9527531, 6864929}, { 9536947, 6866050}, { 9715853, 6887360}, { 9725319, 6887921}, { 9905173, 6898595}, { 10094827, 6898595}, { 10104293, 6898033}, { 10284147, 6887360}, + { 10293563, 6886238}, { 10472469, 6864929}, { 10481802, 6863251}, { 10659132, 6831381}, { 10668349, 6829154}, { 10843479, 6786834}, { 10852548, 6784065}, { 11024863, 6731445}, + { 11033752, 6728143}, { 11202648, 6665407}, { 11211326, 6661584}, { 11376208, 6588953}, { 11384644, 6584623}, { 11544935, 6502352}, { 11553100, 6497530}, { 11708235, 6405907}, + { 11716100, 6400610}, { 11865535, 6299958}, { 11873072, 6294204}, { 12016281, 6184877}, { 12023464, 6178686}, { 12159946, 6061067}, { 12166750, 6054461}, { 12296023, 5928963}, + { 12302424, 5921966}, { 12424036, 5789031}, { 12430011, 5781667}, { 12543534, 5641761}, { 12549062, 5634056}, { 12654099, 5487670}, { 12659161, 5479651}, { 12755340, 5327300}, + { 12759918, 5318995}, { 12846903, 5161214}, { 12850981, 5152653}, { 12928466, 4989995}, { 12932030, 4981208}, { 12999743, 4814245}, { 13002780, 4805262}, { 13060483, 4634582}, + { 13062983, 4625434}, { 13110474, 4451636}, { 13112427, 4442356}, { 13149538, 4266049}, { 13150938, 4256670}, { 13177540, 4078474}, { 13178382, 4069029}, { 13194380, 3889570}, + { 13194661, 3880092}, { 13200000, 3700000}, { 13199719, 3690521}, { 13194380, 3510430}, { 13193538, 3500985}, { 13177540, 3321526}, { 13176140, 3312147}, { 13149538, 3133951}, + { 13147585, 3124672}, { 13110474, 2948365}, { 13107974, 2939217}, { 13060483, 2765418}, { 13057446, 2756435}, { 12999743, 2585755}, { 12996179, 2576968}, { 12928466, 2410005}, + { 12924388, 2401444}, { 12846903, 2238787}, { 12842325, 2230482}, { 12755340, 2072701}, { 12750278, 2064682}, { 12654099, 1912331}, { 12648571, 1904626}, { 12543534, 1758240}, + { 12537559, 1750876}, { 12424036, 1610970}, { 12417635, 1603973}, { 12296023, 1471037}, { 12289219, 1464432}, { 12159946, 1338934}, { 12152763, 1332744}, { 12016281, 1215124}, + { 12008744, 1209370}, { 11865535, 1100042}, { 11857670, 1094745}, { 11708235, 994093}, { 11700070, 989271}, { 11544935, 897648}, { 11536499, 893318}, { 11376208, 811047}, + { 11367530, 807224}, { 11202648, 734593}, { 11193759, 731291}, { 11024863, 668555}, { 11015794, 665786}, { 10843479, 613166}, { 10834262, 610939}, { 10659132, 568619}, + { 10649799, 566941}, { 10472469, 535071}, { 10463053, 533950}, { 10284147, 512640}, { 10274681, 512078}, { 10094827, 501406} + })); + return out; +} + +// Contour from GH issue #2085. +static ExPolygon thin_ring() +{ + ExPolygon out; + out.contour.points = { + { 7805980, 147}, { 8182728, 9400}, { 8188694, 9840}, { 8564533, 37560}, { 8570470, 38292}, { 8944500, 84420}, { 8950394, 85443}, { 9321700, 149880}, + { 9327537, 151191}, { 9695240, 233760}, { 9701005, 235356}, { 10064220, 335870}, { 10069900, 337747}, { 10427740, 455960}, { 10433321, 458113}, { 10784930, 593740}, + { 10790399, 596164}, { 11134930, 748880}, { 11140273, 751570}, { 11476891, 921010}, { 11482096, 923959}, { 11810000, 1109720}, { 11815054, 1112921}, { 12133450, 1314540}, + { 12138341, 1317985}, { 12446450, 1534980}, { 12451166, 1538661}, { 12748270, 1770520}, { 12752800, 1774427}, { 13038160, 2020580}, { 13042492, 2024705}, { 13315430, 2284570}, + { 13575295, 2557508}, { 13579420, 2561840}, { 13825573, 2847201}, { 13829480, 2851730}, { 14061340, 3148834}, { 14065020, 3153550}, { 14282016, 3461660}, { 14285460, 3466550}, + { 14487080, 3784946}, { 14490280, 3790000}, { 14676041, 4117905}, { 14678990, 4123110}, { 14848430, 4459727}, { 14851120, 4465071}, { 15003836, 4809601}, { 15006260, 4815070}, + { 15141887, 5166679}, { 15144040, 5172261}, { 15262254, 5530100}, { 15264130, 5535780}, { 15364645, 5898995}, { 15366240, 5904761}, { 15448809, 6272464}, { 15450120, 6278301}, + { 15514557, 6649607}, { 15515580, 6655501}, { 15561709, 7029530}, { 15562441, 7035467}, { 15590160, 7411306}, { 15590600, 7417272}, { 15599853, 7794020}, { 15600000, 7800000}, + { 15590747, 8176748}, { 15590600, 8182728}, { 15562881, 8558567}, { 15562441, 8564533}, { 15516312, 8938563}, { 15515580, 8944500}, { 15451143, 9315806}, { 15450120, 9321700}, + { 15367551, 9689403}, { 15366240, 9695240}, { 15265725, 10058455}, { 15264130, 10064220}, { 15145916, 10422060}, { 15144040, 10427740}, { 15008413, 10779349}, { 15006260, 10784930}, + { 14853544, 11129461}, { 14851120, 11134930}, { 14681680, 11471548}, { 14678990, 11476891}, { 14493229, 11804795}, { 14490280, 11810000}, { 14288660, 12128396}, { 14285460, 12133450}, + { 14068464, 12441559}, { 14065020, 12446450}, { 13833160, 12743554}, { 13829480, 12748270}, { 13583327, 13033630}, { 13579420, 13038160}, { 13319555, 13311098}, { 13315430, 13315430}, + { 13311098, 13319555}, { 13038160, 13579420}, { 13033630, 13583327}, { 12748270, 13829480}, { 12743554, 13833160}, { 12446450, 14065020}, { 12441559, 14068464}, { 12133450, 14285460}, + { 12128396, 14288660}, { 11810000, 14490280}, { 11804795, 14493229}, { 11476891, 14678990}, { 11471548, 14681680}, { 11134930, 14851120}, { 11129461, 14853544}, { 10784930, 15006260}, + { 10779349, 15008413}, { 10427740, 15144040}, { 10422060, 15145916}, { 10064220, 15264130}, { 10058455, 15265725}, { 9695240, 15366240}, { 9689403, 15367551}, { 9321700, 15450120}, + { 9315806, 15451143}, { 8944500, 15515580}, { 8938563, 15516312}, { 8564533, 15562441}, { 8558567, 15562881}, { 8182728, 15590600}, { 8176748, 15590747}, { 7800000, 15600000}, + { 7794020, 15599853}, { 7417272, 15590600}, { 7411306, 15590160}, { 7035467, 15562441}, { 7029530, 15561709}, { 6655501, 15515580}, { 6649607, 15514557}, { 6278301, 15450120}, + { 6272464, 15448809}, { 5904761, 15366240}, { 5898995, 15364645}, { 5535780, 15264130}, { 5530100, 15262254}, { 5172261, 15144040}, { 5166679, 15141887}, { 4815070, 15006260}, + { 4809601, 15003836}, { 4465071, 14851120}, { 4459727, 14848430}, { 4123110, 14678990}, { 4117905, 14676041}, { 3790000, 14490280}, { 3784946, 14487080}, { 3466550, 14285460}, + { 3461660, 14282016}, { 3153550, 14065020}, { 3148834, 14061340}, { 2851730, 13829480}, { 2847201, 13825573}, { 2561840, 13579420}, { 2557508, 13575295}, { 2284570, 13315430}, + { 2024705, 13042492}, { 2020580, 13038160}, { 1774427, 12752800}, { 1770520, 12748270}, { 1538661, 12451166}, { 1534980, 12446450}, { 1317985, 12138341}, { 1314540, 12133450}, + { 1112921, 11815054}, { 1109720, 11810000}, { 923959, 11482096}, { 921010, 11476891}, { 751570, 11140273}, { 748880, 11134930}, { 596164, 10790399}, { 593740, 10784930}, + { 458113, 10433321}, { 455960, 10427740}, { 337747, 10069900}, { 335870, 10064220}, { 235356, 9701005}, { 233760, 9695240}, { 151191, 9327537}, { 149880, 9321700}, { 85443, 8950394}, + { 84420, 8944500}, { 38292, 8570470}, { 37560, 8564533}, { 9840, 8188694}, { 9400, 8182728}, { 147, 7805980}, { 0, 7800000}, { 9253, 7423252}, { 9400, 7417272}, { 37120, 7041433}, + { 37560, 7035467}, { 83688, 6661437}, { 84420, 6655501}, { 148858, 6284194}, { 149880, 6278301}, { 232450, 5910597}, { 233760, 5904761}, { 334275, 5541545}, { 335870, 5535780}, + { 454084, 5177940}, { 455960, 5172261}, { 591587, 4820651}, { 593740, 4815070}, { 746456, 4470539}, { 748880, 4465071}, { 918320, 4128453}, { 921010, 4123110}, { 1106772, 3795205}, + { 1109720, 3790000}, { 1311340, 3471604}, { 1314540, 3466550}, { 1531536, 3158441}, { 1534980, 3153550}, { 1766840, 2856446}, { 1770520, 2851730}, { 2016673, 2566370}, { 2020580, 2561840}, + { 2280445, 2288903}, { 2284570, 2284570}, { 2288903, 2280445}, { 2561840, 2020580}, { 2566370, 2016673}, { 2851730, 1770520}, { 2856446, 1766840}, { 3153550, 1534980}, { 3158441, 1531536}, + { 3466550, 1314540}, { 3471604, 1311340}, { 3790000, 1109720}, { 3795205, 1106772}, { 4123110, 921010}, { 4128453, 918320}, { 4465071, 748880}, { 4470539, 746456}, { 4815070, 593740}, + { 4820651, 591587}, { 5172261, 455960}, { 5177940, 454084}, { 5535780, 335870}, { 5541545, 334275}, { 5904761, 233760}, { 5910597, 232450}, { 6278301, 149880}, { 6284194, 148858}, + { 6655501, 84420}, { 6661437, 83688}, { 7035467, 37560}, { 7041433, 37120}, { 7417272, 9400}, { 7423252, 9253}, { 7800000, 0} + }; + out.holes.emplace_back(Slic3r::Points( { + { 7794921, 1002175}, { 7466441, 1010240}, { 7461374, 1010614}, { 7133685, 1034780}, { 7128642, 1035402}, { 6802534, 1075630}, { 6797528, 1076499}, { 6473790, 1132670}, + { 6468832, 1133784}, { 6148230, 1205780}, { 6143333, 1207135}, { 5826660, 1294770}, { 5821835, 1296364}, { 5509840, 1399430}, { 5505100, 1401259}, { 5198540, 1519510}, + { 5193895, 1521569}, { 4893501, 1654720}, { 4888962, 1657005}, { 4595471, 1804740}, { 4591050, 1807245}, { 4305150, 1969200}, { 4300857, 1971918}, { 4023260, 2147710}, + { 4019106, 2150636}, { 3750470, 2339831}, { 3746465, 2342956}, { 3487430, 2545110}, { 3483583, 2548429}, { 3234780, 2763050}, { 3231100, 2766553}, { 2993120, 2993120}, + { 2766553, 3231100}, { 2763050, 3234780}, { 2548429, 3483583}, { 2545110, 3487430}, { 2342956, 3746465}, { 2339831, 3750470}, { 2150636, 4019106}, { 2147710, 4023260}, + { 1971918, 4300857}, { 1969200, 4305150}, { 1807245, 4591050}, { 1804740, 4595471}, { 1657005, 4888962}, { 1654720, 4893501}, { 1521569, 5193895}, { 1519510, 5198540}, + { 1401259, 5505100}, { 1399430, 5509840}, { 1296364, 5821835}, { 1294770, 5826660}, { 1207135, 6143333}, { 1205780, 6148230}, { 1133784, 6468832}, { 1132670, 6473790}, + { 1076499, 6797528}, { 1075630, 6802534}, { 1035402, 7128642}, { 1034780, 7133685}, { 1010614, 7461374}, { 1010240, 7466441}, { 1002175, 7794921}, { 1002050, 7800000}, + { 1010115, 8128480}, { 1010240, 8133559}, { 1034406, 8461248}, { 1034780, 8466315}, { 1075008, 8792423}, { 1075630, 8797466}, { 1131802, 9121204}, { 1132670, 9126210}, + { 1204667, 9446812}, { 1205780, 9451770}, { 1293415, 9768443}, { 1294770, 9773340}, { 1397836, 10085335}, { 1399430, 10090160}, { 1517682, 10396721}, { 1519510, 10401461}, + { 1652661, 10701855}, { 1654720, 10706500}, { 1802456, 10999992}, { 1804740, 11004530}, { 1966696, 11290429}, { 1969200, 11294850}, { 2144992, 11572447}, { 2147710, 11576740}, + { 2336905, 11845376}, { 2339831, 11849530}, { 2541984, 12108564}, { 2545110, 12112570}, { 2759731, 12361373}, { 2763050, 12365220}, { 2989617, 12603200}, { 2993120, 12606880}, + { 2996800, 12610383}, { 3234780, 12836950}, { 3238628, 12840269}, { 3487430, 13054890}, { 3491436, 13058016}, { 3750470, 13260170}, { 3754624, 13263096}, { 4023260, 13452290}, + { 4027553, 13455008}, { 4305150, 13630800}, { 4309571, 13633304}, { 4595471, 13795260}, { 4600009, 13797544}, { 4893501, 13945280}, { 4898146, 13947339}, { 5198540, 14080490}, + { 5203280, 14082319}, { 5509840, 14200570}, { 5514665, 14202164}, { 5826660, 14305230}, { 5831557, 14306585}, { 6148230, 14394220}, { 6153188, 14395333}, { 6473790, 14467330}, + { 6478796, 14468199}, { 6802534, 14524370}, { 6807577, 14524992}, { 7133685, 14565220}, { 7138752, 14565594}, { 7466441, 14589760}, { 7471520, 14589885}, { 7800000, 14597950}, + { 7805079, 14597825}, { 8133559, 14589760}, { 8138626, 14589386}, { 8466315, 14565220}, { 8471358, 14564598}, { 8797466, 14524370}, { 8802472, 14523501}, { 9126210, 14467330}, + { 9131168, 14466217}, { 9451770, 14394220}, { 9456667, 14392865}, { 9773340, 14305230}, { 9778165, 14303636}, { 10090160, 14200570}, { 10094900, 14198741}, { 10401461, 14080490}, + { 10406106, 14078431}, { 10706500, 13945280}, { 10711038, 13942996}, { 11004530, 13795260}, { 11008951, 13792756}, { 11294850, 13630800}, { 11299143, 13628082}, { 11576740, 13452290}, + { 11580894, 13449364}, { 11849530, 13260170}, { 11853536, 13257044}, { 12112570, 13054890}, { 12116417, 13051571}, { 12365220, 12836950}, { 12368900, 12833447}, { 12606880, 12606880}, + { 12833447, 12368900}, { 12836950, 12365220}, { 13051571, 12116417}, { 13054890, 12112570}, { 13257044, 11853536}, { 13260170, 11849530}, { 13449364, 11580894}, { 13452290, 11576740}, + { 13628082, 11299143}, { 13630800, 11294850}, { 13792756, 11008951}, { 13795260, 11004530}, { 13942996, 10711038}, { 13945280, 10706500}, { 14078431, 10406106}, { 14080490, 10401461}, + { 14198741, 10094900}, { 14200570, 10090160}, { 14303636, 9778165}, { 14305230, 9773340}, { 14392865, 9456667}, { 14394220, 9451770}, { 14466217, 9131168}, { 14467330, 9126210}, + { 14523501, 8802472}, { 14524370, 8797466}, { 14564598, 8471358}, { 14565220, 8466315}, { 14589386, 8138626}, { 14589760, 8133559}, { 14597825, 7805079}, { 14597950, 7800000}, + { 14589885, 7471520}, { 14589760, 7466441}, { 14565594, 7138752}, { 14565220, 7133685}, { 14524992, 6807577}, { 14524370, 6802534}, { 14468199, 6478796}, { 14467330, 6473790}, + { 14395333, 6153188}, { 14394220, 6148230}, { 14306585, 5831557}, { 14305230, 5826660}, { 14202164, 5514665}, { 14200570, 5509840}, { 14082319, 5203280}, { 14080490, 5198540}, + { 13947339, 4898146}, { 13945280, 4893501}, { 13797544, 4600009}, { 13795260, 4595471}, { 13633304, 4309571}, { 13630800, 4305150}, { 13455008, 4027553}, { 13452290, 4023260}, + { 13263096, 3754624}, { 13260170, 3750470}, { 13058016, 3491436}, { 13054890, 3487430}, { 12840269, 3238628}, { 12836950, 3234780}, { 12610383, 2996800}, { 12606880, 2993120}, + { 12603200, 2989617}, { 12365220, 2763050}, { 12361373, 2759731}, { 12112570, 2545110}, { 12108564, 2541984}, { 11849530, 2339831}, { 11845376, 2336905}, { 11576740, 2147710}, + { 11572447, 2144992}, { 11294850, 1969200}, { 11290429, 1966696}, { 11004530, 1804740}, { 10999992, 1802456}, { 10706500, 1654720}, { 10701855, 1652661}, { 10401461, 1519510}, + { 10396721, 1517682}, { 10090160, 1399430}, { 10085335, 1397836}, { 9773340, 1294770}, { 9768443, 1293415}, { 9451770, 1205780}, { 9446812, 1204667}, { 9126210, 1132670}, + { 9121204, 1131802}, { 8797466, 1075630}, { 8792423, 1075008}, { 8466315, 1034780}, { 8461248, 1034406}, { 8133559, 1010240}, { 8128480, 1010115}, { 7800000, 1002050} + } )); + return out; +} + +SCENARIO("Elephant foot compensation", "[ElephantFoot]") { + + GIVEN("Large box") { + ExPolygon expoly( { {50000000, 50000000 }, { 0, 50000000 }, { 0, 0 }, { 50000000, 0 } } ); + WHEN("Compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.21f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_large_box.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + + GIVEN("Thin ring (GH issue #2085)") { + ExPolygon expoly = thin_ring(); + WHEN("Compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.25f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_thin_ring.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + +#if 0 + GIVEN("Varying inner offset") { + ExPolygon input = spirograph_gear_1mm().simplify(SCALED_EPSILON).front(); + ExPolygon output; + std::vector deltas(input.contour.points.size(), scale_(1.)); + output.contour.points = Slic3r::mittered_offset_path_scaled_points(input.contour.points, deltas, 2.); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("elephant_foot_compensation_0.svg").c_str(), get_extents(output)); + svg.draw(input, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif /* TESTS_EXPORT_SVGS */ + for (size_t i = 0; i <= deltas.size() / 2; ++ i) + deltas[i] = deltas[deltas.size() - i - 1] = scale_(1.) * double(i) / (0.5 * double(deltas.size())); + output.contour.points = Slic3r::mittered_offset_path_scaled_points(input.contour.points, deltas, 2.); +#ifdef TESTS_EXPORT_SVGS + { + SVG svg(debug_out_path("elephant_foot_compensation_varying.svg").c_str(), get_extents(output)); + svg.draw(input, "blue"); + svg.draw_outline(output, "black", coord_t(scale_(0.01))); + } +#endif /* TESTS_EXPORT_SVGS */ + } +#endif + + GIVEN("Rectangle with a narrow part sticking out") { + // Rectangle + ExPolygon expoly; + coord_t scaled_w = coord_t(scale_(10)); + expoly.contour.points = { { 0, 0 }, { 0, scaled_w, }, { scaled_w, scaled_w }, { scaled_w, 0 } }; + // Narrow part + ExPolygon expoly2; + coord_t scaled_h = coord_t(scale_(0.8)); + expoly2.contour.points = { { scaled_w - coord_t(SCALED_EPSILON), scaled_w / 2 }, { scaled_w - coord_t(SCALED_EPSILON), scaled_w / 2 + scaled_h, }, + { 2 * scaled_w, scaled_w / 2 + scaled_h }, { 2 * scaled_w, scaled_w / 2 } }; + // Rectangle with the narrow part. + expoly = union_ex({ expoly, expoly2 }).front(); + + WHEN("Partially compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.45f, 0.2f, 0.4f, false), 0.25f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_0.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + WHEN("Fully compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.35f, 0.2f, 0.4f, false), 0.17f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_1.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + + GIVEN("Box with hole close to wall (GH issue #2998)") { + ExPolygon expoly = box_with_hole_close_to_wall(); + WHEN("Compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.25f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_2.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + + GIVEN("Spirograph wheel") { + // Rectangle + ExPolygon expoly = spirograph_gear_1mm(); + + WHEN("Partially compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.45f, 0.2f, 0.4f, false), 0.25f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_2.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + WHEN("Fully compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.35f, 0.2f, 0.4f, false), 0.17f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_3.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + WHEN("Brutally compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.45f, 0.2f, 0.4f, false), 0.6f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_4.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } +} From c4a74fdfc54ae153ae47696ad15bbe30becfd2fe Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 1 Nov 2019 20:05:40 +0100 Subject: [PATCH 65/82] Fix of previous commit. --- tests/libslic3r/test_elephant_foot_compensation.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp index a1b893975e..7aa2a241e3 100644 --- a/tests/libslic3r/test_elephant_foot_compensation.cpp +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -9,8 +9,6 @@ #include "libslic3r/Flow.hpp" #include "libslic3r/SVG.hpp" -#include "libslic3r/VoronoiOffset.hpp" - using namespace Slic3r; // #define TESTS_EXPORT_SVGS From bb8d59391fdd21317a68e4b83c54fc3f3fe88c0a Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 1 Nov 2019 21:13:53 +0100 Subject: [PATCH 66/82] Fixed missing include --- src/libslic3r/ElephantFootCompensation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index b23854f113..5bdeaa9549 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -1,6 +1,7 @@ #include "clipper/clipper_z.hpp" #include "libslic3r.h" +#include "ClipperUtils.hpp" #include "EdgeGrid.hpp" #include "ExPolygon.hpp" #include "ElephantFootCompensation.hpp" From 4c735192ef5d5e58a1d634c90e4398a4eb0b3764 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 4 Nov 2019 11:26:36 +0100 Subject: [PATCH 67/82] Bugfixes of the new adaptive elephant foot compensation. --- src/libslic3r/ClipperUtils.cpp | 48 +++++++++++++--------- src/libslic3r/ElephantFootCompensation.cpp | 4 +- src/libslic3r/PrintObject.cpp | 5 ++- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 3db2f1f009..25100b22fe 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -951,6 +951,7 @@ ClipperLib::Paths fix_after_inner_offset(const ClipperLib::Path &input, ClipperL ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::vector &deltas, double miter_limit) { assert(contour.size() == deltas.size()); + #ifndef NDEBUG // Verify that the deltas are either all positive, or all negative. bool positive = false; @@ -986,7 +987,10 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v double lmin = *std::max_element(deltas.begin(), deltas.end()) * CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR; double l2min = lmin * lmin; // Minimum angle to consider two edges to be parallel. - double sin_min_parallel = EPSILON + 1. / double(CLIPPER_OFFSET_SCALE); + // Vojtech's estimate. +// const double sin_min_parallel = EPSILON + 1. / double(CLIPPER_OFFSET_SCALE); + // Implementation equal to Clipper. + const double sin_min_parallel = 1.; // Find the last point further from pt by l2min. Vec2d pt = contour.front().cast(); @@ -1012,8 +1016,12 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v if (l2 > l2min) break; } - if (j > ilast) + if (j > ilast) { + assert(i <= ilast); + // If the last edge is too short, merge it with the previous edge. + i = ilast; ptnext = contour.front().cast(); + } // Normal to the (ptnext - pt) segment. Vec2d nnext = perp(ptnext - pt).normalized(); @@ -1026,27 +1034,29 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v add_offset_point(pt + nprev * delta); add_offset_point(pt); add_offset_point(pt + nnext * delta); - } else if (convex < sin_min_parallel) { - // Nearly parallel. - add_offset_point((nprev.dot(nnext) > 0.) ? (pt + nprev * delta) : pt); } else { - // Convex corner double dot = nprev.dot(nnext); - double r = 1. + dot; - if (r >= miter_limit) - add_offset_point(pt + (nprev + nnext) * (delta / r)); - else { - double dx = std::tan(std::atan2(sin_a, dot) / 4.); - Vec2d newpt1 = pt + (nprev - perp(nprev) * dx) * delta; - Vec2d newpt2 = pt + (nnext + perp(nnext) * dx) * delta; + if (convex < sin_min_parallel && dot > 0.) { + // Nearly parallel. + add_offset_point((nprev.dot(nnext) > 0.) ? (pt + nprev * delta) : pt); + } else { + // Convex corner, possibly extremely sharp if convex < sin_min_parallel. + double r = 1. + dot; + if (r >= miter_limit) + add_offset_point(pt + (nprev + nnext) * (delta / r)); + else { + double dx = std::tan(std::atan2(sin_a, dot) / 4.); + Vec2d newpt1 = pt + (nprev - perp(nprev) * dx) * delta; + Vec2d newpt2 = pt + (nnext + perp(nnext) * dx) * delta; #ifndef NDEBUG - Vec2d vedge = 0.5 * (newpt1 + newpt2) - pt; - double dist_norm = vedge.norm(); - assert(std::abs(dist_norm - delta) < EPSILON); + Vec2d vedge = 0.5 * (newpt1 + newpt2) - pt; + double dist_norm = vedge.norm(); + assert(std::abs(dist_norm - std::abs(delta)) < SCALED_EPSILON); #endif /* NDEBUG */ - add_offset_point(newpt1); - add_offset_point(newpt2); - } + add_offset_point(newpt1); + add_offset_point(newpt2); + } + } } if (i == ilast) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 5bdeaa9549..8b3dda8ae8 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -88,7 +88,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx if (std::abs(denom) >= EPSILON) { double t = cross2(dir2, vptpt2) / denom; - assert(t > 0. && t <= 1.); + assert(t > - EPSILON && t < 1. + EPSILON); bool this_valid = true; if (it_contour_and_segment->first == idx_contour) { // The intersected segment originates from the same contour as the starting point. @@ -105,7 +105,7 @@ std::vector contour_distance(const EdgeGrid::Grid &grid, const size_t idx auto it = std::lower_bound(resampled_point_parameters.begin(), resampled_point_parameters.end(), key, lower); assert(it != resampled_point_parameters.end() && it->idx_src == ipt && ! it->interpolated); double t2 = cross2(dir, vptpt2) / denom; - assert(t2 >= 0. && t2 <= 1.); + assert(t2 > - EPSILON && t2 < 1. + EPSILON); if (++ ipt == ipts.size()) param_hi = t2 * dir2.norm(); else diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index b334b70fc7..d717fe8724 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1819,11 +1819,12 @@ end: if (delta < 0.f || elephant_foot_compensation > 0.f) { // Apply the negative XY compensation. Polygons trimming; + static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); if (elephant_foot_compensation > 0.f) { - trimming = to_polygons(Slic3r::elephant_foot_compensation(offset_ex(layer->merged(float(EPSILON)), std::min(delta, 0.f) - float(EPSILON)), + trimming = to_polygons(Slic3r::elephant_foot_compensation(offset_ex(layer->merged(eps), std::min(delta, 0.f) - eps), layer->m_regions.front()->flow(frExternalPerimeter), unscale(elephant_foot_compensation))); } else - trimming = offset(layer->merged(float(EPSILON)), delta - float(EPSILON)); + trimming = offset(layer->merged(float(SCALED_EPSILON)), delta - float(SCALED_EPSILON)); for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) layer->m_regions[region_id]->trim_surfaces(trimming); } From 239957095003735ca9614e413a0d82ac67ddbd03 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 4 Nov 2019 11:34:33 +0100 Subject: [PATCH 68/82] Only enable Elphant foot compensation if printing directly on the print bed (raft is disabled). --- src/libslic3r/PrintObject.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index d717fe8724..c4ca46a8c5 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1772,7 +1772,8 @@ end: float delta = float(scale_(m_config.xy_size_compensation.value)); //FIXME only apply the compensation if no raft is enabled. float elephant_foot_compensation = 0.f; - if (layer_id == 0) + if (layer_id == 0 && m_config.raft_layers == 0) + // Only enable Elephant foot compensation if printing directly on the print bed. elephant_foot_compensation = float(scale_(m_config.elefant_foot_compensation.value)); if (layer->m_regions.size() == 1) { // Optimized version for a single region layer. From 3d450df680eee9a9e5fd786fc3ea436be03f2eff Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 11:59:23 +0100 Subject: [PATCH 69/82] ENABLE_THUMBNAIL_GENERATOR -> Transparent background for thumbnails saved into .3mf --- src/slic3r/GUI/GLCanvas3D.cpp | 22 ++++++++++++++-------- src/slic3r/GUI/GLCanvas3D.hpp | 8 ++++---- src/slic3r/GUI/Plater.cpp | 14 +++++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index f8e7b1f940..7d58f3c091 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1651,12 +1651,12 @@ void GLCanvas3D::render() } #if ENABLE_THUMBNAIL_GENERATOR -void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { if (GLCanvas3DManager::are_framebuffers_supported()) - _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only); + _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); else - _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only); + _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3595,7 +3595,7 @@ static void debug_output_thumbnail(const ThumbnailData& thumbnail_data) #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT -static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only) +static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volumes, ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool transparent_background) { auto is_visible = [](const GLVolume& v) -> bool { @@ -3634,6 +3634,9 @@ static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volu camera.apply_view_matrix(); camera.apply_projection(box); + if (transparent_background) + glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 0.0f)); + glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glEnable(GL_DEPTH_TEST)); @@ -3660,9 +3663,12 @@ static void render_volumes_in_thumbnail(Shader& shader, const GLVolumePtrs& volu shader.stop_using(); glsafe(::glDisable(GL_DEPTH_TEST)); + + if (transparent_background) + glsafe(::glClearColor(1.0f, 1.0f, 1.0f, 1.0f)); } -void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { thumbnail_data.set(w, h); if (!thumbnail_data.is_valid()) @@ -3715,7 +3721,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { - render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); if (multisample) { @@ -3766,7 +3772,7 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un glsafe(::glDisable(GL_MULTISAMPLE)); } -void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { // check that thumbnail size does not exceed the default framebuffer size const Size& cnv_size = get_canvas_size(); @@ -3783,7 +3789,7 @@ void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigne if (!thumbnail_data.is_valid()) return; - render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only); + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); #if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 850e851fa0..9f8d9d228f 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -529,7 +529,7 @@ public: #if ENABLE_THUMBNAIL_GENERATOR // printable_only == false -> render also non printable volumes as grayed // parts_only == false -> render also sla support and pad - void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void select_all(); @@ -684,9 +684,9 @@ private: void _render_undo_redo_stack(const bool is_undo, float pos_x); #if ENABLE_THUMBNAIL_GENERATOR // render thumbnail using an off-screen framebuffer - void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); - // render thumbnail using the default framebuffer - void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + // render thumbnail using the default framebuffer + void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void _update_volumes_hover_state() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 464093712e..939af16521 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1928,7 +1928,7 @@ struct Plater::priv bool can_reload_from_disk() const; #if ENABLE_THUMBNAIL_GENERATOR - void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only); + void generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR void msw_rescale_object_menu(); @@ -3057,7 +3057,7 @@ bool Plater::priv::restart_background_process(unsigned int state) for (const std::pair& size : THUMBNAIL_SIZE_FFF) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); } } else if (this->printer_technology == ptSLA) @@ -3068,7 +3068,7 @@ bool Plater::priv::restart_background_process(unsigned int state) for (const std::pair& size : THUMBNAIL_SIZE_SLA) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, true, false); } } } @@ -3422,7 +3422,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) for (const std::pair& size : THUMBNAIL_SIZE_SLA) { this->thumbnail_data.push_back(ThumbnailData()); - generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false); + generate_thumbnail(this->thumbnail_data.back(), size.first, size.second, true, false, false); } } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3653,9 +3653,9 @@ bool Plater::priv::init_object_menu() } #if ENABLE_THUMBNAIL_GENERATOR -void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only) +void Plater::priv::generate_thumbnail(ThumbnailData& data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { - view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only); + view3D->get_canvas3d()->render_thumbnail(data, w, h, printable_only, parts_only, transparent_background); } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -4699,7 +4699,7 @@ void Plater::export_3mf(const boost::filesystem::path& output_path) wxBusyCursor wait; #if ENABLE_THUMBNAIL_GENERATOR ThumbnailData thumbnail_data; - p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true); + p->generate_thumbnail(thumbnail_data, THUMBNAIL_SIZE_3MF.first, THUMBNAIL_SIZE_3MF.second, false, true, true); if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr, &thumbnail_data)) { #else if (Slic3r::store_3mf(path_u8.c_str(), &p->model, export_config ? &cfg : nullptr)) { From 3321ae7f131d3de3427bd370e81b8915add4a26c Mon Sep 17 00:00:00 2001 From: Stephan Reichhelm Date: Tue, 7 May 2019 19:51:14 +0200 Subject: [PATCH 70/82] + add FlashAir support for host upload --- src/libslic3r/PrintConfig.cpp | 2 + src/libslic3r/PrintConfig.hpp | 3 +- src/slic3r/CMakeLists.txt | 2 + src/slic3r/Utils/FlashAir.cpp | 220 +++++++++++++++++++++++++++++++++ src/slic3r/Utils/FlashAir.hpp | 44 +++++++ src/slic3r/Utils/PrintHost.cpp | 2 + 6 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 src/slic3r/Utils/FlashAir.cpp create mode 100644 src/slic3r/Utils/FlashAir.hpp diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 33105bff30..e639a6734d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1327,8 +1327,10 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("octoprint"); def->enum_values.push_back("duet"); + def->enum_values.push_back("flashair"); def->enum_labels.push_back("OctoPrint"); def->enum_labels.push_back("Duet"); + def->enum_labels.push_back("FlashAir"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(htOctoPrint)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 5c287ba93e..4b007fc51c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -30,7 +30,7 @@ enum GCodeFlavor : unsigned char { }; enum PrintHostType { - htOctoPrint, htDuet + htOctoPrint, htDuet, htFlashAir }; enum InfillPattern { @@ -102,6 +102,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum::g if (keys_map.empty()) { keys_map["octoprint"] = htOctoPrint; keys_map["duet"] = htDuet; + keys_map["flashair"] = htFlashAir; } return keys_map; } diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 17b76e6296..84a60da6ec 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -144,6 +144,8 @@ set(SLIC3R_GUI_SOURCES Utils/OctoPrint.hpp Utils/Duet.cpp Utils/Duet.hpp + Utils/FlashAir.cpp + Utils/FlashAir.hpp Utils/PrintHost.cpp Utils/PrintHost.hpp Utils/Bonjour.cpp diff --git a/src/slic3r/Utils/FlashAir.cpp b/src/slic3r/Utils/FlashAir.cpp new file mode 100644 index 0000000000..d7b97fc54b --- /dev/null +++ b/src/slic3r/Utils/FlashAir.cpp @@ -0,0 +1,220 @@ +#include "FlashAir.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "libslic3r/PrintConfig.hpp" +#include "slic3r/GUI/GUI.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/MsgDialog.hpp" +#include "Http.hpp" + +namespace fs = boost::filesystem; +namespace pt = boost::property_tree; + +namespace Slic3r { + +FlashAir::FlashAir(DynamicPrintConfig *config) : + host(config->opt_string("print_host")) +{} + +FlashAir::~FlashAir() {} + +const char* FlashAir::get_name() const { return "FlashAir"; } + +bool FlashAir::test(wxString &msg) const +{ + // Since the request is performed synchronously here, + // it is ok to refer to `msg` from within the closure + + const char *name = get_name(); + + bool res = false; + auto url = make_url("command.cgi", "op", "118"); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Get upload enabled at: %2%") % name % url; + + auto http = Http::get(std::move(url)); + http.on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error getting upload enabled: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + res = false; + msg = format_error(body, error, status); + }) + .on_complete([&, this](std::string body, unsigned) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got upload enabled: %2%") % name % body; + + res = boost::starts_with(body, "1"); + if (! res) { + msg = _(L("Upload not enabled on FlashAir card.")); + } + }) + .perform_sync(); + + return res; +} + +wxString FlashAir::get_test_ok_msg () const +{ + return _(L("Connection to FlashAir works correctly and upload is enabled.")); +} + +wxString FlashAir::get_test_failed_msg (wxString &msg) const +{ + return wxString::Format("%s: %s", _(L("Could not connect to FlashAir")), msg, _(L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required.")); +} + +bool FlashAir::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const +{ + const char *name = get_name(); + + const auto upload_filename = upload_data.upload_path.filename(); + const auto upload_parent_path = upload_data.upload_path.parent_path(); + + wxString test_msg; + if (! test(test_msg)) { + error_fn(std::move(test_msg)); + return false; + } + + bool res = false; + + auto urlPrepare = make_url("upload.cgi", "WRITEPROTECT=ON&FTIME", timestamp_str()); + auto urlUpload = make_url("upload.cgi"); + + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Uploading file %2% at %3% / %4%, filename: %5%") + % name + % upload_data.source_path + % urlPrepare + % urlUpload + % upload_filename.string(); + + // set filetime for upload and make card writeprotect to prevent filesystem damage + auto httpPrepare = Http::get(std::move(urlPrepare)); + httpPrepare.on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error prepareing upload: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + error_fn(format_error(body, error, status)); + res = false; + }) + .on_complete([&, this](std::string body, unsigned) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: Got prepare result: %2%") % name % body; + res = boost::icontains(body, "SUCCESS"); + if (! res) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Request completed but no SUCCESS message was received.") % name; + error_fn(format_error(body, L("Unknown error occured"), 0)); + } + }) + .perform_sync(); + + if(! res ) { + return res; + } + + // start file upload + auto http = Http::post(std::move(urlUpload)); + http.form_add_file("file", upload_data.source_path.string(), upload_filename.string()) + .on_complete([&](std::string body, unsigned status) { + BOOST_LOG_TRIVIAL(debug) << boost::format("%1%: File uploaded: HTTP %2%: %3%") % name % status % body; + res = boost::icontains(body, "SUCCESS"); + if (! res) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Request completed but no SUCCESS message was received.") % name; + error_fn(format_error(body, L("Unknown error occured"), 0)); + } + }) + .on_error([&](std::string body, std::string error, unsigned status) { + BOOST_LOG_TRIVIAL(error) << boost::format("%1%: Error uploading file: %2%, HTTP %3%, body: `%4%`") % name % error % status % body; + error_fn(format_error(body, error, status)); + res = false; + }) + .on_progress([&](Http::Progress progress, bool &cancel) { + prorgess_fn(std::move(progress), cancel); + if (cancel) { + // Upload was canceled + BOOST_LOG_TRIVIAL(info) << boost::format("%1%: Upload canceled") % name; + res = false; + } + }) + .perform_sync(); + + return res; +} + +bool FlashAir::has_auto_discovery() const +{ + return false; +} + +bool FlashAir::can_test() const +{ + return true; +} + +bool FlashAir::can_start_print() const +{ + return false; +} + +std::string FlashAir::timestamp_str() const +{ + auto t = std::time(nullptr); + auto tm = *std::localtime(&t); + + const char *name = get_name(); + + unsigned long fattime = ((tm.tm_year - 80) << 25) | + ((tm.tm_mon + 1) << 21) | + (tm.tm_mday << 16) | + (tm.tm_hour << 11) | + (tm.tm_min << 5) | + (tm.tm_sec >> 1); + + return (boost::format("%1$#x") % fattime).str(); +} + +std::string FlashAir::make_url(const std::string &path) const +{ + if (host.find("http://") == 0 || host.find("https://") == 0) { + if (host.back() == '/') { + return (boost::format("%1%%2%") % host % path).str(); + } else { + return (boost::format("%1%/%2%") % host % path).str(); + } + } else { + if (host.back() == '/') { + return (boost::format("http://%1%%2%") % host % path).str(); + } else { + return (boost::format("http://%1%/%2%") % host % path).str(); + } + } +} + +std::string FlashAir::make_url(const std::string &path, const std::string &arg, const std::string &val) const +{ + if (host.find("http://") == 0 || host.find("https://") == 0) { + if (host.back() == '/') { + return (boost::format("%1%%2%?%3%=%4%") % host % path % arg % val).str(); + } else { + return (boost::format("%1%/%2%?%3%=%4%") % host % path % arg % val).str(); + } + } else { + if (host.back() == '/') { + return (boost::format("http://%1%%2%?%3%=%4%") % host % path % arg % val).str(); + } else { + return (boost::format("http://%1%/%2%?%3%=%4%") % host % path % arg % val).str(); + } + } +} + +} diff --git a/src/slic3r/Utils/FlashAir.hpp b/src/slic3r/Utils/FlashAir.hpp new file mode 100644 index 0000000000..1499eee5d8 --- /dev/null +++ b/src/slic3r/Utils/FlashAir.hpp @@ -0,0 +1,44 @@ +#ifndef slic3r_FlashAir_hpp_ +#define slic3r_FlashAir_hpp_ + +#include +#include + +#include "PrintHost.hpp" + + +namespace Slic3r { + + +class DynamicPrintConfig; +class Http; + +class FlashAir : public PrintHost +{ +public: + FlashAir(DynamicPrintConfig *config); + virtual ~FlashAir(); + + virtual const char* get_name() const; + + virtual bool test(wxString &curl_msg) const; + virtual wxString get_test_ok_msg () const; + virtual wxString get_test_failed_msg (wxString &msg) const; + virtual bool upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const; + virtual bool has_auto_discovery() const; + virtual bool can_test() const; + virtual bool can_start_print() const; + virtual std::string get_host() const { return host; } + +private: + std::string host; + + std::string timestamp_str() const; + std::string make_url(const std::string &path) const; + std::string make_url(const std::string &path, const std::string &arg, const std::string &val) const; +}; + + +} + +#endif diff --git a/src/slic3r/Utils/PrintHost.cpp b/src/slic3r/Utils/PrintHost.cpp index ab52b23443..59a929ecca 100644 --- a/src/slic3r/Utils/PrintHost.cpp +++ b/src/slic3r/Utils/PrintHost.cpp @@ -14,6 +14,7 @@ #include "libslic3r/Channel.hpp" #include "OctoPrint.hpp" #include "Duet.hpp" +#include "FlashAir.hpp" #include "../GUI/PrintHostDialogs.hpp" namespace fs = boost::filesystem; @@ -43,6 +44,7 @@ PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config) switch (host_type) { case htOctoPrint: return new OctoPrint(config); case htDuet: return new Duet(config); + case htFlashAir: return new FlashAir(config); default: return nullptr; } } else { From 6089cadc4ee42e62ddbbfa7d8c352809dd103208 Mon Sep 17 00:00:00 2001 From: Stephan Reichhelm Date: Tue, 7 May 2019 19:51:47 +0200 Subject: [PATCH 71/82] + add new flashair class to localization --- resources/localization/list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/localization/list.txt b/resources/localization/list.txt index 82f109df44..aa2f938b7e 100644 --- a/resources/localization/list.txt +++ b/resources/localization/list.txt @@ -45,6 +45,7 @@ src/slic3r/GUI/WipeTowerDialog.cpp src/slic3r/GUI/wxExtensions.cpp src/slic3r/Utils/Duet.cpp src/slic3r/Utils/OctoPrint.cpp +src/slic3r/Utils/FlashAir.cpp src/slic3r/Utils/PresetUpdater.cpp src/slic3r/Utils/FixModelByWin10.cpp src/libslic3r/Zipper.cpp From c37cdb6585d9624163d980501d55157426910453 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 7 May 2019 20:30:28 +0200 Subject: [PATCH 72/82] * fix compile error and removed json includes --- src/slic3r/Utils/FlashAir.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/slic3r/Utils/FlashAir.cpp b/src/slic3r/Utils/FlashAir.cpp index d7b97fc54b..2e6a7982d2 100644 --- a/src/slic3r/Utils/FlashAir.cpp +++ b/src/slic3r/Utils/FlashAir.cpp @@ -5,8 +5,6 @@ #include #include #include -#include -#include #include #include @@ -73,7 +71,7 @@ wxString FlashAir::get_test_ok_msg () const wxString FlashAir::get_test_failed_msg (wxString &msg) const { - return wxString::Format("%s: %s", _(L("Could not connect to FlashAir")), msg, _(L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required.")); + return wxString::Format("%s: %s", _(L("Could not connect to FlashAir")), msg, _(L("Note: FlashAir with firmware 2.00.02 or newer and activated upload function is required."))); } bool FlashAir::upload(PrintHostUpload upload_data, ProgressFn prorgess_fn, ErrorFn error_fn) const From 64d5ac0d20b4dc7bb2213bfc33e1631bbd3d3e4d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 14:00:26 +0100 Subject: [PATCH 73/82] ENABLE_THUMBNAIL_GENERATOR -> Export thumbnails to gcode: max length of gcode lines set to 80 characters --- src/libslic3r/GCode.cpp | 22 ++++++++++++++++++++-- src/slic3r/GUI/GUI_App.cpp | 18 +++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 481e82da19..df3225f81c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -957,6 +957,8 @@ void GCode::_do_export(Print &print, FILE *file) // Write thumbnails using base64 encoding if (thumbnail_data != nullptr) { + const unsigned int max_row_length = 78; + for (const ThumbnailData& data : *thumbnail_data) { if (data.is_valid()) @@ -966,10 +968,26 @@ void GCode::_do_export(Print &print, FILE *file) size_t row_size = 4 * data.width; for (int r = (int)data.height - 1; r >= 0; --r) { - _write_format(file, "; %s\n", boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size).c_str()); + std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)(data.pixels.data() + r * row_size), row_size); + unsigned int row_count = 0; + while (encoded.length() > max_row_length) + { + if (row_count == 0) + _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); + else + _write_format(file, ";>%s\n", encoded.substr(0, max_row_length).c_str()); + + encoded = encoded.substr(max_row_length); + ++row_count; + } + + if (row_count == 0) + _write_format(file, "; %s\n", encoded.c_str()); + else + _write_format(file, ";>%s\n", encoded.c_str()); } - _write(file, "; thumbnail end\n;\n\n"); + _write(file, "; thumbnail end\n;\n"); } print.throw_if_canceled(); } diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index c35985f112..8f0014a05f 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1106,6 +1106,7 @@ void GUI_App::gcode_thumbnails_debug() boost::nowide::ifstream file(in_filename.c_str()); std::vector rows; + std::string row; if (file.good()) { while (std::getline(file, gcode_line)) @@ -1121,9 +1122,16 @@ void GUI_App::gcode_thumbnails_debug() width = (unsigned int)::atoi(width_str.c_str()); std::string height_str = gcode_line.substr(x_pos + 1); height = (unsigned int)::atoi(height_str.c_str()); + row.clear(); } else if (reading_image && boost::starts_with(gcode_line, END_MASK)) { + if (!row.empty()) + { + rows.push_back(row); + row.clear(); + } + if ((unsigned int)rows.size() == height) { std::vector thumbnail(4 * width * height, 0); @@ -1160,7 +1168,15 @@ void GUI_App::gcode_thumbnails_debug() rows.clear(); } else if (reading_image) - rows.push_back(gcode_line.substr(2)); + { + if (!row.empty() && (gcode_line[1] == ' ')) + { + rows.push_back(row); + row.clear(); + } + + row += gcode_line.substr(2); + } } } From f5bef3707f8d1b2e114b42f032925b255db00448 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 14:28:18 +0100 Subject: [PATCH 74/82] Added missing include --- src/slic3r/Utils/FlashAir.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/Utils/FlashAir.cpp b/src/slic3r/Utils/FlashAir.cpp index 2e6a7982d2..3fc913c994 100644 --- a/src/slic3r/Utils/FlashAir.cpp +++ b/src/slic3r/Utils/FlashAir.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include From 76377ee0fe334ad3957556ede6d1a8b84d4ed6e1 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 4 Nov 2019 15:38:15 +0100 Subject: [PATCH 75/82] ENABLE_THUMBNAIL_GENERATOR -> Export thumbnails to gcode as png data in lines with max 80 characters length --- src/libslic3r/GCode.cpp | 41 ++++++++++++++++++++++++++++++---- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GUI_App.cpp | 23 ++++++++++++++----- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index df3225f81c..6b773f4d3c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -35,6 +35,10 @@ #include +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE +#include "miniz_extension.hpp" +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + #if 0 // Enable debugging and asserts, even in the release build. #define DEBUG @@ -963,6 +967,31 @@ void GCode::_do_export(Print &print, FILE *file) { if (data.is_valid()) { +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + size_t png_size = 0; + void* png_data = tdefl_write_image_to_png_file_in_memory_ex((const void*)data.pixels.data(), data.width, data.height, 4, &png_size, MZ_DEFAULT_LEVEL, 1); + if (png_data != nullptr) + { + _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); + + std::string encoded = boost::beast::detail::base64_encode((const std::uint8_t*)png_data, png_size); + + unsigned int row_count = 0; + while (encoded.length() > max_row_length) + { + _write_format(file, "; %s\n", encoded.substr(0, max_row_length).c_str()); + encoded = encoded.substr(max_row_length); + ++row_count; + } + + if (encoded.length() > 0) + _write_format(file, "; %s\n", encoded.c_str()); + + _write(file, "; thumbnail end\n;\n"); + + mz_free(png_data); + } +#else _write_format(file, "\n;\n; thumbnail begin %dx%d\n", data.width, data.height); size_t row_size = 4 * data.width; @@ -981,13 +1010,17 @@ void GCode::_do_export(Print &print, FILE *file) ++row_count; } - if (row_count == 0) - _write_format(file, "; %s\n", encoded.c_str()); - else - _write_format(file, ";>%s\n", encoded.c_str()); + if (encoded.length() > 0) + { + if (row_count == 0) + _write_format(file, "; %s\n", encoded.c_str()); + else + _write_format(file, ";>%s\n", encoded.c_str()); + } } _write(file, "; thumbnail end\n;\n"); +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE } print.throw_if_canceled(); } diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 4b351adb29..15cbd38272 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -39,5 +39,6 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +#define ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE (1 && ENABLE_THUMBNAIL_GENERATOR) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 8f0014a05f..07deff54e6 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1104,14 +1104,14 @@ void GUI_App::gcode_thumbnails_debug() std::string in_filename = into_u8(dialog.GetPath()); std::string out_path = boost::filesystem::path(in_filename).remove_filename().append(L"thumbnail").string(); - boost::nowide::ifstream file(in_filename.c_str()); + boost::nowide::ifstream in_file(in_filename.c_str()); std::vector rows; std::string row; - if (file.good()) + if (in_file.good()) { - while (std::getline(file, gcode_line)) + while (std::getline(in_file, gcode_line)) { - if (file.good()) + if (in_file.good()) { if (boost::starts_with(gcode_line, BEGIN_MASK)) { @@ -1126,6 +1126,16 @@ void GUI_App::gcode_thumbnails_debug() } else if (reading_image && boost::starts_with(gcode_line, END_MASK)) { +#if ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE + std::string out_filename = out_path + std::to_string(width) + "x" + std::to_string(height) + ".png"; + boost::nowide::ofstream out_file(out_filename.c_str(), std::ios::binary); + if (out_file.good()) + { + std::string decoded = boost::beast::detail::base64_decode(row); + out_file.write(decoded.c_str(), decoded.length()); + out_file.close(); + } +#else if (!row.empty()) { rows.push_back(row); @@ -1161,6 +1171,7 @@ void GUI_App::gcode_thumbnails_debug() image.SaveFile(out_path + std::to_string(width) + "x" + std::to_string(height) + ".png", wxBITMAP_TYPE_PNG); } +#endif // ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE reading_image = false; width = 0; @@ -1169,18 +1180,20 @@ void GUI_App::gcode_thumbnails_debug() } else if (reading_image) { +#if !ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE if (!row.empty() && (gcode_line[1] == ' ')) { rows.push_back(row); row.clear(); } +#endif // !ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE row += gcode_line.substr(2); } } } - file.close(); + in_file.close(); } } #endif // ENABLE_THUMBNAIL_GENERATOR From b295bc22db89ddd3add28e56022a56a49f3b7c35 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 5 Nov 2019 10:45:14 +0100 Subject: [PATCH 76/82] Adaptive elephant foot compensation: Improvement of the variable offset regularization. --- src/libslic3r/ElephantFootCompensation.cpp | 91 ++++++++++++++++++- .../test_elephant_foot_compensation.cpp | 84 +++++++++++++++++ 2 files changed, 173 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 8b3dda8ae8..3cc3075b81 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -267,6 +267,91 @@ static inline void smooth_compensation(std::vector &compensation, float s } } +template +static inline INDEX_TYPE prev_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) +{ + if (idx == 0) + idx = INDEX_TYPE(container.size()); + return -- idx; +} + +template +static inline INDEX_TYPE next_idx_cyclic(INDEX_TYPE idx, const CONTAINER &container) +{ + if (++ idx == INDEX_TYPE(container.size())) + idx = 0; + return idx; +} + +static inline void smooth_compensation_banded(const Points &contour, float band, std::vector &compensation, float strength, size_t num_iterations) +{ + assert(contour.size() == compensation.size()); + assert(contour.size() > 2); + std::vector out(compensation); + float dist_min2 = band * band; + static constexpr bool use_min = false; + for (size_t iter = 0; iter < num_iterations; ++ iter) { + for (int i = 0; i < int(compensation.size()); ++ i) { + const Vec2f pthis = contour[i].cast(); + + int j = prev_idx_cyclic(i, contour); + Vec2f pprev = contour[j].cast(); + float prev = compensation[j]; + float l2 = (pthis - pprev).squaredNorm(); + if (l2 < dist_min2) { + float l = sqrt(l2); + int jprev = std::exchange(j, prev_idx_cyclic(j, contour)); + while (j != i) { + const Vec2f pp = contour[j].cast(); + const float lthis = (pp - pprev).norm(); + const float lnext = l + lthis; + if (lnext > band) { + // Interpolate the compensation value. + prev = use_min ? + std::min(prev, lerp(compensation[jprev], compensation[j], (band - l) / lthis)) : + lerp(compensation[jprev], compensation[j], (band - l) / lthis); + break; + } + prev = use_min ? std::min(prev, compensation[j]) : compensation[j]; + pprev = pp; + l = lnext; + jprev = std::exchange(j, prev_idx_cyclic(j, contour)); + } + } + + j = next_idx_cyclic(i, contour); + pprev = contour[j].cast(); + float next = compensation[j]; + l2 = (pprev - pthis).squaredNorm(); + if (l2 < dist_min2) { + float l = sqrt(l2); + int jprev = std::exchange(j, next_idx_cyclic(j, contour)); + while (j != i) { + const Vec2f pp = contour[j].cast(); + const float lthis = (pp - pprev).norm(); + const float lnext = l + lthis; + if (lnext > band) { + // Interpolate the compensation value. + next = use_min ? + std::min(next, lerp(compensation[jprev], compensation[j], (band - l) / lthis)) : + lerp(compensation[jprev], compensation[j], (band - l) / lthis); + break; + } + next = use_min ? std::min(next, compensation[j]) : compensation[j]; + pprev = pp; + l = lnext; + jprev = std::exchange(j, next_idx_cyclic(j, contour)); + } + } + + float laplacian = compensation[i] * (1.f - strength) + 0.5f * strength * (prev + next); + // Compensations are negative. Only apply the laplacian if it leads to lower compensation. + out[i] = std::max(laplacian, compensation[i]); + } + out.swap(compensation); + } +} + ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow &external_perimeter_flow, const double compensation) { // The contour shall be wide enough to apply the external perimeter plus compensation on both sides. @@ -285,10 +370,11 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & std::vector> deltas; deltas.reserve(simplified.holes.size() + 1); ExPolygon resampled(simplified); + double resample_interval = scale_(0.5); for (size_t idx_contour = 0; idx_contour <= simplified.holes.size(); ++ idx_contour) { Polygon &poly = (idx_contour == 0) ? resampled.contour : resampled.holes[idx_contour - 1]; std::vector resampled_point_parameters; - poly.points = resample_polygon(poly.points, scale_(0.5), resampled_point_parameters); + poly.points = resample_polygon(poly.points, resample_interval, resampled_point_parameters); std::vector dists = contour_distance(grid, idx_contour, poly.points, resampled_point_parameters, search_radius); for (float &d : dists) { // printf("Point %d, Distance: %lf\n", int(&d - dists.data()), unscale(d)); @@ -301,7 +387,8 @@ ExPolygon elephant_foot_compensation(const ExPolygon &input_expoly, const Flow & d = - (d - float(min_contour_width)) / 2.f; assert(d >= - float(scaled_compensation) && d <= 0.f); } - smooth_compensation(dists, 0.4f, 10); +// smooth_compensation(dists, 0.4f, 10); + smooth_compensation_banded(poly.points, float(0.8 * resample_interval), dists, 0.3f, 3); deltas.emplace_back(dists); } diff --git a/tests/libslic3r/test_elephant_foot_compensation.cpp b/tests/libslic3r/test_elephant_foot_compensation.cpp index 7aa2a241e3..9a7e652648 100644 --- a/tests/libslic3r/test_elephant_foot_compensation.cpp +++ b/tests/libslic3r/test_elephant_foot_compensation.cpp @@ -151,6 +151,75 @@ static ExPolygon thin_ring() return out; } +static ExPolygon vase_with_fins() +{ + ExPolygon out; + out.contour.points = { + {27431106, 489754}, {27436907, 489850}, {27457500, 489724}, {27457500, 5510510}, {28343327, 5565859}, {28351400, 5566288}, {28389945, 5568336}, {28394790, 5568765}, {28420177, 5571613}, {28901163, 5629918}, + {29903776, 5750412}, {30416384, 2513976}, {30682801, 831878}, {30688548, 795593}, {31507808, 939183}, {31513523, 940185}, {31533883, 943282}, {30775577, 5731079}, {30768824, 5773720}, {30748466, 5902252}, + {31614726, 6095505}, {31622633, 6097191}, {31660382, 6105244}, {31665100, 6106426}, {31689729, 6113210}, {32155671, 6246039}, {33127094, 6521893}, {34139670, 3405493}, {34665944, 1785782}, {34677296, 1750843}, + {35464012, 2020824}, {35469500, 2022707}, {35489124, 2028950}, {33991170, 6639179}, {33977829, 6680238}, {33937615, 6804003}, {34762987, 7130382}, {34770532, 7133285}, {34806557, 7147144}, {34811033, 7149049}, + {34834297, 7159603}, {35273721, 7363683}, {36190026, 7788101}, {37677657, 4868472}, {38450834, 3351031}, {38467513, 3318298}, {39202308, 3708028}, {39207434, 3710747}, {39225840, 3719984}, {37025125, 8039112}, + {37005525, 8077579}, {36946446, 8193529}, {37710592, 8645011}, {37717591, 8649059}, {37751004, 8668383}, {37755126, 8670965}, {37776453, 8685028}, {38178545, 8955338}, {39017176, 9517879}, {40943217, 6866906}, + {41944249, 5489097}, {41965843, 5459376}, {42630625, 5959265}, {42635262, 5962752}, {42651996, 5974755}, {39802725, 9896448}, {39777349, 9931375}, {39700858, 10036656}, {40384973, 10602104}, {40391252, 10607196}, + {40421232, 10631509}, {40424899, 10634704}, {40443764, 10651931}, {40798616, 10981815}, {41538921, 11668622}, {43855948, 9351592}, {45060194, 8147345}, {45086172, 8121368}, {45664563, 8719082}, {45668598, 8723251}, + {45683249, 8737724}, {42255579, 12165422}, {42225051, 12195949}, {42133032, 12287968}, {42720262, 12953467}, {42725667, 12959479}, {42751474, 12988183}, {42754596, 12991912}, {42770534, 13011877}, {43069412, 13393211}, + {43693167, 14187377}, {46344137, 12261333}, {47721948, 11260299}, {47751670, 11238705}, {48229435, 11919543}, {48232767, 11924292}, {48244974, 11940879}, {44323286, 14790155}, {44288359, 14815531}, {44183078, 14892022}, + {44658973, 15641210}, {44663371, 15647994}, {44684370, 15680381}, {44686871, 15684553}, {44699489, 15706766}, {44935035, 16130156}, {45426863, 17012121}, {48346505, 15524481}, {49863946, 14751306}, {49896680, 14734627}, + {50262068, 15481841}, {50264616, 15487053}, {50274078, 15505344}, {45954933, 17706046}, {45916466, 17725646}, {45800515, 17784726}, {46153358, 18599135}, {46156641, 18606523}, {46172315, 18641796}, {46174132, 18646308}, + {46183120, 18670221}, {46349534, 19125250}, {46697342, 20073284}, {49813754, 19060715}, {51433464, 18534440}, {51468404, 18523087}, {51712400, 19318239}, {51714102, 19323786}, {51720585, 19343332}, {47110355, 20841293}, + {47069295, 20854634}, {46945530, 20894847}, {47166614, 21754409}, {47168701, 21762220}, {47178664, 21799510}, {47179753, 21804251}, {47184889, 21829276}, {47278074, 22304738}, {47473309, 23295520}, {50709741, 22782917}, + {52391837, 22516497}, {52428122, 22510750}, {52544737, 23334291}, {52545550, 23340036}, {52548897, 23360356}, {47761090, 24118668}, {47718449, 24125422}, {47589917, 24145780}, {47673812, 25029360}, {47674651, 25037401}, + {47678657, 25075792}, {47678992, 25080644}, {47680151, 25106164}, {47697809, 25590347}, {47735642, 26599468}, {52752230, 26599468}, {52738564, 27431106}, {52738469, 27436907}, {52738595, 27457500}, {47717808, 27457500}, + {47662461, 28343321}, {47662032, 28351394}, {47659983, 28389938}, {47659554, 28394784}, {47656706, 28420171}, {47598401, 28901157}, {47477907, 29903774}, {50714338, 30416378}, {52396434, 30682795}, {52432719, 30688542}, + {52289144, 31507800}, {52288143, 31513515}, {52285046, 31533875}, {47497239, 30775569}, {47454598, 30768816}, {47326067, 30748458}, {47132809, 31614720}, {47131122, 31622626}, {47123069, 31660376}, {47121887, 31665094}, + {47115103, 31689724}, {46982279, 32155664}, {46706424, 33127087}, {49822834, 34139662}, {51442545, 34665936}, {51477485, 34677289}, {51207490, 35464012}, {51205607, 35469500}, {51199363, 35489124}, {46589140, 33991162}, + {46548081, 33977821}, {46424316, 33937607}, {46097945, 34762979}, {46095042, 34770524}, {46081183, 34806549}, {46079278, 34811025}, {46068724, 34834289}, {45864641, 35273715}, {45440218, 36190023}, {48359847, 37677651}, + {49877288, 38450826}, {49910022, 38467505}, {49520291, 39202300}, {49517572, 39207426}, {49508336, 39225832}, {45189199, 37025117}, {45150732, 37005517}, {45034781, 36946438}, {44583309, 37710592}, {44579262, 37717591}, + {44559938, 37751004}, {44557356, 37755126}, {44543292, 37776453}, {44272982, 38178543}, {43710441, 39017170}, {46361413, 40943214}, {47739222, 41944249}, {47768943, 41965843}, {47269053, 42630624}, {47265566, 42635262}, + {47253564, 42651996}, {43331872, 39802717}, {43296945, 39777341}, {43191664, 39700850}, {42626221, 40384973}, {42621129, 40391252}, {42596816, 40421232}, {42593621, 40424899}, {42576394, 40443764}, {42246510, 40798616}, + {41559699, 41538918}, {43876735, 43855948}, {45080983, 45060194}, {45106960, 45086172}, {44509231, 45664571}, {44505061, 45668605}, {44490589, 45683256}, {41062903, 42255578}, {40940357, 42133032}, {40274856, 42720258}, + {40268844, 42725663}, {40240140, 42751470}, {40236411, 42754592}, {40216446, 42770530}, {39835112, 43069407}, {39040953, 43693161}, {40966991, 46344124}, {41968025, 47721932}, {41989619, 47751654}, {41308783, 48229434}, + {41304034, 48232767}, {41287447, 48244973}, {38438168, 44323278}, {38412792, 44288351}, {38336302, 44183071}, {37587122, 44658973}, {37580338, 44663371}, {37547951, 44684370}, {37543779, 44686871}, {37521566, 44699489}, + {37098171, 44935029}, {36216213, 45426864}, {37703841, 48346500}, {38477019, 49863946}, {38493698, 49896680}, {37746484, 50262052}, {37741272, 50264600}, {37722981, 50274062}, {35522285, 45954933}, {35502686, 45916466}, + {35443606, 45800515}, {34629191, 46153350}, {34621803, 46156633}, {34586530, 46172307}, {34582018, 46174124}, {34558105, 46183112}, {34103078, 46349526}, {33155041, 46697341}, {34167619, 49813746}, {34693894, 51433456}, + {34705246, 51468395}, {33910086, 51712399}, {33904540, 51714102}, {33884994, 51720585}, {32387039, 47110355}, {32373698, 47069295}, {32333485, 46945530}, {31473915, 47166622}, {31466104, 47168709}, {31428813, 47178672}, + {31424073, 47179760}, {31399048, 47184897}, {30923586, 47278079}, {29932800, 47473310}, {30445407, 50709741}, {30711827, 52391837}, {30717574, 52428122}, {29894033, 52544729}, {29888288, 52545543}, {29867968, 52548889}, + {29109657, 47761082}, {29102904, 47718441}, {29082546, 47589909}, {28198964, 47673827}, {28190923, 47674666}, {28152532, 47678673}, {28147680, 47679007}, {28122160, 47680166}, {27637977, 47697820}, {26628861, 47735648}, + {26628861, 51012422}, {26628864, 52715485}, {26628864, 52752222}, {25797210, 52738556}, {25791409, 52738461}, {25770816, 52738587}, {25770816, 47717800}, {24884998, 47662453}, {24876924, 47662024}, {24838380, 47659975}, + {24833534, 47659546}, {24808147, 47656698}, {24327161, 47598396}, {23324548, 47477901}, {22811940, 50714338}, {22545523, 52396434}, {22539776, 52432719}, {21720525, 52289129}, {21714811, 52288127}, {21694451, 52285030}, + {22452755, 47497223}, {22459508, 47454583}, {22479866, 47326051}, {21613606, 47132816}, {21605699, 47131129}, {21567950, 47123077}, {21563232, 47121895}, {21538602, 47115110}, {21072662, 46982279}, {20101239, 46706425}, + {19088664, 49822824}, {18562390, 51442538}, {18551037, 51477477}, {17764314, 51207498}, {17758826, 51205614}, {17739202, 51199371}, {19237154, 46589140}, {19250495, 46548081}, {19290709, 46424316}, {18465339, 46097937}, + {18457794, 46095035}, {18421769, 46081175}, {18417293, 46079270}, {18394029, 46068716}, {17954603, 45864634}, {17038299, 45440211}, {15550671, 48359845}, {14777498, 49877288}, {14760820, 49910022}, {14026023, 49520291}, + {14020897, 49517572}, {14002491, 49508335}, {16203201, 45189191}, {16222801, 45150724}, {16281880, 45034773}, {15517740, 44583309}, {15510741, 44579261}, {15477328, 44559938}, {15473206, 44557356}, {15451878, 44543292}, + {15049787, 44272982}, {14211153, 43710440}, {12285115, 46361403}, {11284082, 47739206}, {11262488, 47768928}, {10597703, 47269053}, {10593066, 47265566}, {10576332, 47253563}, {13425609, 43331872}, {13450985, 43296945}, + {13527476, 43191664}, {12843352, 42626213}, {12837073, 42621121}, {12807093, 42596808}, {12803426, 42593613}, {12784561, 42576386}, {12429709, 42246502}, {11689410, 41559693}, {9372373, 43876727}, {8168126, 45080975}, + {8142148, 45106952}, {7563757, 44509222}, {7559722, 44505053}, {7545071, 44490581}, {10972747, 41062911}, {11003274, 41032383}, {11095293, 40940365}, {10508063, 40274848}, {10502658, 40268836}, {10476851, 40240132}, + {10473729, 40236403}, {10457791, 40216438}, {10158911, 39835107}, {9535160, 39040950}, {6884192, 40966991}, {5506386, 41968025}, {5476665, 41989618}, {4998885, 41308775}, {4995553, 41304026}, {4983346, 41287439}, + {8905039, 38438168}, {8939966, 38412792}, {9045247, 38336301}, {8569356, 37587114}, {8564958, 37580330}, {8543959, 37547943}, {8541458, 37543771}, {8528840, 37521558}, {8293293, 37098166}, {7801454, 36216208}, + {4881822, 37703836}, {3364381, 38477011}, {3331647, 38493690}, {2966260, 37746484}, {2963712, 37741272}, {2954250, 37722981}, {7273379, 35522270}, {7311845, 35502670}, {7427796, 35443590}, {7074968, 34629191}, + {7071686, 34621803}, {7056012, 34586530}, {7054194, 34582018}, {7045206, 34558105}, {6878792, 34103076}, {6530980, 33155036}, {3414573, 34167611}, {1794864, 34693885}, {1759924, 34705238}, {1515921, 33910079}, + {1514219, 33904532}, {1507735, 33884986}, {6117964, 32387033}, {6159023, 32373692}, {6282789, 32333479}, {6061704, 31473909}, {6059617, 31466099}, {6049654, 31428807}, {6048565, 31424067}, {6043429, 31399042}, + {5950245, 30923582}, {5755014, 29932799}, {2518579, 30445403}, {836483, 30711821}, {800198, 30717568}, {683591, 29894033}, {682777, 29888288}, {679431, 29867968}, {5467236, 29109657}, {5509877, 29102904}, {5638409, 29082546}, + {5554499, 28198964}, {5553660, 28190923}, {5549653, 28152532}, {5549319, 28147680}, {5548160, 28122159}, {5530507, 27637975}, {5492679, 26628853}, {2215900, 26628853}, {512834, 26628856}, {476096, 26628856}, {489754, 25797218}, + {489850, 25791417}, {489724, 25770824}, {5510510, 25770824}, {5565867, 24884990}, {5566296, 24876916}, {5568344, 24838372}, {5568773, 24833527}, {5571621, 24808139}, {5629923, 24327156}, {5750418, 23324543}, {2513981, 22811940}, + {831886, 22545523}, {795600, 22539776}, {939191, 21720518}, {940192, 21714803}, {943289, 21694443}, {5731087, 22452754}, {5773728, 22459508}, {5902260, 22479865}, {6095512, 21613598}, {6097199, 21605691}, {6105252, 21567942}, + {6106434, 21563224}, {6113218, 21538594}, {6246044, 21072654}, {6521898, 20101231}, {3405493, 19088662}, {1785783, 18562390}, {1750843, 18551037}, {2020831, 17764306}, {2022714, 17758819}, {2028958, 17739194}, {6639187, 19237147}, + {6680246, 19250488}, {6804011, 19290701}, {7130382, 18465339}, {7133285, 18457794}, {7147144, 18421769}, {7149049, 18417293}, {7159603, 18394029}, {7363683, 17954605}, {7788110, 17038301}, {4868477, 15550669}, {3351039, 14777491}, + {3318305, 14760812}, {3708029, 14026016}, {3710747, 14020890}, {3719984, 14002484}, {8039120, 16203201}, {8077586, 16222801}, {8193537, 16281881}, {8645019, 15517733}, {8649067, 15510734}, {8668391, 15477321}, {8670973, 15473199}, + {8685036, 15451871}, {8955346, 15049780}, {9517887, 14211149}, {6866919, 12285108}, {5489112, 11284075}, {5459391, 11262481}, {5959259, 10597695}, {5962745, 10593058}, {5974747, 10576324}, {9896454, 13425601}, {9931382, 13450977}, + {10036663, 13527468}, {10602111, 12843352}, {10607203, 12837073}, {10631516, 12807093}, {10634711, 12803426}, {10651937, 12784561}, {10981820, 12429709}, {11668626, 11689407}, {8147345, 8168126}, {8121368, 8142148}, {8719089, 7563749}, + {8723258, 7559715}, {8737731, 7545064}, {12165414, 10972746}, {12195941, 11003274}, {12287960, 11095293}, {12953467, 10508056}, {12959479, 10502650}, {12988183, 10476843}, {12991912, 10473721}, {13011878, 10457783}, {13393211, 10158903}, + {14187378, 9535150}, {12261338, 6884179}, {11260306, 5506371}, {11238712, 5476650}, {11919550, 4998885}, {11924299, 4995552}, {11940886, 4983346}, {14790161, 8905032}, {14815537, 8939959}, {14892028, 9045240}, {15641210, 8569348}, + {15647994, 8564950}, {15680381, 8543951}, {15684553, 8541450}, {15706766, 8528832}, {16130159, 8293285}, {17012123, 7801449}, {15524489, 4881814}, {14751314, 3364373}, {14734635, 3331640}, {15481841, 2966253}, {15487053, 2963704}, + {15505344, 2954242}, {17706054, 7273386}, {17725654, 7311852}, {17784734, 7427803}, {18599135, 7074961}, {18606523, 7071678}, {18641796, 7056004}, {18646308, 7054187}, {18670222, 7045199}, {19125250, 6878787}, {20073289, 6530975}, + {19060715, 3414573}, {18534440, 1794864}, {18523088, 1759924}, {19318247, 1515921}, {19323794, 1514219}, {19343340, 1507736}, {20841293, 6117964}, {20854634, 6159023}, {20894848, 6282789}, {21754417, 6061696}, {21762228, 6059609}, + {21799518, 6049647}, {21804259, 6048557}, {21829284, 6043421}, {22304743, 5950237}, {23295525, 5755007}, {22782917, 2518572}, {22516497, 836476}, {22510750, 800190}, {23334299, 683591}, {23340043, 682777}, {23360363, 679431}, + {24118676, 5467229}, {24125430, 5509869}, {24145787, 5638402}, {25029368, 5554507}, {25037409, 5553668}, {25075799, 5549661}, {25080652, 5549327}, {25106172, 5548168}, {25590355, 5530509}, {26599476, 5492671}, {26599476, 476096} + }; + return out; +} + SCENARIO("Elephant foot compensation", "[ElephantFoot]") { GIVEN("Large box") { @@ -293,6 +362,21 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") { SVG::export_expolygons(debug_out_path("elephant_foot_compensation_4.svg").c_str(), { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); +#endif /* TESTS_EXPORT_SVGS */ + THEN("area of the compensated polygon is smaller") { + REQUIRE(expoly_compensated.area() < expoly.area()); + } + } + } + + GIVEN("Vase with fins") { + ExPolygon expoly = vase_with_fins(); + WHEN("Compensated") { + ExPolygon expoly_compensated = elephant_foot_compensation(expoly, Flow(0.419999987f, 0.2f, 0.4f, false), 0.41f); +#ifdef TESTS_EXPORT_SVGS + SVG::export_expolygons(debug_out_path("elephant_foot_compensation_vase_with_fins.svg").c_str(), + { { { expoly }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } }, + { { expoly_compensated }, { "gray", "black", "blue", coord_t(scale_(0.02)), 0.5f, "black", coord_t(scale_(0.05)) } } }); #endif /* TESTS_EXPORT_SVGS */ THEN("area of the compensated polygon is smaller") { REQUIRE(expoly_compensated.area() < expoly.area()); From e1c6bd174af77c14953df801f2653bf0b9796b41 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 5 Nov 2019 11:14:00 +0100 Subject: [PATCH 77/82] Fixed missing include. --- src/libslic3r/ElephantFootCompensation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 3cc3075b81..7cbd05d696 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -11,6 +11,7 @@ #include #include +#include // #define CONTOUR_DISTANCE_DEBUG_SVG From f75c022445384b9fd656db79395edcca6ba242a5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 5 Nov 2019 11:16:55 +0100 Subject: [PATCH 78/82] Reworked pull request Centering model on bed, using bed shape from config (if available). #2424 thanks @luketaverne --- src/PrusaSlicer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 6c6f9584f0..f708679c18 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -167,6 +167,7 @@ int CLI::run(int argc, char **argv) // sla_print_config.apply(m_print_config, true); // Loop through transform options. + bool user_center_specified = false; for (auto const &opt_key : m_transforms) { if (opt_key == "merge") { Model m; @@ -209,6 +210,7 @@ int CLI::run(int argc, char **argv) for (auto &model : m_models) model.duplicate_objects_grid(x, y, (distance > 0) ? distance : 6); // TODO: this is not the right place for setting a default } else if (opt_key == "center") { + user_center_specified = true; for (auto &model : m_models) { model.add_default_instances(); // this affects instances: @@ -403,7 +405,9 @@ int CLI::run(int argc, char **argv) if (! m_config.opt_bool("dont_arrange")) { //FIXME make the min_object_distance configurable. model.arrange_objects(fff_print.config().min_object_distance()); - model.center_instances_around_point(m_config.option("center")->value); + model.center_instances_around_point((! user_center_specified && m_print_config.has("bed_shape")) ? + BoundingBoxf(m_print_config.opt("bed_shape")->values).center() : + m_config.option("center")->value); } if (printer_technology == ptFFF) { for (auto* mo : model.objects) From 612e45e783ee54104f8586b9a30de1104fdbf493 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 5 Nov 2019 11:46:05 +0100 Subject: [PATCH 79/82] std::exchange not supported by C++11. --- src/libslic3r/ElephantFootCompensation.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/ElephantFootCompensation.cpp b/src/libslic3r/ElephantFootCompensation.cpp index 7cbd05d696..0f4eb01350 100644 --- a/src/libslic3r/ElephantFootCompensation.cpp +++ b/src/libslic3r/ElephantFootCompensation.cpp @@ -11,7 +11,6 @@ #include #include -#include // #define CONTOUR_DISTANCE_DEBUG_SVG @@ -284,6 +283,14 @@ static inline INDEX_TYPE next_idx_cyclic(INDEX_TYPE idx, const CONTAINER &contai return idx; } +template +static inline T exchange(T& obj, U&& new_value) +{ + T old_value = std::move(obj); + obj = std::forward(new_value); + return old_value; +} + static inline void smooth_compensation_banded(const Points &contour, float band, std::vector &compensation, float strength, size_t num_iterations) { assert(contour.size() == compensation.size()); @@ -301,7 +308,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, float l2 = (pthis - pprev).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = std::exchange(j, prev_idx_cyclic(j, contour)); + int jprev = exchange(j, prev_idx_cyclic(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -316,7 +323,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, prev = use_min ? std::min(prev, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = std::exchange(j, prev_idx_cyclic(j, contour)); + jprev = exchange(j, prev_idx_cyclic(j, contour)); } } @@ -326,7 +333,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, l2 = (pprev - pthis).squaredNorm(); if (l2 < dist_min2) { float l = sqrt(l2); - int jprev = std::exchange(j, next_idx_cyclic(j, contour)); + int jprev = exchange(j, next_idx_cyclic(j, contour)); while (j != i) { const Vec2f pp = contour[j].cast(); const float lthis = (pp - pprev).norm(); @@ -341,7 +348,7 @@ static inline void smooth_compensation_banded(const Points &contour, float band, next = use_min ? std::min(next, compensation[j]) : compensation[j]; pprev = pp; l = lnext; - jprev = std::exchange(j, next_idx_cyclic(j, contour)); + jprev = exchange(j, next_idx_cyclic(j, contour)); } } From 41dadfdfcfc1c74ca23169ffc0819a2b12d43321 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 5 Nov 2019 14:50:58 +0100 Subject: [PATCH 80/82] ENABLE_THUMBNAIL_GENERATOR -> Generate thumbnails using GLEW_EXT_framebuffer_object on graphic cards supporting it --- src/slic3r/GUI/GLCanvas3D.cpp | 114 ++++++++++++++++++++++++++- src/slic3r/GUI/GLCanvas3D.hpp | 4 +- src/slic3r/GUI/GLCanvas3DManager.cpp | 10 ++- src/slic3r/GUI/GLCanvas3DManager.hpp | 12 ++- 4 files changed, 129 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7d58f3c091..99f61e51ed 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1653,10 +1653,12 @@ void GLCanvas3D::render() #if ENABLE_THUMBNAIL_GENERATOR void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { - if (GLCanvas3DManager::are_framebuffers_supported()) - _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); - else - _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); + switch (GLCanvas3DManager::get_framebuffers_type()) + { + case GLCanvas3DManager::FB_Arb: { _render_thumbnail_framebuffer(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + case GLCanvas3DManager::FB_Ext: { _render_thumbnail_framebuffer_ext(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + default: { _render_thumbnail_legacy(thumbnail_data, w, h, printable_only, parts_only, transparent_background); break; } + } } #endif // ENABLE_THUMBNAIL_GENERATOR @@ -3772,6 +3774,110 @@ void GLCanvas3D::_render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, un glsafe(::glDisable(GL_MULTISAMPLE)); } +void GLCanvas3D::_render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) +{ + thumbnail_data.set(w, h); + if (!thumbnail_data.is_valid()) + return; + + bool multisample = m_multisample_allowed; + if (multisample) + glsafe(::glEnable(GL_MULTISAMPLE)); + + GLint max_samples; + glsafe(::glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples)); + GLsizei num_samples = max_samples / 2; + + GLuint render_fbo; + glsafe(::glGenFramebuffersEXT(1, &render_fbo)); + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, render_fbo)); + + GLuint render_tex = 0; + GLuint render_tex_buffer = 0; + if (multisample) + { + // use renderbuffer instead of texture to avoid the need to use glTexImage2DMultisample which is available only since OpenGL 3.2 + glsafe(::glGenRenderbuffersEXT(1, &render_tex_buffer)); + glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_tex_buffer)); + glsafe(::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, num_samples, GL_RGBA8, w, h)); + glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, render_tex_buffer)); + } + else + { + glsafe(::glGenTextures(1, &render_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, render_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, render_tex, 0)); + } + + GLuint render_depth; + glsafe(::glGenRenderbuffersEXT(1, &render_depth)); + glsafe(::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_depth)); + if (multisample) + glsafe(::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, num_samples, GL_DEPTH_COMPONENT24, w, h)); + else + glsafe(::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, w, h)); + + glsafe(::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_depth)); + + GLenum drawBufs[] = { GL_COLOR_ATTACHMENT0 }; + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) + { + render_volumes_in_thumbnail(m_shader, m_volumes.volumes, thumbnail_data, printable_only, parts_only, transparent_background); + + if (multisample) + { + GLuint resolve_fbo; + glsafe(::glGenFramebuffersEXT(1, &resolve_fbo)); + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, resolve_fbo)); + + GLuint resolve_tex; + glsafe(::glGenTextures(1, &resolve_tex)); + glsafe(::glBindTexture(GL_TEXTURE_2D, resolve_tex)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, resolve_tex, 0)); + + glsafe(::glDrawBuffers(1, drawBufs)); + + if (::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) + { + glsafe(::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, render_fbo)); + glsafe(::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, resolve_fbo)); + glsafe(::glBlitFramebufferEXT(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR)); + + glsafe(::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, resolve_fbo)); + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + } + + glsafe(::glDeleteTextures(1, &resolve_tex)); + glsafe(::glDeleteFramebuffersEXT(1, &resolve_fbo)); + } + else + glsafe(::glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)thumbnail_data.pixels.data())); + +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + debug_output_thumbnail(thumbnail_data); +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG_OUTPUT + } + + glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); + glsafe(::glDeleteRenderbuffersEXT(1, &render_depth)); + if (render_tex_buffer != 0) + glsafe(::glDeleteRenderbuffersEXT(1, &render_tex_buffer)); + if (render_tex != 0) + glsafe(::glDeleteTextures(1, &render_tex)); + glsafe(::glDeleteFramebuffersEXT(1, &render_fbo)); + + if (multisample) + glsafe(::glDisable(GL_MULTISAMPLE)); +} + void GLCanvas3D::_render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background) { // check that thumbnail size does not exceed the default framebuffer size diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 9f8d9d228f..8c2e6e9a58 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -685,7 +685,9 @@ private: #if ENABLE_THUMBNAIL_GENERATOR // render thumbnail using an off-screen framebuffer void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); - // render thumbnail using the default framebuffer + // render thumbnail using an off-screen framebuffer when GLEW_EXT_framebuffer_object is supported + void _render_thumbnail_framebuffer_ext(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); + // render thumbnail using the default framebuffer void _render_thumbnail_legacy(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool transparent_background); #endif // ENABLE_THUMBNAIL_GENERATOR diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 03daa0b00e..3594e85a42 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -189,7 +189,7 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown; bool GLCanvas3DManager::s_compressed_textures_supported = false; -bool GLCanvas3DManager::s_framebuffers_supported = false; +GLCanvas3DManager::EFramebufferType GLCanvas3DManager::s_framebuffers_type = GLCanvas3DManager::FB_None; GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info; GLCanvas3DManager::GLCanvas3DManager() @@ -270,10 +270,12 @@ void GLCanvas3DManager::init_gl() else s_compressed_textures_supported = false; - if (s_gl_info.is_version_greater_or_equal_to(3, 0) && GLEW_ARB_framebuffer_object) - s_framebuffers_supported = true; + if (GLEW_ARB_framebuffer_object) + s_framebuffers_type = FB_Arb; + else if (GLEW_EXT_framebuffer_object) + s_framebuffers_type = FB_Ext; else - s_framebuffers_supported = false; + s_framebuffers_type = FB_None; if (! s_gl_info.is_version_greater_or_equal_to(2, 0)) { // Complain about the OpenGL version. diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp index a2e35f8111..940e0230ae 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -30,6 +30,13 @@ struct Camera; class GLCanvas3DManager { public: + enum EFramebufferType : unsigned char + { + FB_None, + FB_Arb, + FB_Ext + }; + class GLInfo { mutable bool m_detected; @@ -77,7 +84,7 @@ private: bool m_gl_initialized; static EMultisampleState s_multisample; static bool s_compressed_textures_supported; - static bool s_framebuffers_supported; + static EFramebufferType s_framebuffers_type; public: GLCanvas3DManager(); @@ -98,7 +105,8 @@ public: static bool can_multisample() { return s_multisample == MS_Enabled; } static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } - static bool are_framebuffers_supported() { return s_framebuffers_supported; } + static bool are_framebuffers_supported() { return (s_framebuffers_type != FB_None); } + static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; } static wxGLCanvas* create_wxglcanvas(wxWindow *parent); From f8785250d67df5eeea5a26f3db52296e19c0c83d Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 5 Nov 2019 18:18:27 +0100 Subject: [PATCH 81/82] Disable test_fill.cpp`"Solid surface fill" test for now due to precission issues --- tests/fff_print/test_fill.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp index ec8b44a0d5..c98cdcf430 100644 --- a/tests/fff_print/test_fill.cpp +++ b/tests/fff_print/test_fill.cpp @@ -138,6 +138,8 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { REQUIRE(paths.size() == 1); } } + + #if 0 // Disabled temporarily due to precission issues on the Mac VM SECTION("Solid surface fill") { Slic3r::Points points { Point::new_scale(6883102, 9598327.01296997), @@ -154,6 +156,8 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") { REQUIRE(test_if_solid_surface_filled(expolygon, 0.55) == true); } } + #endif + SECTION("Solid surface fill") { Slic3r::Points points { Slic3r::Point(59515297,5422499),Slic3r::Point(59531249,5578697),Slic3r::Point(59695801,6123186), From 1e8aa54559afddf526d86d0c0f58f892209fcf9a Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 7 Nov 2019 09:01:28 +0100 Subject: [PATCH 82/82] ENABLE_THUMBNAIL_GENERATOR -> Added ENABLE_THUMBNAIL_GENERATOR_DEBUG (disabled) --- src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GUI_App.cpp | 4 ++-- src/slic3r/GUI/MainFrame.cpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 15cbd38272..5d0a7592cd 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -39,6 +39,7 @@ // Enable thumbnail generator #define ENABLE_THUMBNAIL_GENERATOR (1 && ENABLE_2_2_0_ALPHA1) +#define ENABLE_THUMBNAIL_GENERATOR_DEBUG (0 && ENABLE_THUMBNAIL_GENERATOR) #define ENABLE_THUMBNAIL_GENERATOR_PNG_TO_GCODE (1 && ENABLE_THUMBNAIL_GENERATOR) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 07deff54e6..0b24e22157 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1087,7 +1087,7 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage return res; } -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG void GUI_App::gcode_thumbnails_debug() { const std::string BEGIN_MASK = "; thumbnail begin"; @@ -1196,7 +1196,7 @@ void GUI_App::gcode_thumbnails_debug() in_file.close(); } } -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 56eda2c0da..b76110a874 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -682,11 +682,11 @@ void MainFrame::init_menubar() helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("Keyboard Shortcuts")) + sep + "&?", _(L("Show the list of the keyboard shortcuts")), [this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); }); -#if ENABLE_THUMBNAIL_GENERATOR +#if ENABLE_THUMBNAIL_GENERATOR_DEBUG helpMenu->AppendSeparator(); append_menu_item(helpMenu, wxID_ANY, _(L("DEBUG gcode thumbnails")), _(L("DEBUG ONLY - read the selected gcode file and generates png for the contained thumbnails")), [this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); }); -#endif // ENABLE_THUMBNAIL_GENERATOR +#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG } // menubar