diff --git a/CMakeLists.txt b/CMakeLists.txt index cbb0e2ec49..9b8a1c8480 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,13 +13,13 @@ if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() if(DEFINED ENV{SLIC3R_STATIC}) - set(SLIC3R_STATIC_INITIAL $ENV{SLIC3R_STATIC}) + set(SLIC3R_STATIC_INITIAL $ENV{SLIC3R_STATIC}) else() - if (MSVC OR MINGW OR APPLE) - set(SLIC3R_STATIC_INITIAL 1) - else() - set(SLIC3R_STATIC_INITIAL 0) - endif() + if (MSVC OR MINGW OR APPLE) + set(SLIC3R_STATIC_INITIAL 1) + else() + set(SLIC3R_STATIC_INITIAL 0) + endif() endif() option(SLIC3R_STATIC "Compile PrusaSlicer with static libraries (Boost, TBB, glew)" ${SLIC3R_STATIC_INITIAL}) @@ -52,9 +52,21 @@ if (SLIC3R_GUI) add_definitions(-DSLIC3R_GUI) endif () +if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(IS_CLANG_CL TRUE) + + # clang-cl can interpret SYSTEM header paths if -imsvc is used + set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-imsvc") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \ + -Wno-old-style-cast -Wno-reserved-id-macro -Wno-c++98-compat-pedantic") +else () + set(IS_CLANG_CL FALSE) +endif () + if (MSVC) - if (SLIC3R_MSVC_COMPILE_PARALLEL) - add_compile_options(/MP) + if (SLIC3R_MSVC_COMPILE_PARALLEL AND NOT IS_CLANG_CL) + add_compile_options(/MP) endif () # /bigobj (Increase Number of Sections in .Obj file) # error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm90' or greater @@ -62,6 +74,10 @@ if (MSVC) add_compile_options(-bigobj -Zm520 /Zi) endif () +if (MINGW) + add_compile_options(-Wa,-mbig-obj) +endif () + # Display and check CMAKE_PREFIX_PATH message(STATUS "SLIC3R_STATIC: ${SLIC3R_STATIC}") if (NOT "${CMAKE_PREFIX_PATH}" STREQUAL "") @@ -101,17 +117,17 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory. # We pick it from environment if it is not defined in another way if(WIN32) - if(NOT DEFINED WIN10SDK_PATH) - if(DEFINED ENV{WIN10SDK_PATH}) - set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}") - endif() - endif() - if(DEFINED WIN10SDK_PATH AND NOT EXISTS "${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h") - message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}") - message("${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h was not found") - message("STL fixing by the Netfabb service will not be compiled") - unset(WIN10SDK_PATH) - endif() + if(NOT DEFINED WIN10SDK_PATH) + if(DEFINED ENV{WIN10SDK_PATH}) + set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}") + endif() + endif() + if(DEFINED WIN10SDK_PATH AND NOT EXISTS "${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h") + message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}") + message("${WIN10SDK_PATH}/include/winrt/windows.graphics.printing3d.h was not found") + message("STL fixing by the Netfabb service will not be compiled") + unset(WIN10SDK_PATH) + endif() if(WIN10SDK_PATH) message("Building with Win10 Netfabb STL fixing service support") add_definitions(-DHAS_WIN10SDK) @@ -148,8 +164,10 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals" ) endif() -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) +if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")) + if (NOT MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) + endif () set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" ) # On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error. @@ -168,7 +186,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATC add_compile_options(-Wno-unknown-pragmas) endif() - if (SLIC3R_ASAN) add_compile_options(-fsanitize=address -fno-omit-frame-pointer) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") @@ -196,9 +213,12 @@ include_directories(${LIBDIR_BIN}/platform) include_directories(${LIBDIR}/clipper ${LIBDIR}/polypartition) if(WIN32) - # BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking. - add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) -endif() + add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) + if(MSVC) + # BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking. + add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601 ) + endif(MSVC) +endif(WIN32) add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE -DWXINTL_NO_GETTEXT_MACRO) @@ -229,7 +249,7 @@ if(SLIC3R_STATIC) # set(Boost_USE_STATIC_RUNTIME ON) endif() #set(Boost_DEBUG ON) -# set(Boost_COMPILER "-vc120") +# set(Boost_COMPILER "-mgw81") if(NOT WIN32) # boost::process was introduced first in version 1.64.0 set(MINIMUM_BOOST_VERSION "1.64.0") @@ -251,7 +271,7 @@ endif() if(TARGET Boost::system) message(STATUS "Boost::boost exists") target_link_libraries(boost_headeronly INTERFACE Boost::boost) - target_link_libraries(boost_libs INTERFACE + target_link_libraries(boost_libs INTERFACE boost_headeronly # includes the custom compile definitions as well Boost::system Boost::filesystem diff --git a/cmake/modules/PrecompiledHeader.cmake b/cmake/modules/PrecompiledHeader.cmake index e463021441..2f62a7dbeb 100644 --- a/cmake/modules/PrecompiledHeader.cmake +++ b/cmake/modules/PrecompiledHeader.cmake @@ -105,6 +105,9 @@ function(add_precompiled_header _target _input) cmake_parse_arguments(_PCH "FORCEINCLUDE" "SOURCE_CXX;SOURCE_C" "" ${ARGN}) get_filename_component(_input_we ${_input} NAME_WE) + get_filename_component(_input_full ${_input} ABSOLUTE) + file(TO_NATIVE_PATH "${_input_full}" _input_fullpath) + if(NOT _PCH_SOURCE_CXX) set(_PCH_SOURCE_CXX "${_input_we}.cpp") endif() @@ -138,16 +141,16 @@ function(add_precompiled_header _target _input) set_source_files_properties("${_source}" PROPERTIES OBJECT_OUTPUTS "${_pch_c_pch}") else() if(_source MATCHES \\.\(cpp|cxx|cc\)$) - set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_cxx_pch}\" \"/Yu${_input}\"") + set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_cxx_pch}\" \"/Yu${_input_fullpath}\"") set(_pch_source_cxx_needed TRUE) set_source_files_properties("${_source}" PROPERTIES OBJECT_DEPENDS "${_pch_cxx_pch}") else() - set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_c_pch}\" \"/Yu${_input}\"") + set(_pch_compile_flags "${_pch_compile_flags} \"/Fp${_pch_c_pch}\" \"/Yu${_input_fullpath}\"") set(_pch_source_c_needed TRUE) set_source_files_properties("${_source}" PROPERTIES OBJECT_DEPENDS "${_pch_c_pch}") endif() if(_PCH_FORCEINCLUDE) - set(_pch_compile_flags "${_pch_compile_flags} /FI${_input}") + set(_pch_compile_flags "${_pch_compile_flags} /FI${_input_fullpath}") endif(_PCH_FORCEINCLUDE) endif() diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index f6a80f3ca0..90ad6f0fa7 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -76,7 +76,10 @@ elseif (APPLE) endif () include("deps-macos.cmake") -else () +elseif (MINGW) + message(STATUS "Building for MinGW...") + include("deps-mingw.cmake") +else() include("deps-linux.cmake") endif() diff --git a/deps/deps-mingw.cmake b/deps/deps-mingw.cmake new file mode 100644 index 0000000000..bfe5f9fe43 --- /dev/null +++ b/deps/deps-mingw.cmake @@ -0,0 +1,76 @@ +set(DEP_CMAKE_OPTS "-DCMAKE_POSITION_INDEPENDENT_CODE=ON") +set(DEP_BOOST_TOOLSET "gcc") +set(DEP_BITS 64) + +find_package(Git REQUIRED) + +# TODO make sure to build tbb with -flifetime-dse=1 +include("deps-unix-common.cmake") + +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" + URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9 + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND bootstrap.bat + BUILD_COMMAND b2.exe + -j "${NPROC}" + --with-system + --with-filesystem + --with-thread + --with-log + --with-locale + --with-regex + "--prefix=${DESTDIR}/usr/local" + "address-model=${DEPS_BITS}" + "toolset=${DEP_BOOST_TOOLSET}" + link=static + define=BOOST_USE_WINAPI_VERSION=0x0502 + variant=release + threading=multi + boost.locale.icu=off + "${DEP_BOOST_DEBUG}" release install + INSTALL_COMMAND "" # b2 does that already +) + +ExternalProject_Add(dep_libcurl + EXCLUDE_FROM_ALL 1 + URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz" + URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115 + CMAKE_ARGS + -DBUILD_SHARED_LIBS=OFF + -DBUILD_TESTING=OFF + -DCURL_STATICLIB=ON + -DCURL_STATIC_CRT=ON + -DENABLE_THREADED_RESOLVER=ON + -DCURL_DISABLE_FTP=ON + -DCURL_DISABLE_LDAP=ON + -DCURL_DISABLE_LDAPS=ON + -DCURL_DISABLE_TELNET=ON + -DCURL_DISABLE_DICT=ON + -DCURL_DISABLE_FILE=ON + -DCURL_DISABLE_TFTP=ON + -DCURL_DISABLE_RTSP=ON + -DCURL_DISABLE_POP3=ON + -DCURL_DISABLE_IMAP=ON + -DCURL_DISABLE_SMTP=ON + -DCURL_DISABLE_GOPHER=ON + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + ${DEP_CMAKE_OPTS} +) + +ExternalProject_Add(dep_wxwidgets + EXCLUDE_FROM_ALL 1 + GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets" + GIT_TAG v3.1.1-patched +# URL "https://github.com/wxWidgets/wxWidgets/releases/download/v3.1.1/wxWidgets-3.1.1.tar.bz2" +# URL_HASH SHA256=c925dfe17e8f8b09eb7ea9bfdcfcc13696a3e14e92750effd839f5e10726159e +# PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}\\wxwidgets-pngprefix.h" src\\png\\pngprefix.h + CMAKE_ARGS + -DBUILD_SHARED_LIBS=OFF + -DwxUSE_LIBPNG=builtin + -DwxUSE_ZLIB=builtin + -DwxUSE_OPENGL=ON + -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local + ${DEP_CMAKE_OPTS} +) \ No newline at end of file diff --git a/deps/deps-unix-common.cmake b/deps/deps-unix-common.cmake index e323460a6d..6e559d05a3 100644 --- a/deps/deps-unix-common.cmake +++ b/deps/deps-unix-common.cmake @@ -1,6 +1,12 @@ # The unix common part expects DEP_CMAKE_OPTS to be set +if (MINGW) + set(TBB_MINGW_WORKAROUND "-flifetime-dse=1") +else () + set(TBB_MINGW_WORKAROUND "") +endif () + ExternalProject_Add(dep_tbb EXCLUDE_FROM_ALL 1 URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz" @@ -8,6 +14,7 @@ ExternalProject_Add(dep_tbb CMAKE_ARGS -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF + -DCMAKE_CXX_FLAGS=${TBB_MINGW_WORKAROUND} -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local ${DEP_CMAKE_OPTS} ) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index 9092f330bc..85013fbddd 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -19,6 +19,10 @@ else () message(FATAL_ERROR "Unsupported MSVC version") endif () +if (CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(DEP_BOOST_TOOLSET "clang-win") +endif () + if (${DEPS_BITS} EQUAL 32) set(DEP_MSVC_GEN "Visual Studio ${DEP_VS_VER}") set(DEP_PLATFORM "Win32") diff --git a/sandboxes/CMakeLists.txt b/sandboxes/CMakeLists.txt index 0e1f52d6cf..5905c438e9 100644 --- a/sandboxes/CMakeLists.txt +++ b/sandboxes/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(slabasebed) +add_subdirectory(slasupporttree) diff --git a/sandboxes/slabasebed/slabasebed.cpp b/sandboxes/slabasebed/slabasebed.cpp index 5393f61fd7..b8b94d86f3 100644 --- a/sandboxes/slabasebed/slabasebed.cpp +++ b/sandboxes/slabasebed/slabasebed.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -15,8 +16,8 @@ const std::string USAGE_STR = { namespace Slic3r { namespace sla { -Contour3D create_base_pool(const Polygons &ground_layer, - const Polygons &holes = {}, +Contour3D create_base_pool(const Polygons &ground_layer, + const ExPolygons &holes = {}, const PoolConfig& cfg = PoolConfig()); Contour3D walls(const Polygon& floor_plate, const Polygon& ceiling, @@ -43,22 +44,22 @@ int main(const int argc, const char *argv[]) { model.ReadSTLFile(argv[1]); model.align_to_origin(); - Polygons ground_slice; + ExPolygons ground_slice; sla::base_plate(model, ground_slice, 0.1f); if(ground_slice.empty()) return EXIT_FAILURE; - Polygon gndfirst; gndfirst = ground_slice.front(); - sla::offset_with_breakstick_holes(gndfirst, 0.5, 10, 0.3); + 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::PoolConfig cfg; cfg.min_wall_height_mm = 0; cfg.edge_radius_mm = 0; - mesh = sla::create_base_pool(ground_slice, {}, cfg); + mesh = sla::create_base_pool(to_polygons(ground_slice), {}, cfg); bench.stop(); @@ -75,7 +76,7 @@ int main(const int argc, const char *argv[]) { if(std::abs(a) < 1e-6) std::cout << "degenerate triangle" << std::endl; } -// basepool.write_ascii("out.stl"); + // basepool.write_ascii("out.stl"); std::fstream outstream("out.obj", std::fstream::out); mesh.to_obj(outstream); diff --git a/sandboxes/slasupporttree/CMakeLists.txt b/sandboxes/slasupporttree/CMakeLists.txt new file mode 100644 index 0000000000..79adb842b9 --- /dev/null +++ b/sandboxes/slasupporttree/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(slasupporttree slasupporttree.cpp) +target_link_libraries(slasupporttree libslic3r ${Boost_LIBRARIES} ${TBB_LIBRARIES} ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) diff --git a/sandboxes/slasupporttree/slasupporttree.cpp b/sandboxes/slasupporttree/slasupporttree.cpp new file mode 100644 index 0000000000..dcaddf6d3f --- /dev/null +++ b/sandboxes/slasupporttree/slasupporttree.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +const std::string USAGE_STR = { + "Usage: slasupporttree stlfilename.stl" +}; + +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; + } + + DynamicPrintConfig config; + + Model model = Model::read_from_file(argv[1], &config); + + SLAPrint print; + + print.apply(model, config); + print.process(); + + + return EXIT_SUCCESS; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ee46289ad..9f3dbcec89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,7 +47,7 @@ if (SLIC3R_GUI) endif () endif () else () - find_package(wxWidgets 3.1 REQUIRED COMPONENTS base core adv html gl) + find_package(wxWidgets 3.1 REQUIRED COMPONENTS html adv gl core base) endif () if(UNIX) @@ -56,6 +56,9 @@ if (SLIC3R_GUI) include(${wxWidgets_USE_FILE}) +# list(REMOVE_ITEM wxWidgets_LIBRARIES oleacc) + message(STATUS "wx libs: ${wxWidgets_LIBRARIES}") + add_subdirectory(slic3r) endif() @@ -65,12 +68,18 @@ endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/msw/PrusaSlicer.rc.in ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/msw/PrusaSlicer.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.manifest @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/platform/osx/Info.plist.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist @ONLY) -if (MSVC) +if (WIN32) add_library(PrusaSlicer SHARED PrusaSlicer.cpp PrusaSlicer.hpp) else () add_executable(PrusaSlicer PrusaSlicer.cpp PrusaSlicer.hpp) endif () -if (NOT MSVC) + +if (MINGW) + target_link_options(PrusaSlicer PUBLIC "-Wl,-allow-multiple-definition") + set_target_properties(PrusaSlicer PROPERTIES PREFIX "") +endif (MINGW) + +if (NOT WIN32) # Binary name on unix like systems (OSX, Linux) set_target_properties(PrusaSlicer PROPERTIES OUTPUT_NAME "prusa-slicer") endif () @@ -91,11 +100,12 @@ endif () # Add the Slic3r GUI library, libcurl, OpenGL and GLU libraries. if (SLIC3R_GUI) - target_link_libraries(PrusaSlicer libslic3r_gui ${wxWidgets_LIBRARIES}) +# target_link_libraries(PrusaSlicer ws2_32 uxtheme setupapi libslic3r_gui ${wxWidgets_LIBRARIES}) +target_link_libraries(PrusaSlicer libslic3r_gui ${wxWidgets_LIBRARIES}) # Configure libcurl and its dependencies OpenSSL & zlib find_package(CURL REQUIRED) - if (NOT MSVC) + if (NOT WIN32) # Required by libcurl find_package(ZLIB REQUIRED) endif() @@ -123,7 +133,7 @@ if (SLIC3R_GUI) target_link_options(PrusaSlicer PUBLIC "$<$:/DEBUG>") target_link_libraries(PrusaSlicer user32.lib Setupapi.lib OpenGL32.Lib GlU32.Lib) elseif (MINGW) - target_link_libraries(PrusaSlicer -lopengl32) + target_link_libraries(PrusaSlicer opengl32 ws2_32 uxtheme setupapi) elseif (APPLE) target_link_libraries(PrusaSlicer "-framework OpenGL") else () @@ -133,10 +143,16 @@ endif () # On Windows, a shim application is required to produce a console / non console version of the Slic3r application. # Also the shim may load the Mesa software OpenGL renderer if the default renderer does not support OpenGL 2.0 and higher. -if (MSVC) +if (WIN32) + if (MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") + endif() + add_executable(PrusaSlicer_app_gui WIN32 PrusaSlicer_app_msvc.cpp ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc) # Generate debug symbols even in release mode. - target_link_options(PrusaSlicer_app_gui PUBLIC "$<$:/DEBUG>") + if(MSVC) + target_link_options(PrusaSlicer_app_gui PUBLIC "$<$:/DEBUG>") + endif() target_compile_definitions(PrusaSlicer_app_gui PRIVATE -DSLIC3R_WRAPPER_NOCONSOLE) add_dependencies(PrusaSlicer_app_gui PrusaSlicer) set_target_properties(PrusaSlicer_app_gui PROPERTIES OUTPUT_NAME "prusa-slicer") @@ -144,7 +160,9 @@ if (MSVC) add_executable(PrusaSlicer_app_console PrusaSlicer_app_msvc.cpp ${CMAKE_CURRENT_BINARY_DIR}/PrusaSlicer.rc) # Generate debug symbols even in release mode. + if (MSVC) target_link_options(PrusaSlicer_app_console PUBLIC "$<$:/DEBUG>") + endif () target_compile_definitions(PrusaSlicer_app_console PRIVATE -DSLIC3R_WRAPPER_CONSOLE) add_dependencies(PrusaSlicer_app_console PrusaSlicer) set_target_properties(PrusaSlicer_app_console PROPERTIES OUTPUT_NAME "prusa-slicer-console") @@ -152,7 +170,7 @@ if (MSVC) endif () # Link the resources dir to where Slic3r GUI expects it -if (MSVC) +if (WIN32) if (CMAKE_CONFIGURATION_TYPES) foreach (CONF ${CMAKE_CONFIGURATION_TYPES}) file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${CONF}" WIN_CONF_OUTPUT_DIR) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 45a3336304..8ec0e1d8ed 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -7,8 +7,8 @@ #include #include #ifdef SLIC3R_GUI - extern "C" - { + extern "C" + { // Let the NVIDIA and AMD know we want to use their graphics card // on a dual graphics card system. __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; @@ -54,11 +54,11 @@ using namespace Slic3r; PrinterTechnology get_printer_technology(const DynamicConfig &config) { - const ConfigOptionEnum *opt = config.option>("printer_technology"); + const ConfigOptionEnum *opt = config.option>("printer_technology"); return (opt == nullptr) ? ptUnknown : opt->value; } -int CLI::run(int argc, char **argv) +int CLI::run(int argc, char **argv) { // Switch boost::filesystem to utf8. boost::nowide::nowide_filesystem(); @@ -71,14 +71,14 @@ int CLI::run(int argc, char **argv) bool start_gui = m_actions.empty() && // cutting transformations are setting an "export" action. - std::find(m_transforms.begin(), m_transforms.end(), "cut") == m_transforms.end() && - std::find(m_transforms.begin(), m_transforms.end(), "cut_x") == m_transforms.end() && - std::find(m_transforms.begin(), m_transforms.end(), "cut_y") == m_transforms.end(); + std::find(m_transforms.begin(), m_transforms.end(), "cut") == m_transforms.end() && + std::find(m_transforms.begin(), m_transforms.end(), "cut_x") == m_transforms.end() && + std::find(m_transforms.begin(), m_transforms.end(), "cut_y") == m_transforms.end(); PrinterTechnology printer_technology = get_printer_technology(m_extra_config); - const std::vector &load_configs = m_config.option("load", true)->values; - + const std::vector &load_configs = m_config.option("load", true)->values; + // load config files supplied via --load - for (auto const &file : load_configs) { + for (auto const &file : load_configs) { if (! boost::filesystem::exists(file)) { if (m_config.opt_bool("ignore_nonexistent_config")) { continue; @@ -104,7 +104,7 @@ int CLI::run(int argc, char **argv) } m_print_config.apply(config); } - + // Read input file(s) if any. for (const std::string &file : m_input_files) { if (! boost::filesystem::exists(file)) { @@ -140,21 +140,21 @@ int CLI::run(int argc, char **argv) m_print_config.normalize(); if (printer_technology == ptUnknown) - printer_technology = std::find(m_actions.begin(), m_actions.end(), "export_sla") == m_actions.end() ? ptFFF : ptSLA; + printer_technology = std::find(m_actions.begin(), m_actions.end(), "export_sla") == m_actions.end() ? ptFFF : ptSLA; // Initialize full print configs for both the FFF and SLA technologies. FullPrintConfig fff_print_config; // SLAFullPrintConfig sla_print_config; fff_print_config.apply(m_print_config, true); // sla_print_config.apply(m_print_config, true); - + // Loop through transform options. for (auto const &opt_key : m_transforms) { if (opt_key == "merge") { Model m; for (auto &model : m_models) - for (ModelObject *o : model.objects) - m.add_object(*o); + for (ModelObject *o : model.objects) + m.add_object(*o); // Rearrange instances unless --dont-arrange is supplied if (! m_config.opt_bool("dont_arrange")) { m.add_default_instances(); @@ -166,8 +166,8 @@ int CLI::run(int argc, char **argv) this->has_print_action() ? &bb : nullptr ); } - m_models.clear(); - m_models.emplace_back(std::move(m)); + m_models.clear(); + m_models.emplace_back(std::move(m)); } else if (opt_key == "duplicate") { const BoundingBoxf &bb = fff_print_config.bed_shape.values; for (auto &model : m_models) { @@ -196,11 +196,11 @@ int CLI::run(int argc, char **argv) // this affects instances: model.center_instances_around_point(m_config.option("center")->value); // this affects volumes: - //FIXME Vojtech: Who knows why the complete model should be aligned with Z as a single rigid body? + //FIXME Vojtech: Who knows why the complete model should be aligned with Z as a single rigid body? //model.align_to_ground(); BoundingBoxf3 bbox; for (ModelObject *model_object : model.objects) - // We are interested into the Z span only, therefore it is sufficient to measure the bounding box of the 1st instance only. + // We are interested into the Z span only, therefore it is sufficient to measure the bounding box of the 1st instance only. bbox.merge(model_object->instance_bounding_box(0, false)); for (ModelObject *model_object : model.objects) for (ModelInstance *model_instance : model_object->instances) @@ -211,7 +211,7 @@ int CLI::run(int argc, char **argv) for (auto &model : m_models) { BoundingBoxf3 bb = model.bounding_box(); // this affects volumes: - model.translate(-(bb.min.x() - p.x()), -(bb.min.y() - p.y()), -bb.min.z()); + model.translate(-(bb.min.x() - p.x()), -(bb.min.y() - p.y()), -bb.min.z()); } } else if (opt_key == "dont_arrange") { // do nothing - this option alters other transform options @@ -249,8 +249,8 @@ int CLI::run(int argc, char **argv) std::vector new_models; for (auto &model : m_models) { model.translate(0, 0, -model.bounding_box().min.z()); // align to z = 0 - size_t num_objects = model.objects.size(); - for (size_t i = 0; i < num_objects; ++ i) { + size_t num_objects = model.objects.size(); + for (size_t i = 0; i < num_objects; ++ i) { #if 0 if (opt_key == "cut_x") { @@ -261,15 +261,15 @@ int CLI::run(int argc, char **argv) o->cut(Z, m_config.opt_float("cut"), &out); } #else - model.objects.front()->cut(0, m_config.opt_float("cut"), true, true, true); + model.objects.front()->cut(0, m_config.opt_float("cut"), true, true, true); #endif - model.delete_object(size_t(0)); + model.delete_object(size_t(0)); } } - + // TODO: copy less stuff around using pointers m_models = new_models; - + if (m_actions.empty()) m_actions.push_back("export_stl"); } @@ -279,7 +279,7 @@ int CLI::run(int argc, char **argv) for (auto &model : m_models) { TriangleMesh mesh = model.mesh(); mesh.repair(); - + TriangleMeshPtrs meshes = mesh.cut_by_grid(m_config.option("cut_grid")->value); size_t i = 0; for (TriangleMesh* m : meshes) { @@ -290,10 +290,10 @@ int CLI::run(int argc, char **argv) delete m; } } - + // TODO: copy less stuff around using pointers m_models = new_models; - + if (m_actions.empty()) m_actions.push_back("export_stl"); } @@ -307,7 +307,7 @@ int CLI::run(int argc, char **argv) } } } else if (opt_key == "repair") { - // Models are repaired by default. + // Models are repaired by default. //for (auto &model : m_models) // model.repair(); } else { @@ -315,7 +315,7 @@ int CLI::run(int argc, char **argv) return 1; } } - + // loop through action options for (auto const &opt_key : m_actions) { if (opt_key == "help") { @@ -358,14 +358,14 @@ int CLI::run(int argc, char **argv) boost::nowide::cerr << "error: cannot export SLA slices for a SLA configuration" << std::endl; return 1; } - // Make a copy of the model if the current action is not the last action, as the model may be - // modified by the centering and such. - Model model_copy; - bool make_copy = &opt_key != &m_actions.back(); + // Make a copy of the model if the current action is not the last action, as the model may be + // modified by the centering and such. + Model model_copy; + bool make_copy = &opt_key != &m_actions.back(); for (Model &model_in : m_models) { - if (make_copy) - model_copy = model_in; - Model &model = make_copy ? model_copy : model_in; + if (make_copy) + model_copy = model_in; + Model &model = make_copy ? model_copy : model_in; // If all objects have defined instances, their relative positions will be // honored when printing (they will be only centered, unless --dont-arrange // is supplied); if any object has no instances, it will get a default one @@ -385,7 +385,7 @@ 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(m_config.option("center")->value); } if (printer_technology == ptFFF) { for (auto* mo : model.objects) @@ -399,40 +399,40 @@ int CLI::run(int argc, char **argv) } if (print->empty()) boost::nowide::cout << "Nothing to print for " << outfile << " . Either the print is empty or no object is fully inside the print volume." << std::endl; - else + else try { std::string outfile_final; - print->process(); + print->process(); if (printer_technology == ptFFF) { // The outfile is processed by a PlaceholderParser. outfile = fff_print.export_gcode(outfile, nullptr); outfile_final = fff_print.print_statistics().finalize_output_path(outfile); } else { - outfile = sla_print.output_filepath(outfile); + outfile = sla_print.output_filepath(outfile); // We need to finalize the filename beforehand because the export function sets the filename inside the zip metadata outfile_final = sla_print.print_statistics().finalize_output_path(outfile); - sla_print.export_raster(outfile_final); + sla_print.export_raster(outfile_final); } if (outfile != outfile_final && Slic3r::rename_file(outfile, outfile_final) != 0) { - boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl; + boost::nowide::cerr << "Renaming file " << outfile << " to " << outfile_final << " failed" << std::endl; return 1; } boost::nowide::cout << "Slicing result exported to " << outfile << std::endl; } catch (const std::exception &ex) { - boost::nowide::cerr << ex.what() << std::endl; - return 1; + boost::nowide::cerr << ex.what() << std::endl; + return 1; } /* print.center = ! m_config.has("center") && ! m_config.has("align_xy") && ! m_config.opt_bool("dont_arrange"); print.set_model(model); - + // start chronometer typedef std::chrono::high_resolution_clock clock_; typedef std::chrono::duration > second_; std::chrono::time_point t0{ clock_::now() }; - + const std::string outfile = this->output_filepath(model, IO::Gcode); try { print.export_gcode(outfile); @@ -441,7 +441,7 @@ int CLI::run(int argc, char **argv) return 1; } boost::nowide::cout << "G-code exported to " << outfile << std::endl; - + // output some statistics double duration { std::chrono::duration_cast(clock_::now() - t0).count() }; boost::nowide::cout << std::fixed << std::setprecision(0) @@ -458,45 +458,45 @@ int CLI::run(int argc, char **argv) return 1; } } - - if (start_gui) { + + if (start_gui) { #ifdef SLIC3R_GUI // #ifdef USE_WX - GUI::GUI_App *gui = new GUI::GUI_App(); + GUI::GUI_App *gui = new GUI::GUI_App(); // gui->autosave = m_config.opt_string("autosave"); - GUI::GUI_App::SetInstance(gui); - gui->CallAfter([gui, this, &load_configs] { - if (!gui->initialized()) { - return; - } + GUI::GUI_App::SetInstance(gui); + gui->CallAfter([gui, this, &load_configs] { + if (!gui->initialized()) { + return; + } #if 0 - // Load the cummulative config over the currently active profiles. - //FIXME if multiple configs are loaded, only the last one will have an effect. - // We need to decide what to do about loading of separate presets (just print preset, just filament preset etc). - // As of now only the full configs are supported here. - if (!m_print_config.empty()) - gui->mainframe->load_config(m_print_config); + // Load the cummulative config over the currently active profiles. + //FIXME if multiple configs are loaded, only the last one will have an effect. + // We need to decide what to do about loading of separate presets (just print preset, just filament preset etc). + // As of now only the full configs are supported here. + if (!m_print_config.empty()) + gui->mainframe->load_config(m_print_config); #endif - if (! load_configs.empty()) - // Load the last config to give it a name at the UI. The name of the preset may be later - // changed by loading an AMF or 3MF. - //FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config. - gui->mainframe->load_config_file(load_configs.back()); - // If loading a 3MF file, the config is loaded from the last one. - if (! m_input_files.empty()) - gui->plater()->load_files(m_input_files, true, true); - if (! m_extra_config.empty()) - gui->mainframe->load_config(m_extra_config); - }); - return wxEntry(argc, argv); + if (! load_configs.empty()) + // Load the last config to give it a name at the UI. The name of the preset may be later + // changed by loading an AMF or 3MF. + //FIXME this is not strictly correct, as one may pass a print/filament/printer profile here instead of a full config. + gui->mainframe->load_config_file(load_configs.back()); + // If loading a 3MF file, the config is loaded from the last one. + if (! m_input_files.empty()) + gui->plater()->load_files(m_input_files, true, true); + if (! m_extra_config.empty()) + gui->mainframe->load_config(m_extra_config); + }); + return wxEntry(argc, argv); #else /* SLIC3R_GUI */ - // No GUI support. Just print out a help. - this->print_help(false); - // If started without a parameter, consider it to be OK, otherwise report an error code (no action etc). - return (argc == 0) ? 0 : 1; + // No GUI support. Just print out a help. + this->print_help(false); + // If started without a parameter, consider it to be OK, otherwise report an error code (no action etc). + return (argc == 0) ? 0 : 1; #endif /* SLIC3R_GUI */ } - + return 0; } @@ -544,18 +544,18 @@ bool CLI::setup(int argc, char **argv) // If any option is unsupported, print usage and abort immediately. t_config_option_keys opt_order; if (! m_config.read_cli(argc, argv, &m_input_files, &opt_order)) { - // Separate error message reported by the CLI parser from the help. - boost::nowide::cerr << std::endl; + // Separate error message reported by the CLI parser from the help. + boost::nowide::cerr << std::endl; this->print_help(); - return false; + return false; + } + // Parse actions and transform options. + for (auto const &opt_key : opt_order) { + if (cli_actions_config_def.has(opt_key)) + m_actions.emplace_back(opt_key); + else if (cli_transform_config_def.has(opt_key)) + m_transforms.emplace_back(opt_key); } - // Parse actions and transform options. - for (auto const &opt_key : opt_order) { - if (cli_actions_config_def.has(opt_key)) - m_actions.emplace_back(opt_key); - else if (cli_transform_config_def.has(opt_key)) - m_transforms.emplace_back(opt_key); - } { const ConfigOptionInt *opt_loglevel = m_config.opt("loglevel"); @@ -568,15 +568,15 @@ bool CLI::setup(int argc, char **argv) for (const std::pair &optdef : *options) m_config.optptr(optdef.first, true); - set_data_dir(m_config.opt_string("datadir")); + set_data_dir(m_config.opt_string("datadir")); - return true; + return true; } -void CLI::print_help(bool include_print_options, PrinterTechnology printer_technology) const +void CLI::print_help(bool include_print_options, PrinterTechnology printer_technology) const { boost::nowide::cout - << SLIC3R_BUILD_ID << " " << "based on Slic3r" + << SLIC3R_BUILD_ID << " " << "based on Slic3r" #ifdef SLIC3R_GUI << " (with GUI support)" #else /* SLIC3R_GUI */ @@ -588,20 +588,20 @@ void CLI::print_help(bool include_print_options, PrinterTechnology printer_techn << std::endl << "Actions:" << std::endl; cli_actions_config_def.print_cli_help(boost::nowide::cout, false); - + boost::nowide::cout << std::endl << "Transform options:" << std::endl; cli_transform_config_def.print_cli_help(boost::nowide::cout, false); - + boost::nowide::cout << std::endl << "Other options:" << std::endl; cli_misc_config_def.print_cli_help(boost::nowide::cout, false); - + if (include_print_options) { boost::nowide::cout << std::endl; - print_config_def.print_cli_help(boost::nowide::cout, true, [printer_technology](const ConfigOptionDef &def) + print_config_def.print_cli_help(boost::nowide::cout, true, [printer_technology](const ConfigOptionDef &def) { return printer_technology == ptAny || def.printer_technology == ptAny || printer_technology == def.printer_technology; }); } else { boost::nowide::cout @@ -618,14 +618,14 @@ bool CLI::export_models(IO::ExportFormat format) switch (format) { case IO::AMF: success = Slic3r::store_amf(path.c_str(), &model, nullptr); break; case IO::OBJ: success = Slic3r::store_obj(path.c_str(), &model); break; - case IO::STL: success = Slic3r::store_stl(path.c_str(), &model, true); break; - case IO::TMF: success = Slic3r::store_3mf(path.c_str(), &model, nullptr); break; + case IO::STL: success = Slic3r::store_stl(path.c_str(), &model, true); break; + case IO::TMF: success = Slic3r::store_3mf(path.c_str(), &model, nullptr); break; default: assert(false); break; } if (success) - std::cout << "File exported to " << path << std::endl; + std::cout << "File exported to " << path << std::endl; else { - std::cerr << "File export to " << path << " failed" << std::endl; + std::cerr << "File export to " << path << " failed" << std::endl; return false; } } @@ -639,12 +639,12 @@ std::string CLI::output_filepath(const Model &model, IO::ExportFormat format) co case IO::AMF: ext = ".zip.amf"; break; case IO::OBJ: ext = ".obj"; break; case IO::STL: ext = ".stl"; break; - case IO::TMF: ext = ".3mf"; break; + case IO::TMF: ext = ".3mf"; break; default: assert(false); break; }; auto proposed_path = boost::filesystem::path(model.propose_export_file_name_and_path(ext)); // use --output when available - std::string cmdline_param = m_config.opt_string("output"); + std::string cmdline_param = m_config.opt_string("output"); if (! cmdline_param.empty()) { // if we were supplied a directory, use it and append our automatically generated filename boost::filesystem::path cmdline_path(cmdline_param); @@ -656,20 +656,20 @@ std::string CLI::output_filepath(const Model &model, IO::ExportFormat format) co return proposed_path.string(); } -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW32__) extern "C" { - __declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv) - { - // Convert wchar_t arguments to UTF8. - std::vector argv_narrow; - std::vector argv_ptrs(argc + 1, nullptr); - for (size_t i = 0; i < argc; ++ i) - argv_narrow.emplace_back(boost::nowide::narrow(argv[i])); - for (size_t i = 0; i < argc; ++ i) - argv_ptrs[i] = const_cast(argv_narrow[i].data()); - // Call the UTF8 main. - return CLI().run(argc, argv_ptrs.data()); - } + __declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv) + { + // Convert wchar_t arguments to UTF8. + std::vector argv_narrow; + std::vector argv_ptrs(argc + 1, nullptr); + for (size_t i = 0; i < argc; ++ i) + argv_narrow.emplace_back(boost::nowide::narrow(argv[i])); + for (size_t i = 0; i < argc; ++ i) + argv_ptrs[i] = const_cast(argv_narrow[i].data()); + // Call the UTF8 main. + return CLI().run(argc, argv_ptrs.data()); + } } #else /* _MSC_VER */ int main(int argc, char **argv) diff --git a/src/PrusaSlicer_app_msvc.cpp b/src/PrusaSlicer_app_msvc.cpp index 95dd4fb075..b3d1e8bb47 100644 --- a/src/PrusaSlicer_app_msvc.cpp +++ b/src/PrusaSlicer_app_msvc.cpp @@ -8,12 +8,12 @@ #include #ifdef SLIC3R_GUI -extern "C" -{ - // Let the NVIDIA and AMD know we want to use their graphics card - // on a dual graphics card system. - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; +extern "C" +{ + // Let the NVIDIA and AMD know we want to use their graphics card + // on a dual graphics card system. + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif /* SLIC3R_GUI */ @@ -21,7 +21,7 @@ extern "C" #include #ifdef SLIC3R_GUI - #include + #include #endif /* SLIC3R_GUI */ #include @@ -36,97 +36,97 @@ extern "C" class OpenGLVersionCheck { public: - std::string version; - std::string glsl_version; - std::string vendor; - std::string renderer; + std::string version; + std::string glsl_version; + std::string vendor; + std::string renderer; - HINSTANCE hOpenGL = nullptr; - bool success = false; + HINSTANCE hOpenGL = nullptr; + bool success = false; - bool load_opengl_dll() - { - MSG msg = {0}; - WNDCLASS wc = {0}; - wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc; - wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr); - wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); - wc.lpszClassName = L"PrusaSlicer_opengl_version_check"; - wc.style = CS_OWNDC; - if (RegisterClass(&wc)) { - HWND hwnd = CreateWindowW(wc.lpszClassName, L"PrusaSlicer_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this); - if (hwnd) { - message_pump_exit = false; - while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit) - DispatchMessage(&msg); - } - } - return this->success; - } + bool load_opengl_dll() + { + MSG msg = {0}; + WNDCLASS wc = {0}; + wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc; + wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr); + wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); + wc.lpszClassName = L"PrusaSlicer_opengl_version_check"; + wc.style = CS_OWNDC; + if (RegisterClass(&wc)) { + HWND hwnd = CreateWindowW(wc.lpszClassName, L"PrusaSlicer_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this); + if (hwnd) { + message_pump_exit = false; + while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit) + DispatchMessage(&msg); + } + } + return this->success; + } - void unload_opengl_dll() - { - if (this->hOpenGL) { - BOOL released = FreeLibrary(this->hOpenGL); - if (released) - printf("System OpenGL library released\n"); - else - printf("System OpenGL library NOT released\n"); - this->hOpenGL = nullptr; - } - } + void unload_opengl_dll() + { + if (this->hOpenGL) { + BOOL released = FreeLibrary(this->hOpenGL); + if (released) + printf("System OpenGL library released\n"); + else + printf("System OpenGL library NOT released\n"); + this->hOpenGL = nullptr; + } + } - bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const - { - // printf("is_version_greater_or_equal_to, version: %s\n", version.c_str()); - std::vector tokens; - boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); - if (tokens.empty()) - return false; + bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const + { + // printf("is_version_greater_or_equal_to, version: %s\n", version.c_str()); + std::vector tokens; + boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); + if (tokens.empty()) + return false; - std::vector numbers; - boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on); + std::vector numbers; + boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on); - unsigned int gl_major = 0; - unsigned int gl_minor = 0; - if (numbers.size() > 0) - gl_major = ::atoi(numbers[0].c_str()); - if (numbers.size() > 1) - gl_minor = ::atoi(numbers[1].c_str()); - // printf("Major: %d, minor: %d\n", gl_major, gl_minor); - if (gl_major < major) - return false; - else if (gl_major > major) - return true; - else - return gl_minor >= minor; - } + unsigned int gl_major = 0; + unsigned int gl_minor = 0; + if (numbers.size() > 0) + gl_major = ::atoi(numbers[0].c_str()); + if (numbers.size() > 1) + gl_minor = ::atoi(numbers[1].c_str()); + // printf("Major: %d, minor: %d\n", gl_major, gl_minor); + if (gl_major < major) + return false; + else if (gl_major > major) + return true; + else + return gl_minor >= minor; + } protected: - static bool message_pump_exit; + static bool message_pump_exit; - void check(HWND hWnd) - { - hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0); - if (hOpenGL == nullptr) { - printf("Failed loading the system opengl32.dll\n"); - return; - } + void check(HWND hWnd) + { + hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0); + if (hOpenGL == nullptr) { + printf("Failed loading the system opengl32.dll\n"); + return; + } - typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC); - typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC); - typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC); - typedef GLubyte* (WINAPI *Func_glGetString )(GLenum); + typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC); + typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC); + typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC); + typedef GLubyte* (WINAPI *Func_glGetString )(GLenum); - Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext"); - Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent"); - Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext"); - Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString"); + Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext"); + Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent"); + Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext"); + Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString"); - if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) { - printf("Failed loading the system opengl32.dll: The library is invalid.\n"); - return; - } + if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) { + printf("Failed loading the system opengl32.dll: The library is invalid.\n"); + return; + } PIXELFORMATDESCRIPTOR pfd = { @@ -149,152 +149,155 @@ protected: }; HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd); - // Gdi32.dll - int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); - // Gdi32.dll + // Gdi32.dll + int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); + // Gdi32.dll SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd); - // Opengl32.dll + // Opengl32.dll HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext); wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext); // Opengl32.dll - const char *data = (const char*)glGetString(GL_VERSION); - if (data != nullptr) - this->version = data; - // printf("check -version: %s\n", version.c_str()); - data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION - if (data != nullptr) - this->glsl_version = data; - data = (const char*)glGetString(GL_VENDOR); - if (data != nullptr) - this->vendor = data; - data = (const char*)glGetString(GL_RENDERER); - if (data != nullptr) - this->renderer = data; + const char *data = (const char*)glGetString(GL_VERSION); + if (data != nullptr) + this->version = data; + // printf("check -version: %s\n", version.c_str()); + data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION + if (data != nullptr) + this->glsl_version = data; + data = (const char*)glGetString(GL_VENDOR); + if (data != nullptr) + this->vendor = data; + data = (const char*)glGetString(GL_RENDERER); + if (data != nullptr) + this->renderer = data; // Opengl32.dll wglDeleteContext(glcontext); - ::ReleaseDC(hWnd, ourWindowHandleToDeviceContext); + ::ReleaseDC(hWnd, ourWindowHandleToDeviceContext); this->success = true; - } + } - static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) - { - switch(message) - { - case WM_CREATE: - { - CREATESTRUCT *pCreate = reinterpret_cast(lParam); - OpenGLVersionCheck *ogl_data = reinterpret_cast(pCreate->lpCreateParams); - ogl_data->check(hWnd); - DestroyWindow(hWnd); - return 0; - } - case WM_NCDESTROY: - message_pump_exit = true; - return 0; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - } + static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) + { + switch(message) + { + case WM_CREATE: + { + CREATESTRUCT *pCreate = reinterpret_cast(lParam); + OpenGLVersionCheck *ogl_data = reinterpret_cast(pCreate->lpCreateParams); + ogl_data->check(hWnd); + DestroyWindow(hWnd); + return 0; + } + case WM_NCDESTROY: + message_pump_exit = true; + return 0; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + } }; bool OpenGLVersionCheck::message_pump_exit = false; #endif /* SLIC3R_GUI */ extern "C" { - typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv); - Slic3rMainFunc slic3r_main = nullptr; + typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv); + Slic3rMainFunc slic3r_main = nullptr; } +extern "C" { + #ifdef SLIC3R_WRAPPER_NOCONSOLE int APIENTRY wWinMain(HINSTANCE /* hInstance */, HINSTANCE /* hPrevInstance */, PWSTR /* lpCmdLine */, int /* nCmdShow */) { - int argc; - wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + int argc; + wchar_t **argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); #else int wmain(int argc, wchar_t **argv) { #endif - std::vector argv_extended; - argv_extended.emplace_back(argv[0]); + std::vector argv_extended; + argv_extended.emplace_back(argv[0]); #ifdef SLIC3R_GUI - // Here one may push some additional parameters based on the wrapper type. - bool force_mesa = false; + // Here one may push some additional parameters based on the wrapper type. + bool force_mesa = false; #endif /* SLIC3R_GUI */ - for (int i = 1; i < argc; ++ i) { + for (int i = 1; i < argc; ++ i) { #ifdef SLIC3R_GUI - if (wcscmp(argv[i], L"--sw-renderer") == 0) - force_mesa = true; - else if (wcscmp(argv[i], L"--no-sw-renderer") == 0) - force_mesa = false; + if (wcscmp(argv[i], L"--sw-renderer") == 0) + force_mesa = true; + else if (wcscmp(argv[i], L"--no-sw-renderer") == 0) + force_mesa = false; #endif /* SLIC3R_GUI */ - argv_extended.emplace_back(argv[i]); - } - argv_extended.emplace_back(nullptr); + argv_extended.emplace_back(argv[i]); + } + argv_extended.emplace_back(nullptr); #ifdef SLIC3R_GUI - OpenGLVersionCheck opengl_version_check; - bool load_mesa = - // Forced from the command line. - force_mesa || - // Running over a rempote desktop, and the RemoteFX is not enabled, therefore Windows will only provide SW OpenGL 1.1 context. - // In that case, use Mesa. - ::GetSystemMetrics(SM_REMOTESESSION) || - // Try to load the default OpenGL driver and test its context version. - ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); + OpenGLVersionCheck opengl_version_check; + bool load_mesa = + // Forced from the command line. + force_mesa || + // Running over a rempote desktop, and the RemoteFX is not enabled, therefore Windows will only provide SW OpenGL 1.1 context. + // In that case, use Mesa. + ::GetSystemMetrics(SM_REMOTESESSION) || + // Try to load the default OpenGL driver and test its context version. + ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); #endif /* SLIC3R_GUI */ - wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; - ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); - wchar_t drive[_MAX_DRIVE]; - wchar_t dir[_MAX_DIR]; - wchar_t fname[_MAX_FNAME]; - wchar_t ext[_MAX_EXT]; - _wsplitpath(path_to_exe, drive, dir, fname, ext); - _wmakepath(path_to_exe, drive, dir, nullptr, nullptr); + wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; + ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); + wchar_t drive[_MAX_DRIVE]; + wchar_t dir[_MAX_DIR]; + wchar_t fname[_MAX_FNAME]; + wchar_t ext[_MAX_EXT]; + _wsplitpath(path_to_exe, drive, dir, fname, ext); + _wmakepath(path_to_exe, drive, dir, nullptr, nullptr); #ifdef SLIC3R_GUI // https://wiki.qt.io/Cross_compiling_Mesa_for_Windows // http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/ - if (load_mesa) { - opengl_version_check.unload_opengl_dll(); - wchar_t path_to_mesa[MAX_PATH + 1] = { 0 }; - wcscpy(path_to_mesa, path_to_exe); - wcscat(path_to_mesa, L"mesa\\opengl32.dll"); - printf("Loading MESA OpenGL library: %S\n", path_to_mesa); - HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0); - if (hInstance_OpenGL == nullptr) { - printf("MESA OpenGL library was not loaded\n"); - } else - printf("MESA OpenGL library was loaded sucessfully\n"); - } + if (load_mesa) { + opengl_version_check.unload_opengl_dll(); + wchar_t path_to_mesa[MAX_PATH + 1] = { 0 }; + wcscpy(path_to_mesa, path_to_exe); + wcscat(path_to_mesa, L"mesa\\opengl32.dll"); + printf("Loading MESA OpenGL library: %S\n", path_to_mesa); + HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0); + if (hInstance_OpenGL == nullptr) { + printf("MESA OpenGL library was not loaded\n"); + } else + printf("MESA OpenGL library was loaded sucessfully\n"); + } #endif /* SLIC3R_GUI */ - wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 }; - wcscpy(path_to_slic3r, path_to_exe); - wcscat(path_to_slic3r, L"PrusaSlicer.dll"); + wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 }; + wcscpy(path_to_slic3r, path_to_exe); + wcscat(path_to_slic3r, L"PrusaSlicer.dll"); // printf("Loading Slic3r library: %S\n", path_to_slic3r); - HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0); - if (hInstance_Slic3r == nullptr) { - printf("PrusaSlicer.dll was not loaded\n"); - return -1; - } + HINSTANCE hInstance_Slic3r = LoadLibraryExW(path_to_slic3r, nullptr, 0); + if (hInstance_Slic3r == nullptr) { + printf("PrusaSlicer.dll was not loaded\n"); + return -1; + } - // resolve function address here - slic3r_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r, + // resolve function address here + slic3r_main = (Slic3rMainFunc)GetProcAddress(hInstance_Slic3r, #ifdef _WIN64 - // there is just a single calling conversion, therefore no mangling of the function name. - "slic3r_main" + // there is just a single calling conversion, therefore no mangling of the function name. + "slic3r_main" #else // stdcall calling convention declaration - "_slic3r_main@8" + "_slic3r_main@8" #endif - ); - if (slic3r_main == nullptr) { - printf("could not locate the function slic3r_main in PrusaSlicer.dll\n"); - return -1; - } - // argc minus the trailing nullptr of the argv - return slic3r_main((int)argv_extended.size() - 1, argv_extended.data()); + ); + if (slic3r_main == nullptr) { + printf("could not locate the function slic3r_main in PrusaSlicer.dll\n"); + return -1; + } + // argc minus the trailing nullptr of the argv + return slic3r_main((int)argv_extended.size() - 1, argv_extended.data()); +} } diff --git a/src/avrdude/CMakeLists.txt b/src/avrdude/CMakeLists.txt index 0e9b9e6d4d..a1930ad5f9 100644 --- a/src/avrdude/CMakeLists.txt +++ b/src/avrdude/CMakeLists.txt @@ -74,6 +74,10 @@ if (MSVC) windows/unistd.cpp windows/getopt.c ) +elseif (MINGW) + set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES} + windows/utf8.c + ) endif() add_executable(avrdude-conf-gen conf-generate.cpp) @@ -98,5 +102,7 @@ target_link_libraries(avrdude-slic3r avrdude) if (WIN32) target_compile_definitions(avrdude PRIVATE WIN32NATIVE=1) - target_include_directories(avrdude SYSTEM PRIVATE windows) # So that sources find the getopt.h windows drop-in + if(MSVC) + target_include_directories(avrdude SYSTEM PRIVATE windows) # So that sources find the getopt.h windows drop-in + endif(MSVC) endif() diff --git a/src/avrdude/lexer.c b/src/avrdude/lexer.c index f2d8adb4bc..46d88170f5 100644 --- a/src/avrdude/lexer.c +++ b/src/avrdude/lexer.c @@ -30,7 +30,7 @@ /* C99 systems have . Non-C99 systems may or may not. */ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(_MSC_VER) /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. diff --git a/src/avrdude/main-standalone.cpp b/src/avrdude/main-standalone.cpp index df6d79e136..f7cd6d1d4a 100644 --- a/src/avrdude/main-standalone.cpp +++ b/src/avrdude/main-standalone.cpp @@ -38,6 +38,10 @@ struct ArgvUtf8 : std::vector } }; +#endif + +#ifdef _MSC_VER + int wmain(int argc_w, wchar_t *argv_w[]) { ArgvUtf8 argv_utf8(argc_w, argv_w); diff --git a/src/avrdude/windows/unistd.h b/src/avrdude/windows/unistd.h index 95ba79a346..c88b780bfa 100644 --- a/src/avrdude/windows/unistd.h +++ b/src/avrdude/windows/unistd.h @@ -63,10 +63,15 @@ extern "C" { #define STDOUT_FILENO 1 #define STDERR_FILENO 2 +#if defined(_MSC_VER) && defined(__clang__) +#include +struct timezone; +struct timeval; +#else #ifndef __cplusplus /* should be in some equivalent to */ typedef __int8 int8_t; -typedef __int16 int16_t; +typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; @@ -74,6 +79,7 @@ typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #endif +#endif int usleep(unsigned usec); diff --git a/src/libigl/igl/SortableRow.h b/src/libigl/igl/SortableRow.h index 5f172987bf..182bf81343 100644 --- a/src/libigl/igl/SortableRow.h +++ b/src/libigl/igl/SortableRow.h @@ -1,9 +1,9 @@ // This file is part of libigl, a simple c++ geometry processing library. -// +// // Copyright (C) 2013 Alec Jacobson -// -// This Source Code Form is subject to the terms of the Mozilla Public License -// v. 2.0. If a copy of the MPL was not distributed with this file, You can +// +// This Source Code Form is subject to the terms of the Mozilla Public License +// v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #ifndef IGL_SORTABLE_ROW_H #define IGL_SORTABLE_ROW_H @@ -14,57 +14,53 @@ namespace igl { - // Templates: - // T should be a matrix that implements .size(), and operator(int i) - template - class SortableRow - { - public: - T data; - public: - SortableRow():data(){}; - SortableRow(const T & data):data(data){}; - bool operator<(const SortableRow & that) const - { - // Get reference so that I can use parenthesis - const SortableRow & THIS = *this; +// Templates: +// T should be a matrix that implements .size(), and operator(int i) +template +class SortableRow +{ +public: + T data; +public: + SortableRow():data(){}; + SortableRow(const T & data):data(data){}; + bool operator<(const SortableRow & that) const + { // Lexicographical - int minc = (THIS.data.size() < that.data.size()? - THIS.data.size() : that.data.size()); + int minc = (this->data.size() < that.data.size()? + this->data.size() : that.data.size()); // loop over columns for(int i = 0;idata(i) == that.data(i)) + { + continue; + } + return this->data(i) < that.data(i); } // All characters the same, comes done to length - return THIS.data.size() & THIS = *this; - if(THIS.data.size() != that.data.size()) + return this->data.size()data.size() != that.data.size()) { - return false; - } - for(int i = 0;idata.size();i++) + { + if(this->data(i) != that.data(i)) + { + return false; + } } return true; - }; - bool operator!=(const SortableRow & that) const - { + }; + bool operator!=(const SortableRow & that) const + { return !(*this == that); - }; - }; + }; +}; } #endif diff --git a/src/libnest2d/include/libnest2d/backends/clipper/geometries.hpp b/src/libnest2d/include/libnest2d/backends/clipper/geometries.hpp index 06afbd1872..56330e15e7 100644 --- a/src/libnest2d/include/libnest2d/backends/clipper/geometries.hpp +++ b/src/libnest2d/include/libnest2d/backends/clipper/geometries.hpp @@ -337,7 +337,15 @@ merge(const TMultiShape& shapes) //#define DISABLE_BOOST_SERIALIZE //#define DISABLE_BOOST_UNSERIALIZE +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4244) +#pragma warning(disable: 4267) +#endif // All other operators and algorithms are implemented with boost #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif #endif // CLIPPER_BACKEND_HPP diff --git a/src/libnest2d/tests/test.cpp b/src/libnest2d/tests/test.cpp index 29577344d1..4a6691415f 100644 --- a/src/libnest2d/tests/test.cpp +++ b/src/libnest2d/tests/test.cpp @@ -7,6 +7,10 @@ #include "../tools/svgtools.hpp" #include +#if defined(_MSC_VER) && defined(__clang__) +#define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif + #include "boost/multiprecision/integer.hpp" #include "boost/rational.hpp" diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index 76ad81e299..f04e051624 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -12,6 +12,11 @@ #include #include + +#if defined(_MSC_VER) && defined(__clang__) +#define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif + #include #include @@ -128,8 +133,18 @@ protected: PConfig m_pconf; // Placement configuration TBin m_bin; double m_bin_area; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4244) +#pragma warning(disable: 4267) +#endif SpatIndex m_rtree; // spatial index for the normal (bigger) objects SpatIndex m_smallsrtree; // spatial index for only the smaller items +#ifdef _MSC_VER +#pragma warning(pop) +#endif + double m_norm; // A coefficient to scale distances MultiPolygon m_merged_pile; // The already merged pile (vector of items) Box m_pilebb; // The bounding box of the merged pile. diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 4842b51239..1ebd922e20 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -5,6 +5,10 @@ include(PrecompiledHeader) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libslic3r_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h @ONLY) +if (MINGW) + add_compile_options(-Wa,-mbig-obj) +endif () + add_library(libslic3r STATIC pchheader.cpp pchheader.hpp @@ -70,7 +74,7 @@ add_library(libslic3r STATIC GCode/CoolingBuffer.cpp GCode/CoolingBuffer.hpp GCode/PostProcessor.cpp - GCode/PostProcessor.hpp + GCode/PostProcessor.hpp # GCode/PressureEqualizer.cpp # GCode/PressureEqualizer.hpp GCode/PreviewData.cpp diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 18437c8e16..9280aa33a4 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -101,23 +101,6 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool this->collect_extruder_statistics(prime_multi_material); } - -LayerTools& ToolOrdering::tools_for_layer(coordf_t print_z) -{ - auto it_layer_tools = std::lower_bound(m_layer_tools.begin(), m_layer_tools.end(), LayerTools(print_z - EPSILON)); - assert(it_layer_tools != m_layer_tools.end()); - coordf_t dist_min = std::abs(it_layer_tools->print_z - print_z); - for (++ it_layer_tools; it_layer_tools != m_layer_tools.end(); ++it_layer_tools) { - coordf_t d = std::abs(it_layer_tools->print_z - print_z); - if (d >= dist_min) - break; - dist_min = d; - } - -- it_layer_tools; - assert(dist_min < EPSILON); - return *it_layer_tools; -} - void ToolOrdering::initialize_layers(std::vector &zs) { sort_remove_duplicates(zs); @@ -156,7 +139,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object) LayerTools &layer_tools = this->tools_for_layer(layer->print_z); // What extruders are required to print this object layer? for (size_t region_id = 0; region_id < object.region_volumes.size(); ++ region_id) { - const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr; + const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr; if (layerm == nullptr) continue; const PrintRegion ®ion = *object.print()->regions()[region_id]; @@ -336,10 +319,10 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // If it is a bug, it's likely not critical, because this code is unchanged for a long time. It might // still be worth looking into it more and decide if it is a bug or an obsolete assert. //assert(lt_prev.extruders.back() == lt_next.extruders.front()); - lt_extra.has_wipe_tower = true; + lt_extra.has_wipe_tower = true; lt_extra.extruders.push_back(lt_next.extruders.front()); - lt_extra.wipe_tower_partitions = lt_next.wipe_tower_partitions; - } + lt_extra.wipe_tower_partitions = lt_next.wipe_tower_partitions; + } } } break; @@ -381,7 +364,7 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material) // Reorder m_all_printing_extruders in the sequence they will be primed, the last one will be m_first_printing_extruder. // Then set m_first_printing_extruder to the 1st extruder primed. m_all_printing_extruders.erase( - std::remove_if(m_all_printing_extruders.begin(), m_all_printing_extruders.end(), + std::remove_if(m_all_printing_extruders.begin(), m_all_printing_extruders.end(), [ this ](const unsigned int eid) { return eid == m_first_printing_extruder; }), m_all_printing_extruders.end()); m_all_printing_extruders.emplace_back(m_first_printing_extruder); @@ -629,6 +612,6 @@ const std::vector* WipingExtrusions::get_extruder_overrides(const Extrusion return &(entity_map_it->second); } - + } // namespace Slic3r diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index 538127810d..d4006120d2 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -102,45 +102,60 @@ private: class ToolOrdering { public: - ToolOrdering() {} + ToolOrdering() {} - // For the use case when each object is printed separately - // (print.config.complete_objects is true). - ToolOrdering(const PrintObject &object, unsigned int first_extruder = (unsigned int)-1, bool prime_multi_material = false); + // For the use case when each object is printed separately + // (print.config.complete_objects is true). + ToolOrdering(const PrintObject &object, unsigned int first_extruder = (unsigned int)-1, bool prime_multi_material = false); - // For the use case when all objects are printed at once. - // (print.config.complete_objects is false). - ToolOrdering(const Print &print, unsigned int first_extruder = (unsigned int)-1, bool prime_multi_material = false); + // For the use case when all objects are printed at once. + // (print.config.complete_objects is false). + ToolOrdering(const Print &print, unsigned int first_extruder = (unsigned int)-1, bool prime_multi_material = false); - void clear() { m_layer_tools.clear(); } + void clear() { m_layer_tools.clear(); } - // Get the first extruder printing, including the extruder priming areas, returns -1 if there is no layer printed. - unsigned int first_extruder() const { return m_first_printing_extruder; } + // Get the first extruder printing, including the extruder priming areas, returns -1 if there is no layer printed. + unsigned int first_extruder() const { return m_first_printing_extruder; } - // Get the first extruder printing the layer_tools, returns -1 if there is no layer printed. - unsigned int last_extruder() const { return m_last_printing_extruder; } + // Get the first extruder printing the layer_tools, returns -1 if there is no layer printed. + unsigned int last_extruder() const { return m_last_printing_extruder; } - // For a multi-material print, the printing extruders are ordered in the order they shall be primed. - const std::vector& all_extruders() const { return m_all_printing_extruders; } + // For a multi-material print, the printing extruders are ordered in the order they shall be primed. + const std::vector& all_extruders() const { return m_all_printing_extruders; } - // Find LayerTools with the closest print_z. - LayerTools& tools_for_layer(coordf_t print_z); - const LayerTools& tools_for_layer(coordf_t print_z) const - { return *const_cast(&const_cast(this)->tools_for_layer(print_z)); } + template static auto tools_for_layer(Self& self, coordf_t print_z) -> decltype (*self.m_layer_tools.begin()) + { + auto it_layer_tools = std::lower_bound(self.m_layer_tools.begin(), self.m_layer_tools.end(), LayerTools(print_z - EPSILON)); + assert(it_layer_tools != self.m_layer_tools.end()); + coordf_t dist_min = std::abs(it_layer_tools->print_z - print_z); + for (++ it_layer_tools; it_layer_tools != self.m_layer_tools.end(); ++it_layer_tools) { + coordf_t d = std::abs(it_layer_tools->print_z - print_z); + if (d >= dist_min) + break; + dist_min = d; + } + -- it_layer_tools; + assert(dist_min < EPSILON); + return *it_layer_tools; + } - const LayerTools& front() const { return m_layer_tools.front(); } - const LayerTools& back() const { return m_layer_tools.back(); } - std::vector::const_iterator begin() const { return m_layer_tools.begin(); } - std::vector::const_iterator end() const { return m_layer_tools.end(); } - bool empty() const { return m_layer_tools.empty(); } - std::vector& layer_tools() { return m_layer_tools; } - bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().wipe_tower_partitions > 0; } + // Find LayerTools with the closest print_z. + LayerTools& tools_for_layer(coordf_t print_z) { return tools_for_layer(*this, print_z); } + const LayerTools& tools_for_layer(coordf_t print_z) const { return tools_for_layer(*this, print_z); } + + const LayerTools& front() const { return m_layer_tools.front(); } + const LayerTools& back() const { return m_layer_tools.back(); } + std::vector::const_iterator begin() const { return m_layer_tools.begin(); } + std::vector::const_iterator end() const { return m_layer_tools.end(); } + bool empty() const { return m_layer_tools.empty(); } + std::vector& layer_tools() { return m_layer_tools; } + bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().wipe_tower_partitions > 0; } private: - void initialize_layers(std::vector &zs); - void collect_extruders(const PrintObject &object); - void reorder_extruders(unsigned int last_extruder_id); - void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z); + void initialize_layers(std::vector &zs); + void collect_extruders(const PrintObject &object); + void reorder_extruders(unsigned int last_extruder_id); + void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z); void collect_extruder_statistics(bool prime_multi_material); std::vector m_layer_tools; diff --git a/src/libslic3r/MinAreaBoundingBox.cpp b/src/libslic3r/MinAreaBoundingBox.cpp index fafb54a585..15c04517d0 100644 --- a/src/libslic3r/MinAreaBoundingBox.cpp +++ b/src/libslic3r/MinAreaBoundingBox.cpp @@ -1,6 +1,11 @@ #include "MinAreaBoundingBox.hpp" #include + +#if defined(_MSC_VER) && defined(__clang__) +#define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif + #include #include diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2033658640..31de80e8be 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3290,7 +3290,7 @@ CLIMiscConfigDef::CLIMiscConfigDef() def->tooltip = L("Messages with severity lower or eqal to the loglevel will be printed out. 0:trace, 1:debug, 2:info, 3:warning, 4:error, 5:fatal"); def->min = 0; -#if defined(_MSC_VER) && defined(SLIC3R_GUI) +#if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(SLIC3R_GUI) def = this->add("sw_renderer", coBool); def->label = L("Render with a software renderer"); def->tooltip = L("Render with a software renderer. The bundled MESA software renderer is loaded instead of the default OpenGL driver."); diff --git a/src/libslic3r/SLA/SLAAutoSupports.cpp b/src/libslic3r/SLA/SLAAutoSupports.cpp index 78efd08067..36378df395 100644 --- a/src/libslic3r/SLA/SLAAutoSupports.cpp +++ b/src/libslic3r/SLA/SLAAutoSupports.cpp @@ -1,5 +1,5 @@ -#include "igl/random_points_on_mesh.h" -#include "igl/AABB.h" +//#include "igl/random_points_on_mesh.h" +//#include "igl/AABB.h" #include @@ -101,7 +101,7 @@ static std::vector make_layers( std::vector layers; layers.reserve(slices.size()); for (size_t i = 0; i < slices.size(); ++ i) - layers.emplace_back(i, heights[i]); + layers.emplace_back(i, heights[i]); // FIXME: calculate actual pixel area from printer config: //const float pixel_area = pow(wxGetApp().preset_bundle->project_config.option("display_width") / wxGetApp().preset_bundle->project_config.option("display_pixels_x"), 2.f); // @@ -114,47 +114,47 @@ static std::vector make_layers( if ((layer_id % 8) == 0) // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves. throw_on_cancel(); - SLAAutoSupports::MyLayer &layer = layers[layer_id]; + SLAAutoSupports::MyLayer &layer = layers[layer_id]; const ExPolygons &islands = slices[layer_id]; //FIXME WTF? const float height = (layer_id>2 ? heights[layer_id-3] : heights[0]-(heights[1]-heights[0])); - layer.islands.reserve(islands.size()); + layer.islands.reserve(islands.size()); for (const ExPolygon &island : islands) { float area = float(island.area() * SCALING_FACTOR * SCALING_FACTOR); if (area >= pixel_area) //FIXME this is not a correct centroid of a polygon with holes. - layer.islands.emplace_back(layer, island, get_extents(island.contour), Slic3r::unscale(island.contour.centroid()).cast(), area, height); + layer.islands.emplace_back(layer, island, get_extents(island.contour), Slic3r::unscale(island.contour.centroid()).cast(), area, height); } } }); - // Calculate overlap of successive layers. Link overlapping islands. - tbb::parallel_for(tbb::blocked_range(1, layers.size(), 8), - [&layers, &heights, throw_on_cancel](const tbb::blocked_range& range) { - for (size_t layer_id = range.begin(); layer_id < range.end(); ++layer_id) { - if ((layer_id % 2) == 0) - // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves. - throw_on_cancel(); - SLAAutoSupports::MyLayer &layer_above = layers[layer_id]; - SLAAutoSupports::MyLayer &layer_below = layers[layer_id - 1]; + // Calculate overlap of successive layers. Link overlapping islands. + tbb::parallel_for(tbb::blocked_range(1, layers.size(), 8), + [&layers, &heights, throw_on_cancel](const tbb::blocked_range& range) { + for (size_t layer_id = range.begin(); layer_id < range.end(); ++layer_id) { + if ((layer_id % 2) == 0) + // Don't call the following function too often as it flushes CPU write caches due to synchronization primitves. + throw_on_cancel(); + SLAAutoSupports::MyLayer &layer_above = layers[layer_id]; + SLAAutoSupports::MyLayer &layer_below = layers[layer_id - 1]; //FIXME WTF? const float layer_height = (layer_id!=0 ? heights[layer_id]-heights[layer_id-1] : heights[0]); const float safe_angle = 5.f * (float(M_PI)/180.f); // smaller number - less supports const float between_layers_offset = float(scale_(layer_height / std::tan(safe_angle))); const float slope_angle = 75.f * (float(M_PI)/180.f); // smaller number - less supports const float slope_offset = float(scale_(layer_height / std::tan(slope_angle))); - //FIXME This has a quadratic time complexity, it will be excessively slow for many tiny islands. - for (SLAAutoSupports::Structure &top : layer_above.islands) { - for (SLAAutoSupports::Structure &bottom : layer_below.islands) { + //FIXME This has a quadratic time complexity, it will be excessively slow for many tiny islands. + for (SLAAutoSupports::Structure &top : layer_above.islands) { + for (SLAAutoSupports::Structure &bottom : layer_below.islands) { float overlap_area = top.overlap_area(bottom); if (overlap_area > 0) { - top.islands_below.emplace_back(&bottom, overlap_area); + top.islands_below.emplace_back(&bottom, overlap_area); bottom.islands_above.emplace_back(&top, overlap_area); } } if (! top.islands_below.empty()) { Polygons top_polygons = to_polygons(*top.polygon); - Polygons bottom_polygons = top.polygons_below(); + Polygons bottom_polygons = top.polygons_below(); top.overhangs = diff_ex(top_polygons, bottom_polygons); if (! top.overhangs.empty()) { top.overhangs_area = 0.f; @@ -164,21 +164,21 @@ static std::vector make_layers( expolys_with_areas.emplace_back(&ex, area); top.overhangs_area += area; } - std::sort(expolys_with_areas.begin(), expolys_with_areas.end(), + std::sort(expolys_with_areas.begin(), expolys_with_areas.end(), [](const std::pair &p1, const std::pair &p2) { return p1.second > p2.second; }); ExPolygons overhangs_sorted; for (auto &p : expolys_with_areas) overhangs_sorted.emplace_back(std::move(*p.first)); - top.overhangs = std::move(overhangs_sorted); + top.overhangs = std::move(overhangs_sorted); top.overhangs_area *= float(SCALING_FACTOR * SCALING_FACTOR); top.overhangs_slopes = diff_ex(top_polygons, offset(bottom_polygons, slope_offset)); top.dangling_areas = diff_ex(top_polygons, offset(bottom_polygons, between_layers_offset)); } } - } - } - }); + } + } + }); return layers; } @@ -207,14 +207,14 @@ void SLAAutoSupports::process(const std::vector& slices, const std:: support_force_bottom[i] = layer_bottom->islands[i].supports_force_total(); } for (Structure &top : layer_top->islands) - for (Structure::Link &bottom_link : top.islands_below) { + for (Structure::Link &bottom_link : top.islands_below) { Structure &bottom = *bottom_link.island; //float centroids_dist = (bottom.centroid - top.centroid).norm(); // Penalization resulting from centroid offset: // bottom.supports_force *= std::min(1.f, 1.f - std::min(1.f, (1600.f * layer_height) * centroids_dist * centroids_dist / bottom.area)); float &support_force = support_force_bottom[&bottom - layer_bottom->islands.data()]; //FIXME this condition does not reflect a bifurcation into a one large island and one tiny island well, it incorrectly resets the support force to zero. -// One should rather work with the overlap area vs overhang area. +// One should rather work with the overlap area vs overhang area. // support_force *= std::min(1.f, 1.f - std::min(1.f, 0.1f * centroids_dist * centroids_dist / bottom.area)); // Penalization resulting from increasing polygon area: support_force *= std::min(1.f, 20.f * bottom.area / top.area); @@ -224,10 +224,10 @@ void SLAAutoSupports::process(const std::vector& slices, const std:: for (Structure &below : layer_bottom->islands) { float below_support_force = support_force_bottom[&below - layer_bottom->islands.data()]; float above_overlap_area = 0.f; - for (Structure::Link &above_link : below.islands_above) - above_overlap_area += above_link.overlap_area; - for (Structure::Link &above_link : below.islands_above) - above_link.island->supports_force_inherited += below_support_force * above_link.overlap_area / above_overlap_area; + for (Structure::Link &above_link : below.islands_above) + above_overlap_area += above_link.overlap_area; + for (Structure::Link &above_link : below.islands_above) + above_link.island->supports_force_inherited += below_support_force * above_link.overlap_area / above_overlap_area; } } // Now iterate over all polygons and append new points if needed. @@ -266,7 +266,7 @@ void SLAAutoSupports::process(const std::vector& slices, const std:: } std::vector sample_expolygon(const ExPolygon &expoly, float samples_per_mm2, std::mt19937 &rng) -{ +{ // Triangulate the polygon with holes into triplets of 3D points. std::vector triangles = Slic3r::triangulate_expolygon_2f(expoly); @@ -347,7 +347,7 @@ static inline std::vector poisson_disk_from_samples(const std::vector(); raw_samples_sorted.emplace_back(sample); } - std::sort(raw_samples_sorted.begin(), raw_samples_sorted.end(), [](const RawSample &lhs, const RawSample &rhs) + std::sort(raw_samples_sorted.begin(), raw_samples_sorted.end(), [](const RawSample &lhs, const RawSample &rhs) { return lhs.cell_id.x() < rhs.cell_id.x() || (lhs.cell_id.x() == rhs.cell_id.x() && lhs.cell_id.y() < rhs.cell_id.y()); }); struct PoissonDiskGridEntry { @@ -464,10 +464,10 @@ void SLAAutoSupports::uniformly_cover(const ExPolygons& islands, Structure& stru //FIXME share the random generator. The random generator may be not so cheap to initialize, also we don't want the random generator to be restarted for each polygon. std::random_device rd; std::mt19937 rng(rd()); - std::vector raw_samples = sample_expolygon_with_boundary(islands, samples_per_mm2, 5.f / poisson_radius, rng); + std::vector raw_samples = sample_expolygon_with_boundary(islands, samples_per_mm2, 5.f / poisson_radius, rng); std::vector poisson_samples; for (size_t iter = 0; iter < 4; ++ iter) { - poisson_samples = poisson_disk_from_samples(raw_samples, poisson_radius, + poisson_samples = poisson_disk_from_samples(raw_samples, poisson_radius, [&structure, &grid3d, min_spacing](const Vec2f &pos) { return grid3d.collides_with(pos, &structure, min_spacing); }); @@ -481,21 +481,21 @@ void SLAAutoSupports::uniformly_cover(const ExPolygons& islands, Structure& stru } #ifdef SLA_AUTOSUPPORTS_DEBUG - { - static int irun = 0; - Slic3r::SVG svg(debug_out_path("SLA_supports-uniformly_cover-%d.svg", irun ++), get_extents(islands)); + { + static int irun = 0; + Slic3r::SVG svg(debug_out_path("SLA_supports-uniformly_cover-%d.svg", irun ++), get_extents(islands)); for (const ExPolygon &island : islands) svg.draw(island); - for (const Vec2f &pt : raw_samples) - svg.draw(Point(scale_(pt.x()), scale_(pt.y())), "red"); - for (const Vec2f &pt : poisson_samples) - svg.draw(Point(scale_(pt.x()), scale_(pt.y())), "blue"); - } + for (const Vec2f &pt : raw_samples) + svg.draw(Point(scale_(pt.x()), scale_(pt.y())), "red"); + for (const Vec2f &pt : poisson_samples) + svg.draw(Point(scale_(pt.x()), scale_(pt.y())), "blue"); + } #endif /* NDEBUG */ // assert(! poisson_samples.empty()); if (poisson_samples_target < poisson_samples.size()) { - std::shuffle(poisson_samples.begin(), poisson_samples.end(), rng); + std::shuffle(poisson_samples.begin(), poisson_samples.end(), rng); poisson_samples.erase(poisson_samples.begin() + poisson_samples_target, poisson_samples.end()); } for (const Vec2f &pt : poisson_samples) { diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index ac3b508316..5e0ac1c956 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -85,7 +85,7 @@ using Portion = std::tuple; // Set this to true to enable full parallelism in this module. // Only the well tested parts will be concurrent if this is set to false. -const constexpr bool USE_FULL_CONCURRENCY = false; +const constexpr bool USE_FULL_CONCURRENCY = true; template struct _ccr {}; @@ -1194,7 +1194,7 @@ class SLASupportTree::Algorithm { // Now a and b vectors are perpendicular to v and to each other. // Together they define the plane where we have to iterate with the // given angles in the 'phis' vector - ccr_par::enumerate(phis.begin(), phis.end(), + ccr_seq::enumerate(phis.begin(), phis.end(), [&hits, &m, sd, r_pin, r_back, s, a, b, c] (double phi, size_t i) { @@ -1297,7 +1297,7 @@ class SLASupportTree::Algorithm { // Hit results std::array hits; - ccr_par::enumerate(phis.begin(), phis.end(), + ccr_seq::enumerate(phis.begin(), phis.end(), [&m, a, b, sd, dir, r, s, ins_check, &hits] (double phi, size_t i) { @@ -2588,7 +2588,7 @@ SLASupportTree::SLASupportTree(double gnd_lvl): m_impl(new Impl()) { const TriangleMesh &SLASupportTree::merged_mesh() const { - return get().merged_mesh(); + return m_impl->merged_mesh(); } void SLASupportTree::merged_mesh_with_pad(TriangleMesh &outmesh) const { diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index d48b5bf739..95d4512710 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -148,9 +148,9 @@ std::vector BoxIndex::query(const BoundingBox &qrbb, BoxIndex::QueryType qt) { namespace bgi = boost::geometry::index; - + std::vector ret; ret.reserve(m_impl->m_store.size()); - + switch (qt) { case qtIntersects: m_impl->m_store.query(bgi::intersects(qrbb), std::back_inserter(ret)); @@ -158,7 +158,7 @@ std::vector BoxIndex::query(const BoundingBox &qrbb, case qtWithin: m_impl->m_store.query(bgi::within(qrbb), std::back_inserter(ret)); } - + return ret; } @@ -198,9 +198,9 @@ EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh): m_aabb(new AABBImpl()) { F.resize(stl.stats.number_of_facets, 3); for (unsigned int i = 0; i < stl.stats.number_of_facets; ++i) { const stl_facet &facet = stl.facet_start[i]; - V.block<1, 3>(3 * i + 0, 0) = facet.vertex[0].cast(); - V.block<1, 3>(3 * i + 1, 0) = facet.vertex[1].cast(); - V.block<1, 3>(3 * i + 2, 0) = facet.vertex[2].cast(); + V.block<1, 3>(3 * i + 0, 0) = facet.vertex[0].cast(); + V.block<1, 3>(3 * i + 1, 0) = facet.vertex[1].cast(); + V.block<1, 3>(3 * i + 2, 0) = facet.vertex[2].cast(); F(i, 0) = int(3*i+0); F(i, 1) = int(3*i+1); F(i, 2) = int(3*i+2); @@ -306,6 +306,7 @@ PointSet normals(const PointSet& points, PointSet ret(range.size(), 3); +// for (size_t ridx = 0; ridx < range.size(); ++ridx) tbb::parallel_for(size_t(0), range.size(), [&ret, &range, &mesh, &points, thr, eps](size_t ridx) { diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 893d90bbf6..1529f4bafc 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -16,6 +16,12 @@ // For geometry algorithms with native Clipper types (no copies and conversions) #include +// #define SLAPRINT_DO_BENCHMARK + +#ifdef SLAPRINT_DO_BENCHMARK +#include +#endif + //#include //#include "tbb/mutex.h" #include "I18N.hpp" @@ -1441,7 +1447,7 @@ void SLAPrint::process() if(canceled()) return; // Sequential version (for testing) - // for(unsigned l = 0; l < lvlcnt; ++l) process_level(l); + // for(unsigned l = 0; l < lvlcnt; ++l) lvlfn(l); // Print all the layers in parallel tbb::parallel_for(0, lvlcnt, lvlfn); @@ -1458,44 +1464,45 @@ void SLAPrint::process() using slaposFn = std::function; using slapsFn = std::function; - std::array pobj_program = + slaposFn pobj_program[] = { - slice_model, - support_points, - support_tree, - base_pool, - slice_supports + slice_model, support_points, support_tree, base_pool, slice_supports }; - std::array print_program = - { - merge_slices_and_eval_stats, - rasterize + // We want to first process all objects... + std::vector level1_obj_steps = { + slaposObjectSlice, slaposSupportPoints, slaposSupportTree, slaposBasePool }; + // and then slice all supports to allow preview to be displayed ASAP + std::vector level2_obj_steps = { + slaposSliceSupports + }; + + slapsFn print_program[] = { merge_slices_and_eval_stats, rasterize }; + SLAPrintStep print_steps[] = { slapsMergeSlicesAndEval, slapsRasterize }; + double st = min_objstatus; - unsigned incr = 0; BOOST_LOG_TRIVIAL(info) << "Start slicing process."; - // TODO: this loop could run in parallel but should not exhaust all the CPU - // power available - // Calculate the support structures first before slicing the supports, - // so that the preview will get displayed ASAP for all objects. - std::vector step_ranges = {slaposObjectSlice, - slaposSliceSupports, - slaposCount}; +#ifdef SLAPRINT_DO_BENCHMARK + Benchmark bench; +#else + struct { + void start() {} void stop() {} double getElapsedSec() { return .0; } + } bench; +#endif - for (size_t idx_range = 0; idx_range + 1 < step_ranges.size(); ++idx_range) { + std::array step_times {}; + + auto apply_steps_on_objects = + [this, &st, ostepd, &pobj_program, &step_times, &bench] + (const std::vector &steps) + { + unsigned incr = 0; for (SLAPrintObject *po : m_objects) { - - BOOST_LOG_TRIVIAL(info) - << "Slicing object " << po->model_object()->name; - - for (int s = int(step_ranges[idx_range]); - s < int(step_ranges[idx_range + 1]); - ++s) { - auto currentstep = static_cast(s); + for (SLAPrintObjectStep step : steps) { // Cancellation checking. Each step will check for // cancellation on its own and return earlier gracefully. @@ -1505,39 +1512,38 @@ void SLAPrint::process() st += incr * ostepd; - if (po->m_stepmask[currentstep] - && po->set_started(currentstep)) { - m_report_status(*this, - st, - OBJ_STEP_LABELS(currentstep)); - pobj_program[currentstep](*po); + if (po->m_stepmask[step] && po->set_started(step)) { + m_report_status(*this, st, OBJ_STEP_LABELS(step)); + bench.start(); + pobj_program[step](*po); + bench.stop(); + step_times[step] += bench.getElapsedSec(); throw_if_canceled(); - po->set_done(currentstep); + po->set_done(step); } - incr = OBJ_STEP_LEVELS[currentstep]; + incr = OBJ_STEP_LEVELS[step]; } } - } - - std::array printsteps = { - slapsMergeSlicesAndEval, slapsRasterize }; + apply_steps_on_objects(level1_obj_steps); + apply_steps_on_objects(level2_obj_steps); + // this would disable the rasterization step - // m_stepmask[slapsRasterize] = false; + // std::fill(m_stepmask.begin(), m_stepmask.end(), false); double pstd = (100 - max_objstatus) / 100.0; st = max_objstatus; - for(size_t s = 0; s < print_program.size(); ++s) { - auto currentstep = printsteps[s]; - + for(SLAPrintStep currentstep : print_steps) { throw_if_canceled(); - if(m_stepmask[currentstep] && set_started(currentstep)) - { + if (m_stepmask[currentstep] && set_started(currentstep)) { m_report_status(*this, st, PRINT_STEP_LABELS(currentstep)); + bench.start(); print_program[currentstep](); + bench.stop(); + step_times[slaposCount + currentstep] += bench.getElapsedSec(); throw_if_canceled(); set_done(currentstep); } @@ -1547,6 +1553,21 @@ void SLAPrint::process() // If everything vent well m_report_status(*this, 100, L("Slicing done")); + +#ifdef SLAPRINT_DO_BENCHMARK + std::string csvbenchstr; + for (size_t i = 0; i < size_t(slaposCount); ++i) + csvbenchstr += OBJ_STEP_LABELS(i) + ";"; + + for (size_t i = 0; i < size_t(slapsCount); ++i) + csvbenchstr += PRINT_STEP_LABELS(i) + ";"; + + csvbenchstr += "\n"; + for (double t : step_times) csvbenchstr += std::to_string(t) + ";"; + + std::cout << "Performance stats: \n" << csvbenchstr << std::endl; +#endif + } bool SLAPrint::invalidate_state_by_config_options(const std::vector &opt_keys, bool &invalidate_all_model_objects) diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index 74e70c5546..d5753f2ccf 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -62,7 +62,7 @@ template typename F::FN winapi_get_function(const wchar_t *dll, const c static HINSTANCE dll_handle = LoadLibraryExW(dll, nullptr, 0); if (dll_handle == nullptr) { return nullptr; } - return (F::FN)GetProcAddress(dll_handle, fn_name); + return (typename F::FN)GetProcAddress(dll_handle, fn_name); } #endif diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 24a28ecff1..14ceab8ff3 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -11,13 +11,14 @@ #include #include #include +#include #include #include #include namespace Slic3r { - enum class ModelVolumeType : int; + enum class ModelVolumeType : int; }; typedef double coordf_t; @@ -36,11 +37,11 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const std::function cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr, std::function const cb_condition = []() { return true; }, wxWindow* parent = nullptr); -wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, +wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, const std::string& icon = "", std::function const cb_condition = []() { return true; }, wxWindow* parent = nullptr); -wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, +wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, wxEvtHandler* event_handler); wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description, @@ -51,7 +52,7 @@ void edit_tooltip(wxString& tooltip); void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector& btn_ids); int em_unit(wxWindow* win); -wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, +wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false, const bool grayscale = false); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup @@ -95,23 +96,23 @@ public: class wxDataViewTreeCtrlComboPopup: public wxDataViewTreeCtrl, public wxComboPopup { - static const unsigned int DefaultWidth; - static const unsigned int DefaultHeight; - static const unsigned int DefaultItemHeight; + static const unsigned int DefaultWidth; + static const unsigned int DefaultHeight; + static const unsigned int DefaultItemHeight; - wxString m_text; - int m_cnt_open_items{0}; + wxString m_text; + int m_cnt_open_items{0}; public: - virtual bool Create(wxWindow* parent); - virtual wxWindow* GetControl() { return this; } - virtual void SetStringValue(const wxString& value) { m_text = value; } - virtual wxString GetStringValue() const { return m_text; } + virtual bool Create(wxWindow* parent); + virtual wxWindow* GetControl() { return this; } + virtual void SetStringValue(const wxString& value) { m_text = value; } + virtual wxString GetStringValue() const { return m_text; } // virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight); - virtual void OnKeyEvent(wxKeyEvent& evt); - void OnDataViewTreeCtrlSelection(wxCommandEvent& evt); - void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; } + virtual void OnKeyEvent(wxKeyEvent& evt); + void OnDataViewTreeCtrlSelection(wxCommandEvent& evt); + void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; } }; @@ -124,7 +125,7 @@ class DataViewBitmapText : public wxObject public: DataViewBitmapText( const wxString &text = wxEmptyString, const wxBitmap& bmp = wxNullBitmap) : - m_text(text), + m_text(text), m_bmp(bmp) { } @@ -195,8 +196,8 @@ WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); class ObjectDataViewModelNode { - ObjectDataViewModelNode* m_parent; - MyObjectTreeModelNodePtrArray m_children; + ObjectDataViewModelNode* m_parent; + MyObjectTreeModelNodePtrArray m_children; wxBitmap m_empty_bmp; size_t m_volumes_cnt = 0; std::vector< std::string > m_opt_categories; @@ -216,7 +217,7 @@ class ObjectDataViewModelNode Slic3r::ModelVolumeType m_volume_type; public: - ObjectDataViewModelNode(const wxString &name, + ObjectDataViewModelNode(const wxString &name, const wxString& extruder): m_parent(NULL), m_name(name), @@ -227,14 +228,14 @@ public: init_container(); } - ObjectDataViewModelNode(ObjectDataViewModelNode* parent, - const wxString& sub_obj_name, - const wxBitmap& bmp, - const wxString& extruder, + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const wxString& sub_obj_name, + const wxBitmap& bmp, + const wxString& extruder, const int idx = -1 ) : m_parent (parent), - m_name (sub_obj_name), - m_type (itVolume), + m_name (sub_obj_name), + m_type (itVolume), m_idx (idx), m_extruder (extruder) { @@ -243,27 +244,27 @@ public: init_container(); } - ObjectDataViewModelNode(ObjectDataViewModelNode* parent, - const t_layer_height_range& layer_range, + ObjectDataViewModelNode(ObjectDataViewModelNode* parent, + const t_layer_height_range& layer_range, const int idx = -1, const wxString& extruder = wxEmptyString ); ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type); - ~ObjectDataViewModelNode() - { - // free all our children nodes - size_t count = m_children.GetCount(); - for (size_t i = 0; i < count; i++) - { - ObjectDataViewModelNode *child = m_children[i]; - delete child; - } + ~ObjectDataViewModelNode() + { + // free all our children nodes + size_t count = m_children.GetCount(); + for (size_t i = 0; i < count; i++) + { + ObjectDataViewModelNode *child = m_children[i]; + delete child; + } #ifndef NDEBUG - // Indicate that the object was deleted. - m_idx = -2; + // Indicate that the object was deleted. + m_idx = -2; #endif /* NDEBUG */ - } + } void init_container(); bool IsContainer() const @@ -271,53 +272,53 @@ public: return m_container; } - ObjectDataViewModelNode* GetParent() - { - assert(m_parent == nullptr || m_parent->valid()); - return m_parent; - } - MyObjectTreeModelNodePtrArray& GetChildren() - { - return m_children; - } - ObjectDataViewModelNode* GetNthChild(unsigned int n) - { - return m_children.Item(n); - } - void Insert(ObjectDataViewModelNode* child, unsigned int n) - { - if (!m_container) - m_container = true; - m_children.Insert(child, n); - } - void Append(ObjectDataViewModelNode* child) - { - if (!m_container) - m_container = true; - m_children.Add(child); - } - void RemoveAllChildren() - { - if (GetChildCount() == 0) - return; - for (int id = int(GetChildCount()) - 1; id >= 0; --id) - { - if (m_children.Item(id)->GetChildCount() > 0) - m_children[id]->RemoveAllChildren(); - auto node = m_children[id]; - m_children.RemoveAt(id); - delete node; - } - } + ObjectDataViewModelNode* GetParent() + { + assert(m_parent == nullptr || m_parent->valid()); + return m_parent; + } + MyObjectTreeModelNodePtrArray& GetChildren() + { + return m_children; + } + ObjectDataViewModelNode* GetNthChild(unsigned int n) + { + return m_children.Item(n); + } + void Insert(ObjectDataViewModelNode* child, unsigned int n) + { + if (!m_container) + m_container = true; + m_children.Insert(child, n); + } + void Append(ObjectDataViewModelNode* child) + { + if (!m_container) + m_container = true; + m_children.Add(child); + } + void RemoveAllChildren() + { + if (GetChildCount() == 0) + return; + for (int id = int(GetChildCount()) - 1; id >= 0; --id) + { + if (m_children.Item(id)->GetChildCount() > 0) + m_children[id]->RemoveAllChildren(); + auto node = m_children[id]; + m_children.RemoveAt(id); + delete node; + } + } - size_t GetChildCount() const - { - return m_children.GetCount(); - } + size_t GetChildCount() const + { + return m_children.GetCount(); + } - bool SetValue(const wxVariant &variant, unsigned int col); + bool SetValue(const wxVariant &variant, unsigned int col); - void SetBitmap(const wxBitmap &icon) { m_bmp = icon; } + void SetBitmap(const wxBitmap &icon) { m_bmp = icon; } const wxBitmap& GetBitmap() const { return m_bmp; } const wxString& GetName() const { return m_name; } ItemType GetType() const { return m_type; } @@ -326,46 +327,46 @@ public: t_layer_height_range GetLayerRange() const { return m_layer_range; } PrintIndicator IsPrintable() const { return m_printable; } - // use this function only for childrens - void AssignAllVal(ObjectDataViewModelNode& from_node) - { - // ! Don't overwrite other values because of equality of this values for all children -- - m_name = from_node.m_name; + // use this function only for childrens + void AssignAllVal(ObjectDataViewModelNode& from_node) + { + // ! Don't overwrite other values because of equality of this values for all children -- + m_name = from_node.m_name; m_bmp = from_node.m_bmp; m_idx = from_node.m_idx; m_extruder = from_node.m_extruder; m_type = from_node.m_type; - } + } - bool SwapChildrens(int frst_id, int scnd_id) { - if (GetChildCount() < 2 || - frst_id < 0 || (size_t)frst_id >= GetChildCount() || - scnd_id < 0 || (size_t)scnd_id >= GetChildCount()) - return false; + bool SwapChildrens(int frst_id, int scnd_id) { + if (GetChildCount() < 2 || + frst_id < 0 || (size_t)frst_id >= GetChildCount() || + scnd_id < 0 || (size_t)scnd_id >= GetChildCount()) + return false; - ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); - ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); + ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); + ObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); new_scnd.m_idx = m_children.Item(scnd_id)->m_idx; new_frst.m_idx = m_children.Item(frst_id)->m_idx; - m_children.Item(frst_id)->AssignAllVal(new_frst); - m_children.Item(scnd_id)->AssignAllVal(new_scnd); - return true; - } + m_children.Item(frst_id)->AssignAllVal(new_frst); + m_children.Item(scnd_id)->AssignAllVal(new_scnd); + return true; + } - // Set action icons for node + // Set action icons for node void set_action_icon(); // Set printable icon for node void set_printable_icon(PrintIndicator printable); void update_settings_digest_bitmaps(); - bool update_settings_digest(const std::vector& categories); + bool update_settings_digest(const std::vector& categories); int volume_type() const { return int(m_volume_type); } void msw_rescale(); #ifndef NDEBUG - bool valid(); + bool valid(); #endif /* NDEBUG */ bool invalid() const { return m_idx < -1; } @@ -382,7 +383,7 @@ wxDECLARE_EVENT(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, wxCommandEvent); class ObjectDataViewModel :public wxDataViewModel { - std::vector m_objects; + std::vector m_objects; std::vector m_volume_bmps; wxBitmap* m_warning_bmp; @@ -392,7 +393,7 @@ public: ObjectDataViewModel(); ~ObjectDataViewModel(); - wxDataViewItem Add( const wxString &name, + wxDataViewItem Add( const wxString &name, const int extruder, const bool has_errors = false); wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item, @@ -405,24 +406,24 @@ public: wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector& print_indicator); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); - wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, + wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, const t_layer_height_range& layer_range, - const int extruder = 0, + const int extruder = 0, const int index = -1); - wxDataViewItem Delete(const wxDataViewItem &item); - wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); - void DeleteAll(); + wxDataViewItem Delete(const wxDataViewItem &item); + wxDataViewItem DeleteLastInstance(const wxDataViewItem &parent_item, size_t num); + void DeleteAll(); void DeleteChildren(wxDataViewItem& parent); void DeleteVolumeChildren(wxDataViewItem& parent); void DeleteSettings(const wxDataViewItem& parent); - wxDataViewItem GetItemById(int obj_idx); + wxDataViewItem GetItemById(int obj_idx); wxDataViewItem GetItemById(const int obj_idx, const int sub_obj_idx, const ItemType parent_type); - wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); - wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); + wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); + wxDataViewItem GetItemByInstanceId(int obj_idx, int inst_idx); wxDataViewItem GetItemByLayerId(int obj_idx, int layer_idx); wxDataViewItem GetItemByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); int GetItemIdByLayerRange(const int obj_idx, const t_layer_height_range& layer_range); - int GetIdByItem(const wxDataViewItem& item) const; + int GetIdByItem(const wxDataViewItem& item) const; int GetIdByItemAndType(const wxDataViewItem& item, const ItemType type) const; int GetObjectIdByItem(const wxDataViewItem& item) const; int GetVolumeIdByItem(const wxDataViewItem& item) const; @@ -433,53 +434,53 @@ public: bool IsEmpty() { return m_objects.empty(); } bool InvalidItem(const wxDataViewItem& item); - // helper method for wxLog + // helper method for wxLog - wxString GetName(const wxDataViewItem &item) const; + wxString GetName(const wxDataViewItem &item) const; wxBitmap& GetBitmap(const wxDataViewItem &item) const; - // helper methods to change the model + // helper methods to change the model - virtual unsigned int GetColumnCount() const override { return 3;} - virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } + virtual unsigned int GetColumnCount() const override { return 3;} + virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } - virtual void GetValue( wxVariant &variant, - const wxDataViewItem &item, + virtual void GetValue( wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const override; - virtual bool SetValue( const wxVariant &variant, - const wxDataViewItem &item, + virtual bool SetValue( const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) override; - bool SetValue( const wxVariant &variant, - const int item_idx, + bool SetValue( const wxVariant &variant, + const int item_idx, unsigned int col); - // For parent move child from cur_volume_id place to new_volume_id + // For parent move child from cur_volume_id place to new_volume_id // Remaining items will moved up/down accordingly - wxDataViewItem ReorganizeChildren( const int cur_volume_id, + wxDataViewItem ReorganizeChildren( const int cur_volume_id, const int new_volume_id, const wxDataViewItem &parent); - virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; + virtual bool IsEnabled(const wxDataViewItem &item, unsigned int col) const override; - virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; + virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; // get object item wxDataViewItem GetTopParent(const wxDataViewItem &item) const; - virtual bool IsContainer(const wxDataViewItem &item) const override; - virtual unsigned int GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const override; + virtual bool IsContainer(const wxDataViewItem &item) const override; + virtual unsigned int GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const override; void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const; - // Is the container just a header or an item with all columns - // In our case it is an item with all columns - virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } + // Is the container just a header or an item with all columns + // In our case it is an item with all columns + virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } ItemType GetItemType(const wxDataViewItem &item) const ; - wxDataViewItem GetItemByType( const wxDataViewItem &parent_item, + wxDataViewItem GetItemByType( const wxDataViewItem &parent_item, ItemType type) const; wxDataViewItem GetSettingsItem(const wxDataViewItem &item) const; wxDataViewItem GetInstanceRootItem(const wxDataViewItem &item) const; wxDataViewItem GetLayerRootItem(const wxDataViewItem &item) const; bool IsSettingsItem(const wxDataViewItem &item) const; - void UpdateSettingsDigest( const wxDataViewItem &item, + void UpdateSettingsDigest( const wxDataViewItem &item, const std::vector& categories); bool IsPrintable(const wxDataViewItem &item) const; @@ -498,7 +499,7 @@ public: // Rescale bitmaps for existing Items void Rescale(); - wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, + wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, const bool is_marked = false); void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; @@ -547,12 +548,12 @@ public: return false; #else return true; -#endif +#endif } - wxWindow* CreateEditorCtrl(wxWindow* parent, - wxRect labelRect, + wxWindow* CreateEditorCtrl(wxWindow* parent, + wxRect labelRect, const wxVariant& value) override; - bool GetValueFromEditorCtrl( wxWindow* ctrl, + bool GetValueFromEditorCtrl( wxWindow* ctrl, wxVariant& value) override; bool WasCanceled() const { return m_was_unusable_symbol; } @@ -569,88 +570,88 @@ private: class MyCustomRenderer : public wxDataViewCustomRenderer { public: - // This renderer can be either activatable or editable, for demonstration - // purposes. In real programs, you should select whether the user should be - // able to activate or edit the cell and it doesn't make sense to switch - // between the two -- but this is just an example, so it doesn't stop us. - explicit MyCustomRenderer(wxDataViewCellMode mode) - : wxDataViewCustomRenderer("string", mode, wxALIGN_CENTER) - { } + // This renderer can be either activatable or editable, for demonstration + // purposes. In real programs, you should select whether the user should be + // able to activate or edit the cell and it doesn't make sense to switch + // between the two -- but this is just an example, so it doesn't stop us. + explicit MyCustomRenderer(wxDataViewCellMode mode) + : wxDataViewCustomRenderer("string", mode, wxALIGN_CENTER) + { } - virtual bool Render(wxRect rect, wxDC *dc, int state) override/*wxOVERRIDE*/ - { - dc->SetBrush(*wxLIGHT_GREY_BRUSH); - dc->SetPen(*wxTRANSPARENT_PEN); + virtual bool Render(wxRect rect, wxDC *dc, int state) override/*wxOVERRIDE*/ + { + dc->SetBrush(*wxLIGHT_GREY_BRUSH); + dc->SetPen(*wxTRANSPARENT_PEN); - rect.Deflate(2); - dc->DrawRoundedRectangle(rect, 5); + rect.Deflate(2); + dc->DrawRoundedRectangle(rect, 5); - RenderText(m_value, - 0, // no offset - wxRect(dc->GetTextExtent(m_value)).CentreIn(rect), - dc, - state); - return true; - } + RenderText(m_value, + 0, // no offset + wxRect(dc->GetTextExtent(m_value)).CentreIn(rect), + dc, + state); + return true; + } - virtual bool ActivateCell(const wxRect& WXUNUSED(cell), - wxDataViewModel *WXUNUSED(model), - const wxDataViewItem &WXUNUSED(item), - unsigned int WXUNUSED(col), - const wxMouseEvent *mouseEvent) override/*wxOVERRIDE*/ - { - wxString position; - if (mouseEvent) - position = wxString::Format("via mouse at %d, %d", mouseEvent->m_x, mouseEvent->m_y); - else - position = "from keyboard"; + virtual bool ActivateCell(const wxRect& WXUNUSED(cell), + wxDataViewModel *WXUNUSED(model), + const wxDataViewItem &WXUNUSED(item), + unsigned int WXUNUSED(col), + const wxMouseEvent *mouseEvent) override/*wxOVERRIDE*/ + { + wxString position; + if (mouseEvent) + position = wxString::Format("via mouse at %d, %d", mouseEvent->m_x, mouseEvent->m_y); + else + position = "from keyboard"; // wxLogMessage("MyCustomRenderer ActivateCell() %s", position); - return false; - } + return false; + } - virtual wxSize GetSize() const override/*wxOVERRIDE*/ - { - return wxSize(60, 20); - } + virtual wxSize GetSize() const override/*wxOVERRIDE*/ + { + return wxSize(60, 20); + } - virtual bool SetValue(const wxVariant &value) override/*wxOVERRIDE*/ - { - m_value = value.GetString(); - return true; - } + virtual bool SetValue(const wxVariant &value) override/*wxOVERRIDE*/ + { + m_value = value.GetString(); + return true; + } - virtual bool GetValue(wxVariant &WXUNUSED(value)) const override/*wxOVERRIDE*/{ return true; } + virtual bool GetValue(wxVariant &WXUNUSED(value)) const override/*wxOVERRIDE*/{ return true; } - virtual bool HasEditorCtrl() const override/*wxOVERRIDE*/{ return true; } + virtual bool HasEditorCtrl() const override/*wxOVERRIDE*/{ return true; } - virtual wxWindow* - CreateEditorCtrl(wxWindow* parent, - wxRect labelRect, - const wxVariant& value) override/*wxOVERRIDE*/ - { - wxTextCtrl* text = new wxTextCtrl(parent, wxID_ANY, value, - labelRect.GetPosition(), - labelRect.GetSize(), - wxTE_PROCESS_ENTER); - text->SetInsertionPointEnd(); + virtual wxWindow* + CreateEditorCtrl(wxWindow* parent, + wxRect labelRect, + const wxVariant& value) override/*wxOVERRIDE*/ + { + wxTextCtrl* text = new wxTextCtrl(parent, wxID_ANY, value, + labelRect.GetPosition(), + labelRect.GetSize(), + wxTE_PROCESS_ENTER); + text->SetInsertionPointEnd(); - return text; - } + return text; + } - virtual bool - GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) override/*wxOVERRIDE*/ - { - wxTextCtrl* text = wxDynamicCast(ctrl, wxTextCtrl); - if (!text) - return false; + virtual bool + GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) override/*wxOVERRIDE*/ + { + wxTextCtrl* text = wxDynamicCast(ctrl, wxTextCtrl); + if (!text) + return false; - value = text->GetValue(); + value = text->GetValue(); - return true; - } + return true; + } private: - wxString m_value; + wxString m_value; }; @@ -662,7 +663,7 @@ class ScalableBitmap { public: ScalableBitmap() {}; - ScalableBitmap( wxWindow *parent, + ScalableBitmap( wxWindow *parent, const std::string& icon_name = "", const int px_cnt = 16, const bool is_horizontal = false); @@ -708,9 +709,9 @@ public: DoubleSlider( wxWindow *parent, wxWindowID id, - int lowerValue, - int higherValue, - int minValue, + int lowerValue, + int higherValue, + int minValue, int maxValue, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -753,8 +754,8 @@ public: EnableTickManipulation(false); } - bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } - bool is_one_layer() const { return m_is_one_layer; } + bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } + bool is_one_layer() const { return m_is_one_layer; } bool is_lower_at_min() const { return m_lower_value == m_min_value; } bool is_higher_at_max() const { return m_higher_value == m_max_value; } bool is_full_span() const { return this->is_lower_at_min() && this->is_higher_at_max(); } @@ -773,7 +774,7 @@ public: void OnRightUp(wxMouseEvent& event); protected: - + void render(); void draw_focus_rect(); void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end); diff --git a/src/slic3r/Utils/Time.hpp b/src/slic3r/Utils/Time.hpp index 7b670bd3ee..6a1aefa188 100644 --- a/src/slic3r/Utils/Time.hpp +++ b/src/slic3r/Utils/Time.hpp @@ -2,7 +2,7 @@ #define slic3r_Utils_Time_hpp_ #include -#include +#include namespace Slic3r { namespace Utils {