Merge branch 'master' into fs_QuadricEdgeCollapse

This commit is contained in:
Filip Sykala 2021-08-02 09:04:15 +02:00
commit 59d02aea0a
160 changed files with 5982 additions and 5094 deletions

3
.gitignore vendored
View File

@ -1,5 +1,6 @@
Build
Build.bat
/build/
MYMETA.json
MYMETA.yml
_build
@ -11,3 +12,5 @@ xs/MANIFEST.bak
xs/assertlib*
.init_bundle.ini
local-lib
/src/TAGS
/.vscode/

View File

@ -389,10 +389,13 @@ find_package(CURL REQUIRED)
add_library(libcurl INTERFACE)
target_link_libraries(libcurl INTERFACE CURL::libcurl)
# Fixing curl's cmake config script bugs
if (NOT WIN32)
# Required by libcurl
find_package(ZLIB REQUIRED)
target_link_libraries(libcurl INTERFACE ZLIB::ZLIB)
else()
target_link_libraries(libcurl INTERFACE crypt32)
endif()
if (SLIC3R_STATIC)

View File

@ -2,67 +2,79 @@
@IF "%PS_ECHO_ON%" NEQ "" (echo on) ELSE (echo off)
@GOTO :MAIN
:HELP
@ECHO.
@ECHO Performs initial build or rebuild of the app (build) and deps (build/deps).
@ECHO Default options are determined from build directories and system state.
@ECHO.
@ECHO Usage: build_win [-ARCH ^<arch^>] [-CONFIG ^<config^>] [-DESTDIR ^<directory^>]
@ECHO [-STEPS ^<all^|all-dirty^|app^|app-dirty^|deps^|deps-dirty^>]
@ECHO [-RUN ^<console^|custom^|none^|viewer^|window^>]
@ECHO.
@ECHO -a -ARCH Target processor architecture
@ECHO Default: %PS_ARCH_HOST%
@ECHO -c -CONFIG MSVC project config
@ECHO Default: %PS_CONFIG_DEFAULT%
@ECHO -s -STEPS Performs only the specified build steps:
@ECHO all - clean and build deps and app
@ECHO all-dirty - build deps and app without cleaning
@ECHO app - build main project/application
@ECHO app-dirty - does not build main project/application
@ECHO deps - clean and build deps
@ECHO deps-dirty - build deps without cleaning
@ECHO Default: %PS_STEPS_DEFAULT%
@ECHO -d -DESTDIR Deps destination directory (ignored on dirty builds)
@ECHO %PS_DESTDIR_DEFAULT_MSG%
@ECHO -a -ARCH Target processor architecture
@ECHO Default: %PS_ARCH_HOST%
@ECHO -c -CONFIG MSVC project config
@ECHO Default: %PS_CONFIG_DEFAULT%
@ECHO -s -STEPS Performs only the specified build steps:
@ECHO all - clean and build deps and app
@ECHO all-dirty - build deps and app without cleaning
@ECHO app - clean and build main applications
@ECHO app-dirty - build main applications without cleaning
@ECHO deps - clean and build deps
@ECHO deps-dirty - build deps without cleaning
@ECHO Default: %PS_STEPS_DEFAULT%
@ECHO -r -RUN Specifies what to perform at the run step:
@ECHO console - run and wait on prusa-slicer-console.exe
@ECHO custom - run and wait on your custom build/%PS_CUSTOM_RUN_FILE%
@ECHO ide - open project in Visual Studio if not open (no wait)
@ECHO none - run step does nothing
@ECHO viewer - run prusa-gcodeviewer.exe (no wait)
@ECHO window - run prusa-slicer.exe (no wait)
@ECHO Default: none
@ECHO -d -DESTDIR Deps destination directory
@ECHO Warning: Changing destdir path will not delete the old destdir.
@ECHO Default: %PS_DESTDIR_DEFAULT_MSG%
@ECHO.
@ECHO Example usage:
@ECHO First build: build_win -d "c:\src\PrusaSlicer-deps"
@ECHO Deps change: build_win -s all
@ECHO App rebuild: build_win
@ECHO Examples:
@ECHO.
@ECHO Initial build: build_win -d "c:\src\PrusaSlicer-deps"
@ECHO Build post deps change: build_win -s all
@ECHO App dirty build: build_win
@ECHO App dirty build ^& run: build_win -r console
@ECHO All clean build ^& run: build_win -s all -r console -d "deps\build\out_deps"
@ECHO.
GOTO :END
:MAIN
REM Script constants
SET START_TIME=%TIME%
SET PS_START_DIR=%CD%
SET PS_SOLUTION_NAME=PrusaSlicer
SET PS_CHOICE_TIMEOUT=30
SET PS_CUSTOM_RUN_FILE=custom_run.bat
SET PS_DEPS_PATH_FILE_NAME=.DEPS_PATH.txt
SET PS_DEPS_PATH_FILE=%~dp0deps\build\%PS_DEPS_PATH_FILE_NAME%
SET PS_CONFIG_LIST="Debug;MinSizeRel;Release;RelWithDebInfo"
REM Probe build directories and system state for reasonable default arguments
pushd %~dp0
REM Probe build directories and sytem state for reasonable default arguments
SET PS_CONFIG=RelWithDebInfo
SET PS_ARCH=%PROCESSOR_ARCHITECTURE%
SET PS_ARCH=%PROCESSOR_ARCHITECTURE:amd64=x64%
CALL :TOLOWER PS_ARCH
SET PS_DEPS_PATH_FILE=%~dp0deps\build\.DEPS_PATH.txt
SET PS_RUN=none
SET PS_DESTDIR=
IF EXIST %PS_DEPS_PATH_FILE% (
FOR /F "tokens=* USEBACKQ" %%I IN ("%PS_DEPS_PATH_FILE%") DO SET PS_DESTDIR=%%I
IF EXIST build/ALL_BUILD.vcxproj (
SET PS_STEPS=app-dirty
) ELSE SET PS_STEPS=app
) ELSE SET PS_STEPS=all
SET PS_DESTDIR_CACHED=%PS_DESTDIR%
CALL :RESOLVE_DESTDIR_CACHE
REM Set up parameters used by help menu
SET PS_CONFIG_DEFAULT=%PS_CONFIG%
SET PS_ARCH_HOST=%PS_ARCH%
SET PS_STEPS_DEFAULT=%PS_STEPS%
IF "%PS_DESTDIR%" NEQ "" (
SET PS_DESTDIR_DEFAULT_MSG=Default: %PS_DESTDIR%
) ELSE (
SET PS_DESTDIR_DEFAULT_MSG=Argument required ^(no default available^)
)
(echo " -help /help -h /h -? /? ")| findstr /I /C:" %~1 ">nul && GOTO :HELP
REM Parse arguments
SET EXIT_STATUS=1
SET PS_CURRENT_STEP=arguments
SET PARSER_STATE=
SET PARSER_FAIL=
FOR %%I in (%*) DO CALL :PARSE_OPTION "ARCH CONFIG DESTDIR STEPS" PARSER_STATE "%%~I"
FOR %%I in (%*) DO CALL :PARSE_OPTION "ARCH CONFIG DESTDIR STEPS RUN" PARSER_STATE "%%~I"
IF "%PARSER_FAIL%" NEQ "" (
@ECHO ERROR: Invalid switch: %PARSER_FAIL% 1>&2
GOTO :HELP
@ -72,46 +84,71 @@ IF "%PARSER_FAIL%" NEQ "" (
)
REM Validate arguments
SET PS_STEPS_SAVED=%PS_STEPS%
CALL :PARSE_OPTION_NAME "all all-dirty deps-dirty deps app-dirty app" PS_STEPS -%PS_STEPS%
IF "%PS_STEPS%" EQU "" (
@ECHO ERROR: Invalid parameter: steps=%PS_STEPS_SAVED% 1>&2
GOTO :HELP
) ELSE SET PS_STEPS_SAVED=
(echo %PS_STEPS%)| findstr /I /C:"dirty">nul && SET PS_STEPS_DIRTY=1
CALL :TOLOWER PS_STEPS
SET PS_ASK_TO_CONTINUE=
CALL :TOLOWER PS_ARCH
CALL :CANONICALIZE_PATH PS_DESTDIR "%PS_START_DIR%"
SET PS_ARCH=%PS_ARCH:amd64=x64%
CALL :PARSE_OPTION_VALUE %PS_CONFIG_LIST:;= % PS_CONFIG
IF "%PS_CONFIG%" EQU "" GOTO :HELP
REM RESOLVE_DESTDIR_CACHE must go after PS_ARCH and PS_CONFIG, but before PS STEPS
CALL :RESOLVE_DESTDIR_CACHE
IF "%PS_STEPS%" EQU "" SET PS_STEPS=%PS_STEPS_DEFAULT%
CALL :PARSE_OPTION_VALUE "all all-dirty deps-dirty deps app-dirty app app-cmake" PS_STEPS
IF "%PS_STEPS%" EQU "" GOTO :HELP
(echo %PS_STEPS%)| findstr /I /C:"dirty">nul && SET PS_STEPS_DIRTY=1 || SET PS_STEPS_DIRTY=
IF "%PS_STEPS%" EQU "app-cmake" SET PS_STEPS_DIRTY=1
IF "%PS_DESTDIR%" EQU "" SET PS_DESTDIR=%PS_DESTDIR_CACHED%
IF "%PS_DESTDIR%" EQU "" (
IF "%PS_STEPS_DIRTY%" EQU "" (
@ECHO ERROR: Parameter required: destdir 1>&2
GOTO :HELP
)
) ELSE IF "%PS_DESTDIR%" NEQ "%PS_DESTDIR_CACHED%" (
IF "%PS_STEPS_DIRTY%" NEQ "" (
@ECHO WARNING: Parameter ignored: destdir
) ELSE (echo "all deps")| findstr /I /C:"%PS_STEPS%">nul || (
@ECHO WARNING: Conflict with cached parameter: 1>&2
@ECHO WARNING: -destdir=%PS_DESTDIR% 1>&2
@ECHO WARNING: cached=%PS_DESTDIR_CACHED% 1>&2
@ECHO ERROR: Parameter required: -DESTDIR 1>&2
GOTO :HELP
)
CALL :CANONICALIZE_PATH PS_DESTDIR "%PS_START_DIR%"
IF "%PS_DESTDIR%" NEQ "%PS_DESTDIR_CACHED%" (
(echo "all deps all-dirty deps-dirty")| findstr /I /C:"%PS_STEPS%">nul || (
IF EXIST "%PS_DESTDIR%" (
@ECHO WARNING: DESTDIR does not match cache: 1>&2
@ECHO WARNING: new: %PS_DESTDIR% 1>&2
@ECHO WARNING: old: %PS_DESTDIR_CACHED% 1>&2
SET PS_ASK_TO_CONTINUE=1
) ELSE (
@ECHO ERROR: Invalid parameter: DESTDIR=%PS_DESTDIR% 1>&2
GOTO :HELP
)
)
)
SET PS_DESTDIR_DEFAULT_MSG=
CALL :PARSE_OPTION_VALUE "console custom ide none viewer window" PS_RUN
IF "%PS_RUN%" EQU "" GOTO :HELP
IF "%PS_RUN%" NEQ "none" IF "%PS_STEPS:~0,4%" EQU "deps" (
@ECHO ERROR: RUN=%PS_RUN% specified with STEPS=%PS_STEPS%
@ECHO ERROR: RUN=none is the only valid option for STEPS "deps" or "deps-dirty"
GOTO :HELP
)
REM Give the user a chance to cancel if we found something odd.
IF "%PS_ASK_TO_CONTINUE%" EQU "" GOTO :BUILD_ENV
@ECHO.
@ECHO Unexpected parameters detected. Build paused for %PS_CHOICE_TIMEOUT% seconds.
choice /T %PS_CHOICE_TIMEOUT% /C YN /D N /M "Continue"
IF %ERRORLEVEL% NEQ 1 GOTO :HELP
REM Set up MSVC environment
:BUILD_ENV
SET EXIT_STATUS=2
SET PS_CURRENT_STEP=environment
@ECHO **********************************************************************
@ECHO ** Build Config: %PS_CONFIG%
@ECHO ** Target Arch: %PS_ARCH%
@ECHO ** Build Steps: %PS_STEPS%
@ECHO ** Run App: %PS_RUN%
@ECHO ** Deps path: %PS_DESTDIR%
@ECHO ** Using Microsoft Visual Studio installation found at:
SET VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
IF NOT EXIST %VSWHERE% SET VSWHERE="%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe"
FOR /F "tokens=* USEBACKQ" %%I IN (`%VSWHERE% -nologo -property installationPath`) DO SET MSVC_DIR=%%I
SET VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe
IF NOT EXIST "%VSWHERE%" SET VSWHERE=%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe
FOR /F "tokens=* USEBACKQ" %%I IN (`"%VSWHERE%" -nologo -property installationPath`) DO SET MSVC_DIR=%%I
@ECHO ** %MSVC_DIR%
CALL "%MSVC_DIR%\Common7\Tools\vsdevcmd.bat" -arch=%PS_ARCH% -host_arch=%PS_ARCH_HOST% -app_platform=Desktop
IF "%ERRORLEVEL%" NEQ "0" GOTO :END
IF %ERRORLEVEL% NEQ 0 GOTO :END
REM Need to reset the echo state after vsdevcmd.bat clobbers it.
@IF "%PS_ECHO_ON%" NEQ "" (echo on) ELSE (echo off)
IF "%PS_DRY_RUN_ONLY%" NEQ "" (
@ECHO Script terminated early because PS_DRY_RUN_ONLY is set. 1>&2
GOTO :END
@ -121,36 +158,132 @@ IF /I "%PS_STEPS:~0,3%" EQU "app" GOTO :BUILD_APP
REM Build deps
:BUILD_DEPS
SET EXIT_STATUS=3
IF "%PS_STEPS_DIRTY%" EQU "" CALL :MAKE_OR_CLEAN_DIRECTORY deps\build
SET PS_CURRENT_STEP=deps
IF "%PS_STEPS_DIRTY%" EQU "" CALL :MAKE_OR_CLEAN_DIRECTORY deps\build "%PS_DEPS_PATH_FILE_NAME%"
cd deps\build || GOTO :END
IF "%PS_STEPS_DIRTY%" EQU "" cmake.exe .. -DDESTDIR="%PS_DESTDIR%" || GOTO :END
cmake.exe .. -DDESTDIR="%PS_DESTDIR%" || GOTO :END
(echo %PS_DESTDIR%)> "%PS_DEPS_PATH_FILE%"
msbuild /m ALL_BUILD.vcxproj /p:Configuration=%PS_CONFIG% || GOTO :END
cd ..\..
IF /I "%PS_STEPS:~0,4%" EQU "deps" GOTO :PROLOGUE
IF /I "%PS_STEPS:~0,4%" EQU "deps" GOTO :RUN_APP
REM Build app
:BUILD_APP
SET EXIT_STATUS=4
IF "%PS_STEPS_DIRTY%" EQU "" CALL :MAKE_OR_CLEAN_DIRECTORY build
SET PS_CURRENT_STEP=app
IF "%PS_STEPS_DIRTY%" EQU "" CALL :MAKE_OR_CLEAN_DIRECTORY build "%PS_CUSTOM_RUN_FILE%"
cd build || GOTO :END
IF "%PS_STEPS_DIRTY%" EQU "" cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" || GOTO :END
msbuild /m ALL_BUILD.vcxproj /p:Configuration=%PS_CONFIG% || GOTO :END
REM Make sure we have a custom batch file skeleton for the run stage
set PS_CUSTOM_BAT=%PS_CUSTOM_RUN_FILE%
CALL :CANONICALIZE_PATH PS_CUSTOM_BAT
IF NOT EXIST %PS_CUSTOM_BAT% CALL :WRITE_CUSTOM_SCRIPT_SKELETON %PS_CUSTOM_BAT%
SET PS_PROJECT_IS_OPEN=
FOR /F "tokens=2 delims=," %%I in (
'tasklist /V /FI "IMAGENAME eq devenv.exe " /NH /FO CSV ^| find "%PS_SOLUTION_NAME%"'
) do SET PS_PROJECT_IS_OPEN=%%~I
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG_LIST% || GOTO :END
REM Skip the build step if we're using the undocumented app-cmake to regenerate the full config from inside devenv
IF "%PS_STEPS%" NEQ "app-cmake" msbuild /m ALL_BUILD.vcxproj /p:Configuration=%PS_CONFIG% || GOTO :END
(echo %PS_DESTDIR%)> "%PS_DEPS_PATH_FILE_FOR_CONFIG%"
REM Run app
:RUN_APP
REM All build steps complete.
CALL :DIFF_TIME ELAPSED_TIME %START_TIME% %TIME%
IF "%PS_CURRENT_STEP%" NEQ "arguments" (
@ECHO.
@ECHO Total Build Time Elapsed %ELAPSED_TIME%
)
SET EXIT_STATUS=5
SET PS_CURRENT_STEP=run
cd src\%PS_CONFIG% || GOTO :END
IF "%PS_RUN%" EQU "none" GOTO :PROLOGUE
SET PS_PROJECT_IS_OPEN=
FOR /F "tokens=2 delims=," %%I in (
'tasklist /V /FI "IMAGENAME eq devenv.exe " /NH /FO CSV ^| find "%PS_SOLUTION_NAME%"'
) do SET PS_PROJECT_IS_OPEN=%%~I
@ECHO.
@ECHO Running %PS_RUN% application...
@REM icacls below is just a hack for file-not-found error handling
IF "%PS_RUN%" EQU "console" (
icacls prusa-slicer-console.exe >nul || GOTO :END
start /wait /b prusa-slicer-console.exe
) ELSE IF "%PS_RUN%" EQU "window" (
icacls prusa-slicer.exe >nul || GOTO :END
start prusa-slicer.exe
) ELSE IF "%PS_RUN%" EQU "viewer" (
icacls prusa-gcodeviewer.exe >nul || GOTO :END
start prusa-gcodeviewer.exe
) ELSE IF "%PS_RUN%" EQU "custom" (
icacls %PS_CUSTOM_BAT% >nul || GOTO :END
CALL %PS_CUSTOM_BAT%
) ELSE IF "%PS_RUN%" EQU "ide" (
IF "%PS_PROJECT_IS_OPEN%" NEQ "" (
@ECHO WARNING: Solution is already open in Visual Studio. Skipping ide run step. 1>&2
) ELSE (
@ECHO Preparing to run Visual Studio...
cd ..\.. || GOTO :END
REM This hack generates a single config for MSVS, guaranteeing it gets set as the active config.
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG% > nul 2> nul || GOTO :END
REM Now launch devenv with the single config (setting it active) and a /command switch to re-run cmake and generate the full config list
start devenv.exe %PS_SOLUTION_NAME%.sln /command ^"shell /o ^^^"%~f0^^^" -d ^^^"%PS_DESTDIR%^^^" -c %PS_CONFIG% -a %PS_ARCH% -r none -s app-cmake^"
REM If devenv fails to launch just directly regenerate the full config list.
IF %ERRORLEVEL% NEQ 0 (
cmake.exe .. -DCMAKE_PREFIX_PATH="%PS_DESTDIR%\usr\local" -DCMAKE_CONFIGURATION_TYPES=%PS_CONFIG_LIST% 2> nul 1> nul || GOTO :END
)
)
)
@REM ********** DON'T ADD ANY CODE BETWEEN THESE TWO SECTIONS **********
@REM RUN_APP may hand off control, so let exit codes fall through to PROLOGUE.
:PROLOGUE
SET EXIT_STATUS=%ERRORLEVEL%
:END
@IF "%PS_ECHO_ON%%PS_DRY_RUN_ONLY%" NEQ "" (
@ECHO Script Parameters:
@ECHO **********************************************************************
@ECHO ** Script Parameters:
@ECHO **********************************************************************
@SET PS_
)
@ECHO Script started at %START_TIME% and completed at %TIME%.
IF "%EXIT_STATUS%" NEQ "0" (
IF "%PS_CURRENT_STEP%" NEQ "arguments" (
@ECHO.
@ECHO ERROR: *** Build process failed at %PS_CURRENT_STEP% step. *** 1>&2
)
) ELSE (
@ECHO All steps completed successfully.
)
popd
exit /B %EXIT_STATUS%
GOTO :EOF
REM Functions and stubs start here.
:RESOLVE_DESTDIR_CACHE
@REM Resolves all DESTDIR cache values and sets PS_STEPS_DEFAULT
@REM Note: This just sets global variableq, so it doesn't use setlocal.
SET PS_DEPS_PATH_FILE_FOR_CONFIG=%~dp0build\%PS_ARCH%\%PS_CONFIG%\%PS_DEPS_PATH_FILE_NAME%
CALL :CANONICALIZE_PATH PS_DEPS_PATH_FILE_FOR_CONFIG
IF EXIST "%PS_DEPS_PATH_FILE_FOR_CONFIG%" (
FOR /F "tokens=* USEBACKQ" %%I IN ("%PS_DEPS_PATH_FILE_FOR_CONFIG%") DO (
SET PS_DESTDIR_CACHED=%%I
SET PS_DESTDIR_DEFAULT_MSG=%%I
)
SET PS_STEPS_DEFAULT=app-dirty
) ELSE IF EXIST "%PS_DEPS_PATH_FILE%" (
FOR /F "tokens=* USEBACKQ" %%I IN ("%PS_DEPS_PATH_FILE%") DO (
SET PS_DESTDIR_CACHED=%%I
SET PS_DESTDIR_DEFAULT_MSG=%%I
)
SET PS_STEPS_DEFAULT=app
) ELSE (
SET PS_DESTDIR_CACHED=
SET PS_DESTDIR_DEFAULT_MSG=Cache missing. Argument required.
SET PS_STEPS_DEFAULT=all
)
GOTO :EOF
:PARSE_OPTION
@REM Argument parser called for each argument
@REM %1 - Valid option list
@ -179,12 +312,27 @@ IF "%LAST_ARG%%ARG_TYPE%" EQU "NAME" SET PARSER_FAIL=%~3
)
GOTO :EOF
:PARSE_OPTION_VALUE
setlocal disableDelayedExpansion
@REM Parses value and verifies it is within the supplied list
@REM %1 - Valid option list
@REM %2 - In/out variable name; unset on error
CALL SET NAME=%~2
CALL SET SAVED_VALUE=%%%NAME%%%
CALL :PARSE_OPTION_NAME %1 %NAME% -%SAVED_VALUE%
CALL SET NEW_VALUE=%%%NAME%%%
IF "%NEW_VALUE%" EQU "" (
@ECHO ERROR: Invalid parameter: %NAME:~3%=%SAVED_VALUE% 1>&2
)
endlocal & SET %NAME%=%NEW_VALUE%
GOTO :EOF
:PARSE_OPTION_NAME
@REM Parses an option name
@REM %1 - Valid option list
@REM %2 - Out variable name; unset on error
@REM %3 - Current argument value
@REM $4 - Boolean indicating single character switches are valid
@REM %4 - Boolean indicating single character switches are valid
@REM Note: Delayed expansion safe because ! character is invalid in option name
setlocal enableDelayedExpansion
IF "%4" NEQ "" FOR %%I IN (%~1) DO @(
@ -201,6 +349,7 @@ IF "%4" NEQ "" (
)
@(echo %OPTION_NAME%)| findstr /R /C:".[ ][ ]*.">nul && GOTO :PARSE_OPTION_NAME_FAIL
@(echo %~1 )| findstr /I /C:" %OPTION_NAME% ">nul || GOTO :PARSE_OPTION_NAME_FAIL
FOR %%I IN (%~1) DO SET OPTION_NAME=!OPTION_NAME:%%~I=%%~I!
endlocal & SET %~2=%OPTION_NAME%
GOTO :EOF
:PARSE_OPTION_NAME_FAIL
@ -210,14 +359,28 @@ GOTO :EOF
:MAKE_OR_CLEAN_DIRECTORY
@REM Create directory if it doesn't exist or clean it if it does
@REM %1 - Directory path to clean or create
@REM %* - Optional list of files/dirs to keep (in the base directory only)
setlocal disableDelayedExpansion
IF NOT EXIST "%~1" (
ECHO Creating %~1
mkdir "%~1" && GOTO :EOF
@ECHO Creating %~1
mkdir "%~1" && (
endlocal
GOTO :EOF
)
)
@ECHO Cleaning %~1 ...
SET KEEP_LIST=
:MAKE_OR_CLEAN_DIRECTORY_ARG_LOOP
IF "%~2" NEQ "" (
SET KEEP_LIST=%KEEP_LIST% "%~2"
SHIFT /2
GOTO :MAKE_OR_CLEAN_DIRECTORY_ARG_LOOP
)
ECHO Cleaning %~1 ...
for /F "usebackq delims=" %%I in (`dir /a /b "%~1"`) do (
(rmdir /s /q "%~1\%%I" 2>nul ) || del /q /f "%~1\%%I")
(echo %KEEP_LIST%)| findstr /I /L /C:"\"%%I\"">nul || (
rmdir /s /q "%~1\%%I" 2>nul ) || del /q /f "%~1\%%I"
)
endlocal
GOTO :EOF
:TOLOWER
@ -239,7 +402,51 @@ CALL :CANONICALIZE_PATH_INNER %1 %%%~1%% %2
endlocal & SET %~1=%OUTPUT%
GOTO :EOF
:CANONICALIZE_PATH_INNER
if "%~3" NEQ "" (pushd %~3 || GOTO :EOF)
if "%~3" NEQ "" (pushd %3 || GOTO :EOF)
SET OUTPUT=%~f2
if "%~3" NEQ "" popd %~3
if "%~3" NEQ "" popd
GOTO :EOF
:DIFF_TIME
@REM Calculates elapsed time between two timestamps (TIME environment variable format)
@REM %1 - Output variable
@REM %2 - Start time
@REM %3 - End time
setlocal EnableDelayedExpansion
set START_ARG=%2
set END_ARG=%3
set END=!END_ARG:%TIME:~8,1%=%%100)*100+1!
set START=!START_ARG:%TIME:~8,1%=%%100)*100+1!
set /A DIFF=((((10!END:%TIME:~2,1%=%%100)*60+1!%%100)-((((10!START:%TIME:~2,1%=%%100)*60+1!%%100), DIFF-=(DIFF^>^>31)*24*60*60*100
set /A CC=DIFF%%100+100,DIFF/=100,SS=DIFF%%60+100,DIFF/=60,MM=DIFF%%60+100,HH=DIFF/60+100
@endlocal & set %1=%HH:~1%%TIME:~2,1%%MM:~1%%TIME:~2,1%%SS:~1%%TIME:~8,1%%CC:~1%
@GOTO :EOF
:WRITE_CUSTOM_SCRIPT_SKELETON
@REM Writes the following text to the supplied file
@REM %1 - Output filename
setlocal
@(
ECHO @ECHO.
ECHO @ECHO ********************************************************************************
ECHO @ECHO ** This is a custom run script skeleton.
ECHO @ECHO ********************************************************************************
ECHO @ECHO.
ECHO @ECHO ********************************************************************************
ECHO @ECHO ** The working directory is:
ECHO @ECHO ********************************************************************************
ECHO dir
ECHO @ECHO.
ECHO @ECHO ********************************************************************************
ECHO @ECHO ** The environment is:
ECHO @ECHO ********************************************************************************
ECHO set
ECHO @ECHO.
ECHO @ECHO ********************************************************************************
ECHO @ECHO ** Edit or replace this script to run custom steps after a successful build:
ECHO @ECHO ** %~1
ECHO @ECHO ********************************************************************************
ECHO @ECHO.
) > "%~1"
endlocal
GOTO :EOF

View File

@ -347,7 +347,7 @@ macro(just_fail msg)
return()
endmacro()
find_package(IlmBase QUIET COMPONENTS Half)
find_package(IlmBase QUIET)
if(NOT IlmBase_FOUND)
pkg_check_modules(IlmBase QUIET IlmBase)
endif()

28
deps/Blosc/Blosc.cmake vendored Normal file
View File

@ -0,0 +1,28 @@
if(BUILD_SHARED_LIBS)
set(_build_shared ON)
set(_build_static OFF)
else()
set(_build_shared OFF)
set(_build_static ON)
endif()
prusaslicer_add_cmake_project(Blosc
#URL https://github.com/Blosc/c-blosc/archive/refs/tags/v1.17.0.zip
#URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9
URL https://github.com/tamasmeszaros/c-blosc/archive/refs/heads/v1.17.0_tm.zip
URL_HASH SHA256=dcb48bf43a672fa3de6a4b1de2c4c238709dad5893d1e097b8374ad84b1fc3b3
DEPENDS ${ZLIB_PKG}
# Patching upstream does not work this way with git version 2.28 installed on mac worker
# PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/blosc-mods.patch
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DBUILD_SHARED=${_build_shared}
-DBUILD_STATIC=${_build_static}
-DBUILD_TESTS=OFF
-DBUILD_BENCHMARKS=OFF
-DPREFER_EXTERNAL_ZLIB=ON
)
if (MSVC)
add_debug_dep(dep_Blosc)
endif ()

150
deps/Boost/Boost.cmake vendored Normal file
View File

@ -0,0 +1,150 @@
include(ExternalProject)
if (WIN32)
set(_bootstrap_cmd bootstrap.bat)
set(_build_cmd b2.exe)
else()
set(_bootstrap_cmd ./bootstrap.sh)
set(_build_cmd ./b2)
endif()
set(_patch_command ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/common.jam ./tools/build/src/tools/common.jam)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
configure_file(${CMAKE_CURRENT_LIST_DIR}/user-config.jam boost-user-config.jam)
set(_boost_toolset gcc)
set(_patch_command ${_patch_command} && ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/boost-user-config.jam ./tools/build/src/tools/user-config.jam)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html
if (MSVC_VERSION EQUAL 1800)
# 1800 = VS 12.0 (v120 toolset)
set(_boost_toolset "msvc-12.0")
elseif (MSVC_VERSION EQUAL 1900)
# 1900 = VS 14.0 (v140 toolset)
set(_boost_toolset "msvc-14.0")
elseif (MSVC_VERSION LESS 1920)
# 1910-1919 = VS 15.0 (v141 toolset)
set(_boost_toolset "msvc-14.1")
elseif (MSVC_VERSION LESS 1930)
# 1920-1929 = VS 16.0 (v142 toolset)
set(_boost_toolset "msvc-14.2")
else ()
message(FATAL_ERROR "Unsupported MSVC version")
endif ()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (WIN32)
set(_boost_toolset "clang-win")
else()
set(_boost_toolset "clang")
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
set(_boost_toolset "intel")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(_boost_toolset "clang")
endif()
message(STATUS "Deduced boost toolset: ${_boost_toolset} based on ${CMAKE_CXX_COMPILER_ID} compiler")
set(_libs "")
foreach(_comp ${DEP_Boost_COMPONENTS})
list(APPEND _libs "--with-${_comp}")
endforeach()
if (BUILD_SHARED_LIBS)
set(_link shared)
else()
set(_link static)
endif()
set(_bits "")
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(_bits 64)
elseif ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
set(_bits 32)
endif ()
include(ProcessorCount)
ProcessorCount(NPROC)
file(TO_NATIVE_PATH ${DESTDIR}/usr/local/ _prefix)
set(_boost_flags "")
if (UNIX)
set(_boost_flags "cflags=-fPIC;cxxflags=-fPIC")
elseif(APPLE)
set(_boost_flags
"cflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET};"
"cxxflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET};"
"mflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET};"
"mmflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}")
endif()
set(_boost_variants "")
if(CMAKE_BUILD_TYPE)
list(APPEND CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE})
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
endif()
list(FIND CMAKE_CONFIGURATION_TYPES "Release" _cfg_rel)
list(FIND CMAKE_CONFIGURATION_TYPES "RelWithDebInfo" _cfg_relwdeb)
list(FIND CMAKE_CONFIGURATION_TYPES "MinSizeRel" _cfg_minsizerel)
list(FIND CMAKE_CONFIGURATION_TYPES "Debug" _cfg_deb)
if (_cfg_rel GREATER -1 OR _cfg_relwdeb GREATER -1 OR _cfg_minsizerel GREATER -1)
list(APPEND _boost_variants release)
endif()
if (_cfg_deb GREATER -1 OR (MSVC AND ${DEP_DEBUG}) )
list(APPEND _boost_variants debug)
endif()
if (NOT _boost_variants)
set(_boost_variants release)
endif()
set(_build_cmd ${_build_cmd}
${_boost_flags}
-j${NPROC}
${_libs}
--layout=versioned
--debug-configuration
toolset=${_boost_toolset}
address-model=${_bits}
link=${_link}
threading=multi
boost.locale.icu=off
--disable-icu
${_boost_variants}
stage)
set(_install_cmd ${_build_cmd} --prefix=${_prefix} install)
ExternalProject_Add(
dep_Boost
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/Boost
CONFIGURE_COMMAND "${_bootstrap_cmd}"
PATCH_COMMAND ${_patch_command}
BUILD_COMMAND "${_build_cmd}"
BUILD_IN_SOURCE ON
INSTALL_COMMAND "${_install_cmd}"
)
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
# Patch the boost::polygon library with a custom one.
ExternalProject_Add(dep_boost_polygon
EXCLUDE_FROM_ALL ON
# GIT_REPOSITORY "https://github.com/prusa3d/polygon"
# GIT_TAG prusaslicer_gmp
URL https://github.com/prusa3d/polygon/archive/refs/heads/prusaslicer_gmp.zip
URL_HASH SHA256=abeb9710f0a7069fb9b22181ae5c56f6066002f125db210e7ffb27032aed6824
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/boost_polygon
DEPENDS dep_Boost
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_BINARY_DIR}/dep_boost_polygon-prefix/src/dep_boost_polygon/include/boost/polygon"
"${DESTDIR}/usr/local/include/boost/polygon"
)
# Only override boost::Polygon Voronoi implementation with Vojtech's GMP hacks on 64bit platforms.
list(APPEND _dep_list "dep_boost_polygon")
endif ()

1095
deps/Boost/common.jam vendored Normal file

File diff suppressed because it is too large Load Diff

1
deps/Boost/user-config.jam vendored Normal file
View File

@ -0,0 +1 @@
using gcc : : @CMAKE_CXX_COMPILER@ ;

10
deps/CGAL/CGAL.cmake vendored
View File

@ -1,11 +1,11 @@
prusaslicer_add_cmake_project(
CGAL
GIT_REPOSITORY https://github.com/CGAL/cgal.git
GIT_TAG bec70a6d52d8aacb0b3d82a7b4edc3caa899184b # releases/CGAL-5.0
# GIT_REPOSITORY https://github.com/CGAL/cgal.git
# GIT_TAG bec70a6d52d8aacb0b3d82a7b4edc3caa899184b # releases/CGAL-5.0
# For whatever reason, this keeps downloading forever (repeats downloads if finished)
# URL https://github.com/CGAL/cgal/archive/releases/CGAL-5.0.zip
# URL_HASH SHA256=bd9327be903ab7ee379a8a7a0609eba0962f5078d2497cf8e13e8e1598584154
DEPENDS dep_boost dep_GMP dep_MPFR
URL https://github.com/CGAL/cgal/archive/releases/CGAL-5.0.zip
URL_HASH SHA256=c2b035bd078687b6d8c0fb6371a7443adcdb647856af9969532c4050cd5f48e5
DEPENDS dep_Boost dep_GMP dep_MPFR
)
include(GNUInstallDirs)

65
deps/CMakeLists.txt vendored
View File

@ -32,6 +32,7 @@ if (NPROC EQUAL 0)
endif ()
set(DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/destdir" CACHE PATH "Destination directory")
set(DEP_DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Path for downloaded source packages.")
option(DEP_DEBUG "Build debug variants (only applicable on Windows)" ON)
@ -46,10 +47,14 @@ endif()
# option(DEP_BUILD_IGL_STATIC "Build IGL as a static library. Might cause link errors and increase binary size." OFF)
message(STATUS "PrusaSlicer deps DESTDIR: ${DESTDIR}")
message(STATUS "PrusaSlicer dowload dir for source packages: ${DEP_DOWNLOAD_DIR}")
message(STATUS "PrusaSlicer deps debug build: ${DEP_DEBUG}")
find_package(Git REQUIRED)
# The default command line for patching. Only works for newer
set(PATCH_CMD ${GIT_EXECUTABLE} apply --verbose --ignore-space-change --whitespace=fix)
get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
function(prusaslicer_add_cmake_project projectname)
@ -71,6 +76,7 @@ function(prusaslicer_add_cmake_project projectname)
dep_${projectname}
EXCLUDE_FROM_ALL ON
INSTALL_DIR ${DESTDIR}/usr/local
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/${projectname}
${_gen}
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX:STRING=${DESTDIR}/usr/local
@ -79,6 +85,7 @@ function(prusaslicer_add_cmake_project projectname)
-DCMAKE_DEBUG_POSTFIX:STRING=d
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
-DCMAKE_TOOLCHAIN_FILE:STRING=${CMAKE_TOOLCHAIN_FILE}
-DBUILD_SHARED_LIBS:BOOL=OFF
"${_configs_line}"
${DEP_CMAKE_OPTS}
@ -145,27 +152,42 @@ if (NOT EXPAT_FOUND)
set(EXPAT_PKG dep_EXPAT)
endif ()
set(DEP_Boost_COMPONENTS system iostreams filesystem thread log locale regex date_time)
include(Boost/Boost.cmake)
# The order of includes respects the dependencies between libraries
include(Cereal/Cereal.cmake)
include(Qhull/Qhull.cmake)
include(GLEW/GLEW.cmake)
include(OpenCSG/OpenCSG.cmake)
include(TBB/TBB.cmake)
include(Blosc/Blosc.cmake)
include(OpenEXR/OpenEXR.cmake)
include(OpenVDB/OpenVDB.cmake)
include(GMP/GMP.cmake)
include(MPFR/MPFR.cmake)
include(CGAL/CGAL.cmake)
include(NLopt/NLopt.cmake)
include(OpenSSL/OpenSSL.cmake)
include(CURL/CURL.cmake)
include(JPEG/JPEG.cmake)
include(TIFF/TIFF.cmake)
include(wxWidgets/wxWidgets.cmake)
if (NOT "${ZLIB_PKG}" STREQUAL "")
add_dependencies(dep_blosc ${ZLIB_PKG})
add_dependencies(dep_openexr ${ZLIB_PKG})
endif ()
set(_dep_list
dep_boost
dep_tbb
dep_libcurl
dep_Boost
dep_TBB
dep_CURL
dep_wxWidgets
dep_gtest
dep_cereal
dep_nlopt
dep_openvdb
dep_Cereal
dep_NLopt
dep_OpenVDB
dep_OpenCSG
dep_CGAL
${PNG_PKG}
@ -173,28 +195,11 @@ set(_dep_list
${EXPAT_PKG}
)
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
# Patch the boost::polygon library with a custom one.
ExternalProject_Add(dep_boost_polygon
EXCLUDE_FROM_ALL ON
GIT_REPOSITORY "https://github.com/prusa3d/polygon"
GIT_TAG prusaslicer_gmp
DEPENDS dep_boost
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_BINARY_DIR}/dep_boost_polygon-prefix/src/dep_boost_polygon/include/boost/polygon"
"${DESTDIR}/usr/local/include/boost/polygon"
)
# Only override boost::Polygon Voronoi implementation with Vojtech's GMP hacks on 64bit platforms.
list(APPEND _dep_list "dep_boost_polygon")
endif ()
if (MSVC)
# Experimental
#list(APPEND _dep_list "dep_qhull")
else()
list(APPEND _dep_list "dep_qhull")
list(APPEND _dep_list "dep_Qhull")
# Not working, static build has different Eigen
#list(APPEND _dep_list "dep_libigl")
endif()

78
deps/CURL/CURL.cmake vendored Normal file
View File

@ -0,0 +1,78 @@
set(_curl_platform_flags
-DENABLE_IPV6:BOOL=ON
-DENABLE_VERSIONED_SYMBOLS:BOOL=ON
-DENABLE_THREADED_RESOLVER:BOOL=ON
# -DCURL_DISABLE_LDAP:BOOL=ON
# -DCURL_DISABLE_LDAPS:BOOL=ON
-DENABLE_MANUAL:BOOL=OFF
# -DCURL_DISABLE_RTSP:BOOL=ON
# -DCURL_DISABLE_DICT:BOOL=ON
# -DCURL_DISABLE_TELNET:BOOL=ON
# -DCURL_DISABLE_POP3:BOOL=ON
# -DCURL_DISABLE_IMAP:BOOL=ON
# -DCURL_DISABLE_SMB:BOOL=ON
# -DCURL_DISABLE_SMTP:BOOL=ON
# -DCURL_DISABLE_GOPHER:BOOL=ON
-DHTTP_ONLY=ON
-DCMAKE_USE_GSSAPI:BOOL=OFF
-DCMAKE_USE_LIBSSH2:BOOL=OFF
-DUSE_RTMP:BOOL=OFF
-DUSE_NGHTTP2:BOOL=OFF
-DUSE_MBEDTLS:BOOL=OFF
)
if (WIN32)
set(_curl_platform_flags ${_curl_platform_flags} -DCMAKE_USE_SCHANNEL=ON)
elseif (APPLE)
set(_curl_platform_flags
${_curl_platform_flags}
-DCMAKE_USE_SECTRANSP:BOOL=ON
-DCMAKE_USE_OPENSSL:BOOL=OFF
-DCURL_CA_PATH:STRING=none
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(_curl_platform_flags
${_curl_platform_flags}
-DCMAKE_USE_OPENSSL:BOOL=ON
-DCURL_CA_PATH:STRING=none
-DCURL_CA_BUNDLE:STRING=none
-DCURL_CA_FALLBACK:BOOL=ON
)
endif ()
if (BUILD_SHARED_LIBS)
set(_curl_static OFF)
else()
set(_curl_static ON)
endif()
prusaslicer_add_cmake_project(CURL
# GIT_REPOSITORY https://github.com/curl/curl.git
# GIT_TAG curl-7_75_0
URL https://github.com/curl/curl/archive/refs/tags/curl-7_75_0.zip
URL_HASH SHA256=a63ae025bb0a14f119e73250f2c923f4bf89aa93b8d4fafa4a9f5353a96a765a
DEPENDS ${ZLIB_PKG}
# PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df &&
# ${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/curl-mods.patch
CMAKE_ARGS
-DBUILD_TESTING:BOOL=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCURL_STATICLIB=${_curl_static}
${_curl_platform_flags}
)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_dependencies(dep_CURL dep_OpenSSL)
endif ()
if (MSVC)
add_debug_dep(dep_CURL)
endif ()

6
deps/Cereal/Cereal.cmake vendored Normal file
View File

@ -0,0 +1,6 @@
prusaslicer_add_cmake_project(Cereal
URL "https://github.com/USCiLab/cereal/archive/v1.2.2.tar.gz"
URL_HASH SHA256=1921f26d2e1daf9132da3c432e2fd02093ecaedf846e65d7679ddf868c7289c4
CMAKE_ARGS
-DJUST_INSTALL_CEREAL=on
)

11
deps/GMP/GMP.cmake vendored
View File

@ -36,11 +36,18 @@ else ()
set(_gmp_build_tgt "") # let it guess
endif()
set(_cross_compile_arg "")
if (CMAKE_CROSSCOMPILING)
# TOOLCHAIN_PREFIX should be defined in the toolchain file
set(_cross_compile_arg --host=${TOOLCHAIN_PREFIX})
endif ()
ExternalProject_Add(dep_GMP
# URL https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2
URL https://gmplib.org/download/gmp/gmp-6.2.1.tar.bz2
URL_HASH SHA256=eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/GMP
BUILD_IN_SOURCE ON
CONFIGURE_COMMAND env "CFLAGS=${_gmp_ccflags}" "CXXFLAGS=${_gmp_ccflags}" ./configure --enable-shared=no --enable-cxx=yes --enable-static=yes "--prefix=${DESTDIR}/usr/local" ${_gmp_build_tgt}
CONFIGURE_COMMAND env "CFLAGS=${_gmp_ccflags}" "CXXFLAGS=${_gmp_ccflags}" ./configure ${_cross_compile_arg} --enable-shared=no --enable-cxx=yes --enable-static=yes "--prefix=${DESTDIR}/usr/local" ${_gmp_build_tgt}
BUILD_COMMAND make -j
INSTALL_COMMAND make install
)

8
deps/JPEG/JPEG.cmake vendored Normal file
View File

@ -0,0 +1,8 @@
prusaslicer_add_cmake_project(JPEG
URL https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/2.0.6.zip
URL_HASH SHA256=017bdc33ff3a72e11301c0feb4657cb27719d7f97fa67a78ed506c594218bbf1
DEPENDS ${ZLIB_PKG}
CMAKE_ARGS
-DENABLE_SHARED=OFF
-DENABLE_STATIC=ON
)

11
deps/MPFR/MPFR.cmake vendored
View File

@ -18,10 +18,19 @@ if (MSVC)
add_custom_target(dep_MPFR SOURCES ${_output})
else ()
set(_cross_compile_arg "")
if (CMAKE_CROSSCOMPILING)
# TOOLCHAIN_PREFIX should be defined in the toolchain file
set(_cross_compile_arg --host=${TOOLCHAIN_PREFIX})
endif ()
ExternalProject_Add(dep_MPFR
URL http://ftp.vim.org/ftp/gnu/mpfr/mpfr-3.1.6.tar.bz2 https://www.mpfr.org/mpfr-3.1.6/mpfr-3.1.6.tar.bz2 # mirrors are allowed
URL_HASH SHA256=cf4f4b2d80abb79e820e78c8077b6725bbbb4e8f41896783c899087be0e94068
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/MPFR
BUILD_IN_SOURCE ON
CONFIGURE_COMMAND env "CFLAGS=${_gmp_ccflags}" "CXXFLAGS=${_gmp_ccflags}" ./configure --prefix=${DESTDIR}/usr/local --enable-shared=no --enable-static=yes --with-gmp=${DESTDIR}/usr/local ${_gmp_build_tgt}
CONFIGURE_COMMAND env "CFLAGS=${_gmp_ccflags}" "CXXFLAGS=${_gmp_ccflags}" ./configure ${_cross_compile_arg} --prefix=${DESTDIR}/usr/local --enable-shared=no --enable-static=yes --with-gmp=${DESTDIR}/usr/local ${_gmp_build_tgt}
BUILD_COMMAND make -j
INSTALL_COMMAND make install
DEPENDS dep_GMP

15
deps/NLopt/NLopt.cmake vendored Normal file
View File

@ -0,0 +1,15 @@
prusaslicer_add_cmake_project(NLopt
URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz"
URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
CMAKE_ARGS
-DNLOPT_PYTHON:BOOL=OFF
-DNLOPT_OCTAVE:BOOL=OFF
-DNLOPT_MATLAB:BOOL=OFF
-DNLOPT_GUILE:BOOL=OFF
-DNLOPT_SWIG:BOOL=OFF
-DNLOPT_TESTS:BOOL=OFF
)
if (MSVC)
add_debug_dep(dep_NLopt)
endif ()

View File

@ -1,7 +1,9 @@
prusaslicer_add_cmake_project(OpenCSG
GIT_REPOSITORY https://github.com/floriankirsch/OpenCSG.git
GIT_TAG 83e274457b46c9ad11a4ee599203250b1618f3b9 #v1.4.2
# GIT_REPOSITORY https://github.com/floriankirsch/OpenCSG.git
# GIT_TAG 83e274457b46c9ad11a4ee599203250b1618f3b9 #v1.4.2
URL https://github.com/floriankirsch/OpenCSG/archive/refs/tags/opencsg-1-4-2-release.zip
URL_HASH SHA256=51afe0db79af8386e2027d56d685177135581e0ee82ade9d7f2caff8deab5ec5
PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in ./CMakeLists.txt
DEPENDS dep_GLEW
)

17
deps/OpenEXR/OpenEXR.cmake vendored Normal file
View File

@ -0,0 +1,17 @@
prusaslicer_add_cmake_project(OpenEXR
# GIT_REPOSITORY https://github.com/openexr/openexr.git
URL https://github.com/AcademySoftwareFoundation/openexr/archive/refs/tags/v2.5.5.zip
URL_HASH SHA256=0307a3d7e1fa1e77e9d84d7e9a8694583fbbbfd50bdc6884e2c96b8ef6b902de
DEPENDS ${ZLIB_PKG}
GIT_TAG v2.5.5
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DBUILD_TESTING=OFF
-DPYILMBASE_ENABLE:BOOL=OFF
-DOPENEXR_VIEWERS_ENABLE:BOOL=OFF
-DOPENEXR_BUILD_UTILS:BOOL=OFF
)
if (MSVC)
add_debug_dep(dep_OpenEXR)
endif ()

35
deps/OpenSSL/OpenSSL.cmake vendored Normal file
View File

@ -0,0 +1,35 @@
include(ProcessorCount)
ProcessorCount(NPROC)
set(_conf_cmd "./config")
set(_cross_arch "")
set(_cross_comp_prefix_line "")
if (CMAKE_CROSSCOMPILING)
set(_conf_cmd "./Configure")
set(_cross_comp_prefix_line "--cross-compile-prefix=${TOOLCHAIN_PREFIX}-")
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
set(_cross_arch "linux-aarch64")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armhf") # For raspbian
# TODO: verify
set(_cross_arch "linux-armv4")
endif ()
endif ()
ExternalProject_Add(dep_OpenSSL
EXCLUDE_FROM_ALL ON
URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_0l.tar.gz"
URL_HASH SHA256=e2acf0cf58d9bff2b42f2dc0aee79340c8ffe2c5e45d3ca4533dd5d4f5775b1d
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/OpenSSL
BUILD_IN_SOURCE ON
CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch}
"--prefix=${DESTDIR}/usr/local"
${_cross_comp_prefix_line}
no-shared
no-ssl3-method
no-dynamic-engine
-Wa,--noexecstack
BUILD_COMMAND make depend && make "-j${NPROC}"
INSTALL_COMMAND make install_sw
)

36
deps/OpenVDB/OpenVDB.cmake vendored Normal file
View File

@ -0,0 +1,36 @@
if(BUILD_SHARED_LIBS)
set(_build_shared ON)
set(_build_static OFF)
else()
set(_build_shared OFF)
set(_build_static ON)
endif()
prusaslicer_add_cmake_project(OpenVDB
URL https://github.com/tamasmeszaros/openvdb/archive/refs/tags/v6.2.1-prusa3d.zip #v6.2.1 patched
URL_HASH SHA256=caf9f0c91976722883ff9cb32420ef142af22f7e625fc643b91c23d6e4172f62
DEPENDS dep_TBB dep_Blosc dep_OpenEXR dep_Boost
CMAKE_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DOPENVDB_BUILD_PYTHON_MODULE=OFF
-DUSE_BLOSC=ON
-DOPENVDB_CORE_SHARED=${_build_shared}
-DOPENVDB_CORE_STATIC=${_build_static}
-DOPENVDB_ENABLE_RPATH:BOOL=OFF
-DTBB_STATIC=${_build_static}
-DOPENVDB_BUILD_VDB_PRINT=ON
-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON # Centos6 has old zlib
)
if (MSVC)
if (${DEP_DEBUG})
ExternalProject_Get_Property(dep_OpenVDB BINARY_DIR)
ExternalProject_Add_Step(dep_OpenVDB build_debug
DEPENDEES build
DEPENDERS install
COMMAND ${CMAKE_COMMAND} ../dep_OpenVDB -DOPENVDB_BUILD_VDB_PRINT=OFF
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()
endif ()

12
deps/PNG/PNG.cmake vendored
View File

@ -5,10 +5,18 @@ else ()
set(_disable_neon_extension "")
endif ()
set(_patch_step "")
if (APPLE)
set(_patch_step PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/PNG.patch)
endif ()
prusaslicer_add_cmake_project(PNG
GIT_REPOSITORY https://github.com/glennrp/libpng.git
GIT_TAG v1.6.35
# GIT_REPOSITORY https://github.com/glennrp/libpng.git
# GIT_TAG v1.6.35
URL https://github.com/glennrp/libpng/archive/refs/tags/v1.6.35.zip
URL_HASH SHA256=3d22d46c566b1761a0e15ea397589b3a5f36ac09b7c785382e6470156c04247f
DEPENDS ${ZLIB_PKG}
"${_patch_step}"
CMAKE_ARGS
-DPNG_SHARED=OFF
-DPNG_STATIC=ON

26
deps/PNG/PNG.patch vendored Normal file
View File

@ -0,0 +1,26 @@
Common subdirectories: ../libpng-1.6.35-orig/arm and ./arm
Common subdirectories: ../libpng-1.6.35-orig/contrib and ./contrib
Common subdirectories: ../libpng-1.6.35-orig/intel and ./intel
Common subdirectories: ../libpng-1.6.35-orig/mips and ./mips
Only in ./: PNG.patch
diff -u ../libpng-1.6.35-orig/pngrutil.c ./pngrutil.c
--- ../libpng-1.6.35-orig/pngrutil.c 2018-07-15 20:58:00.000000000 +0200
+++ ./pngrutil.c 2021-03-24 15:59:38.687108444 +0100
@@ -422,13 +422,6 @@
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
-#if ZLIB_VERNUM >= 0x1290 && \
- defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
- if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
- /* Turn off validation of the ADLER32 checksum in IDAT chunks */
- ret = inflateValidate(&png_ptr->zstream, 0);
-#endif
-
if (ret == Z_OK)
png_ptr->zowner = owner;
Common subdirectories: ../libpng-1.6.35-orig/powerpc and ./powerpc
Common subdirectories: ../libpng-1.6.35-orig/projects and ./projects
Common subdirectories: ../libpng-1.6.35-orig/scripts and ./scripts
Common subdirectories: ../libpng-1.6.35-orig/tests and ./tests

11
deps/Qhull/Qhull.cmake vendored Normal file
View File

@ -0,0 +1,11 @@
include(GNUInstallDirs)
prusaslicer_add_cmake_project(Qhull
URL "https://github.com/qhull/qhull/archive/v8.0.1.zip"
URL_HASH SHA256=5287f5edd6a0372588f5d6640799086a4033d89d19711023ef8229dd9301d69b
CMAKE_ARGS
-DINCLUDE_INSTALL_DIR=${CMAKE_INSTALL_INCLUDEDIR}
)
if (MSVC)
add_debug_dep(dep_Qhull)
endif ()

17
deps/TBB/TBB.cmake vendored Normal file
View File

@ -0,0 +1,17 @@
prusaslicer_add_cmake_project(
TBB
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
URL_HASH SHA256=0545cb6033bd1873fcae3ea304def720a380a88292726943ae3b9b207f322efe
CMAKE_ARGS
-DTBB_BUILD_SHARED=OFF
-DTBB_BUILD_TESTS=OFF
-DTBB_BUILD_TESTS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=_debug
)
if (MSVC)
add_debug_dep(dep_TBB)
endif ()

13
deps/TIFF/TIFF.cmake vendored Normal file
View File

@ -0,0 +1,13 @@
find_package(OpenGL QUIET REQUIRED)
prusaslicer_add_cmake_project(TIFF
URL https://gitlab.com/libtiff/libtiff/-/archive/v4.1.0/libtiff-v4.1.0.zip
URL_HASH SHA256=c56edfacef0a60c0de3e6489194fcb2f24c03dbb550a8a7de5938642d045bd32
DEPENDS ${ZLIB_PKG} ${PNG_PKG} dep_JPEG
CMAKE_ARGS
-Dlzma:BOOL=OFF
-Dwebp:BOOL=OFF
-Djbig:BOOL=OFF
-Dzstd:BOOL=OFF
-Dpixarlog:BOOL=OFF
)

View File

@ -1,17 +1,8 @@
From 0c64e33bc2e4e7c011f5a64f5d9c7571a434cc86 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Sat, 16 Nov 2019 13:43:17 +0100
Subject: [PATCH] Respect BUILD_SHARED_LIBS
---
CMakeLists.txt | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0fe939d..01dfea1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -183,10 +183,12 @@ if(MINGW)
Common subdirectories: ../zlib-1.2.11/amiga and ./amiga
diff -u ../zlib-1.2.11/CMakeLists.txt ./CMakeLists.txt
--- ../zlib-1.2.11/CMakeLists.txt 2017-01-15 09:29:40.000000000 +0100
+++ ./CMakeLists.txt 2021-03-24 15:24:48.190291072 +0100
@@ -183,10 +183,12 @@
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW)
@ -28,7 +19,7 @@ index 0fe939d..01dfea1 100644
if(NOT CYGWIN)
# This property causes shared libraries on Linux to have the full version
@@ -201,7 +203,7 @@ endif()
@@ -201,7 +203,7 @@
if(UNIX)
# On unix-like platforms the library is almost always called libz
@ -37,7 +28,7 @@ index 0fe939d..01dfea1 100644
if(NOT APPLE)
set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
endif()
@@ -211,7 +213,7 @@ elseif(BUILD_SHARED_LIBS AND WIN32)
@@ -211,7 +213,7 @@
endif()
if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
@ -46,6 +37,15 @@ index 0fe939d..01dfea1 100644
RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
--
2.16.2.windows.1
Common subdirectories: ../zlib-1.2.11/contrib and ./contrib
Common subdirectories: ../zlib-1.2.11/doc and ./doc
Common subdirectories: ../zlib-1.2.11/examples and ./examples
Common subdirectories: ../zlib-1.2.11/msdos and ./msdos
Common subdirectories: ../zlib-1.2.11/nintendods and ./nintendods
Common subdirectories: ../zlib-1.2.11/old and ./old
Common subdirectories: ../zlib-1.2.11/os400 and ./os400
Common subdirectories: ../zlib-1.2.11/qnx and ./qnx
Common subdirectories: ../zlib-1.2.11/test and ./test
Common subdirectories: ../zlib-1.2.11/watcom and ./watcom
Common subdirectories: ../zlib-1.2.11/win32 and ./win32
Only in ./: ZLIB.patch

View File

@ -1,8 +1,9 @@
prusaslicer_add_cmake_project(ZLIB
GIT_REPOSITORY https://github.com/madler/zlib.git
GIT_TAG v1.2.11
PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df &&
${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-Respect-BUILD_SHARED_LIBS.patch
# GIT_REPOSITORY https://github.com/madler/zlib.git
# GIT_TAG v1.2.11
URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
URL_HASH SHA256=f5cc4ab910db99b2bdbba39ebbdc225ffc2aa04b4057bc2817f1b94b6978cfc3
PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-Respect-BUILD_SHARED_LIBS.patch
CMAKE_ARGS
-DSKIP_INSTALL_FILES=ON # Prevent installation of man pages et al.
-DCMAKE_POSITION_INDEPENDENT_CODE=ON

96
deps/deps-linux.cmake vendored
View File

@ -7,98 +7,4 @@ include("deps-unix-common.cmake")
# find_package(PNG QUIET)
# if (NOT PNG_FOUND)
# message(WARNING "No PNG dev package found in system, building static library. You should install the system package.")
# endif ()
#TODO UDEV
ExternalProject_Add(dep_boost
EXCLUDE_FROM_ALL 1
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./bootstrap.sh
--with-libraries=system,iostreams,filesystem,thread,log,locale,regex,date_time
"--prefix=${DESTDIR}/usr/local"
BUILD_COMMAND ./b2
-j ${NPROC}
--reconfigure
link=static
variant=release
threading=multi
boost.locale.icu=off
--disable-icu
cflags=-fPIC
cxxflags=-fPIC
install
INSTALL_COMMAND "" # b2 does that already
)
ExternalProject_Add(dep_libopenssl
EXCLUDE_FROM_ALL 1
URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_0l.tar.gz"
URL_HASH SHA256=e2acf0cf58d9bff2b42f2dc0aee79340c8ffe2c5e45d3ca4533dd5d4f5775b1d
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./config
"--prefix=${DESTDIR}/usr/local"
"--libdir=lib"
no-shared
no-ssl3-method
no-dynamic-engine
-Wa,--noexecstack
BUILD_COMMAND make depend && make "-j${NPROC}"
INSTALL_COMMAND make install_sw
)
ExternalProject_Add(dep_libcurl
EXCLUDE_FROM_ALL 1
DEPENDS dep_libopenssl
URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz"
URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./configure
--enable-static
--disable-shared
"--with-ssl=${DESTDIR}/usr/local"
--with-pic
--enable-ipv6
--enable-versioned-symbols
--enable-threaded-resolver
--with-random=/dev/urandom
# CA root certificate paths will be set for openssl at runtime.
--without-ca-bundle
--without-ca-path
--with-ca-fallback # to look for the ssl backend's ca store
--disable-ldap
--disable-ldaps
--disable-manual
--disable-rtsp
--disable-dict
--disable-telnet
--disable-pop3
--disable-imap
--disable-smb
--disable-smtp
--disable-gopher
--without-gssapi
--without-libpsl
--without-libidn2
--without-gnutls
--without-polarssl
--without-mbedtls
--without-cyassl
--without-nss
--without-axtls
--without-brotli
--without-libmetalink
--without-libssh
--without-libssh2
--without-librtmp
--without-nghttp2
--without-zsh-functions-dir
BUILD_COMMAND make "-j${NPROC}"
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
)
add_dependencies(dep_openvdb dep_boost)
# endif ()

142
deps/deps-macos.cmake vendored
View File

@ -16,76 +16,76 @@ set(DEP_CMAKE_OPTS
include("deps-unix-common.cmake")
ExternalProject_Add(dep_boost
EXCLUDE_FROM_ALL 1
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./bootstrap.sh
--with-toolset=clang
--with-libraries=system,iostreams,filesystem,thread,log,locale,regex,date_time
"--prefix=${DESTDIR}/usr/local"
BUILD_COMMAND ./b2
-j ${NPROC}
--reconfigure
toolset=clang
link=static
variant=release
threading=multi
boost.locale.icu=off
--disable-icu
"cflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
"cxxflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
"mflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
"mmflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
install
INSTALL_COMMAND "" # b2 does that already
)
# ExternalProject_Add(dep_boost
# EXCLUDE_FROM_ALL 1
# URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz"
# URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
# BUILD_IN_SOURCE 1
# CONFIGURE_COMMAND ./bootstrap.sh
# --with-toolset=clang
# --with-libraries=system,iostreams,filesystem,thread,log,locale,regex,date_time
# "--prefix=${DESTDIR}/usr/local"
# BUILD_COMMAND ./b2
# -j ${NPROC}
# --reconfigure
# toolset=clang
# link=static
# variant=release
# threading=multi
# boost.locale.icu=off
# --disable-icu
# "cflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
# "cxxflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
# "mflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
# "mmflags=-fPIC -mmacosx-version-min=${DEP_OSX_TARGET}"
# install
# INSTALL_COMMAND "" # b2 does that already
# )
ExternalProject_Add(dep_libcurl
EXCLUDE_FROM_ALL 1
URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz"
URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ./configure
--enable-static
--disable-shared
"--with-ssl=${DESTDIR}/usr/local"
--with-pic
--enable-ipv6
--enable-versioned-symbols
--enable-threaded-resolver
--with-darwinssl
--without-ssl # disables OpenSSL
--disable-ldap
--disable-ldaps
--disable-manual
--disable-rtsp
--disable-dict
--disable-telnet
--disable-pop3
--disable-imap
--disable-smb
--disable-smtp
--disable-gopher
--without-gssapi
--without-libpsl
--without-libidn2
--without-gnutls
--without-polarssl
--without-mbedtls
--without-cyassl
--without-nss
--without-axtls
--without-brotli
--without-libmetalink
--without-libssh
--without-libssh2
--without-librtmp
--without-nghttp2
--without-zsh-functions-dir
BUILD_COMMAND make "-j${NPROC}"
INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
)
add_dependencies(dep_openvdb dep_boost)
# ExternalProject_Add(dep_libcurl
# EXCLUDE_FROM_ALL 1
# URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz"
# URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115
# BUILD_IN_SOURCE 1
# CONFIGURE_COMMAND ./configure
# --enable-static
# --disable-shared
# "--with-ssl=${DESTDIR}/usr/local"
# --with-pic
# --enable-ipv6
# --enable-versioned-symbols
# --enable-threaded-resolver
# --with-darwinssl
# --without-ssl # disables OpenSSL
# --disable-ldap
# --disable-ldaps
# --disable-manual
# --disable-rtsp
# --disable-dict
# --disable-telnet
# --disable-pop3
# --disable-imap
# --disable-smb
# --disable-smtp
# --disable-gopher
# --without-gssapi
# --without-libpsl
# --without-libidn2
# --without-gnutls
# --without-polarssl
# --without-mbedtls
# --without-cyassl
# --without-nss
# --without-axtls
# --without-brotli
# --without-libmetalink
# --without-libssh
# --without-libssh2
# --without-librtmp
# --without-nghttp2
# --without-zsh-functions-dir
# BUILD_COMMAND make "-j${NPROC}"
# INSTALL_COMMAND make install "DESTDIR=${DESTDIR}"
# )
# add_dependencies(dep_openvdb dep_boost)

54
deps/deps-mingw.cmake vendored
View File

@ -6,57 +6,3 @@ 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://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
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
--with-date_time
"--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}
)

View File

@ -17,113 +17,3 @@ endif ()
# if (NOT EXPAT_FOUND)
# message(WARNING "No EXPAT dev package found in system, building static library. Consider installing the system package.")
# endif ()
ExternalProject_Add(dep_tbb
EXCLUDE_FROM_ALL 1
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
URL_HASH SHA256=0545cb6033bd1873fcae3ea304def720a380a88292726943ae3b9b207f322efe
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}
)
ExternalProject_Add(dep_gtest
EXCLUDE_FROM_ALL 1
URL "https://github.com/google/googletest/archive/release-1.8.1.tar.gz"
URL_HASH SHA256=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
CMAKE_ARGS -DBUILD_GMOCK=OFF ${DEP_CMAKE_OPTS} -DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
)
ExternalProject_Add(dep_cereal
EXCLUDE_FROM_ALL 1
URL "https://github.com/USCiLab/cereal/archive/v1.2.2.tar.gz"
# URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
CMAKE_ARGS
-DJUST_INSTALL_CEREAL=on
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
${DEP_CMAKE_OPTS}
)
ExternalProject_Add(dep_nlopt
EXCLUDE_FROM_ALL 1
URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz"
URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
CMAKE_ARGS
-DBUILD_SHARED_LIBS=OFF
-DNLOPT_PYTHON=OFF
-DNLOPT_OCTAVE=OFF
-DNLOPT_MATLAB=OFF
-DNLOPT_GUILE=OFF
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
${DEP_CMAKE_OPTS}
)
ExternalProject_Add(dep_qhull
EXCLUDE_FROM_ALL 1
#URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz"
#URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0
GIT_REPOSITORY https://github.com/qhull/qhull.git
GIT_TAG 7afedcc73666e46a9f1d74632412ebecf53b1b30 # v7.3.2 plus the mac build patch
CMAKE_ARGS
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
${DEP_CMAKE_OPTS}
)
ExternalProject_Add(dep_blosc
EXCLUDE_FROM_ALL 1
GIT_REPOSITORY https://github.com/Blosc/c-blosc.git
GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0
DEPENDS
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=d
-DBUILD_SHARED=OFF
-DBUILD_STATIC=ON
-DBUILD_TESTS=OFF
-DBUILD_BENCHMARKS=OFF
-DPREFER_EXTERNAL_ZLIB=ON
PATCH_COMMAND ${GIT_EXECUTABLE} reset --hard && git clean -df &&
${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch
)
ExternalProject_Add(dep_openexr
EXCLUDE_FROM_ALL 1
GIT_REPOSITORY https://github.com/openexr/openexr.git
GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DBUILD_TESTING=OFF
-DPYILMBASE_ENABLE:BOOL=OFF
-DOPENEXR_VIEWERS_ENABLE:BOOL=OFF
-DOPENEXR_BUILD_UTILS:BOOL=OFF
)
ExternalProject_Add(dep_openvdb
EXCLUDE_FROM_ALL 1
GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git
GIT_TAG aebaf8d95be5e57fd33949281ec357db4a576c2e #v6.2.1
DEPENDS dep_blosc dep_openexr dep_tbb
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DCMAKE_DEBUG_POSTFIX=d
-DCMAKE_PREFIX_PATH=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DOPENVDB_BUILD_PYTHON_MODULE=OFF
-DUSE_BLOSC=ON
-DOPENVDB_CORE_SHARED=OFF
-DOPENVDB_CORE_STATIC=ON
-DTBB_STATIC=ON
-DOPENVDB_BUILD_VDB_PRINT=ON
-DDISABLE_DEPENDENCY_VERSION_CHECKS=ON
PATCH_COMMAND PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df &&
${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch
)

View File

@ -53,154 +53,6 @@ if (${DEP_DEBUG})
endif ()
endmacro()
ExternalProject_Add(dep_boost
EXCLUDE_FROM_ALL 1
URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz"
URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND bootstrap.bat
BUILD_COMMAND b2.exe
-j "${NPROC}"
--with-system
--with-iostreams
--with-filesystem
--with-thread
--with-log
--with-locale
--with-regex
--with-date_time
"--prefix=${DESTDIR}/usr/local"
"address-model=${DEPS_BITS}"
"toolset=${DEP_BOOST_TOOLSET}"
link=static
variant=release
threading=multi
boost.locale.icu=off
--disable-icu
"${DEP_BOOST_DEBUG}" release install
INSTALL_COMMAND "" # b2 does that already
)
ExternalProject_Add(dep_tbb
EXCLUDE_FROM_ALL 1
URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
URL_HASH SHA256=0545cb6033bd1873fcae3ea304def720a380a88292726943ae3b9b207f322efe
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DCMAKE_DEBUG_POSTFIX=_debug
-DTBB_BUILD_SHARED=OFF
-DTBB_BUILD_TESTS=OFF
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
add_debug_dep(dep_tbb)
# ExternalProject_Add(dep_gtest
# EXCLUDE_FROM_ALL 1
# URL "https://github.com/google/googletest/archive/release-1.8.1.tar.gz"
# URL_HASH SHA256=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
# CMAKE_GENERATOR "${DEP_MSVC_GEN}"
# CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
# CMAKE_ARGS
# -DBUILD_GMOCK=OFF
# -Dgtest_force_shared_crt=ON
# -DCMAKE_POSITION_INDEPENDENT_CODE=ON
# "-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
# BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
# INSTALL_COMMAND ""
# )
# add_debug_dep(dep_gtest)
ExternalProject_Add(dep_cereal
EXCLUDE_FROM_ALL 1
URL "https://github.com/USCiLab/cereal/archive/v1.2.2.tar.gz"
# URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DJUST_INSTALL_CEREAL=on
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
ExternalProject_Add(dep_nlopt
EXCLUDE_FROM_ALL 1
URL "https://github.com/stevengj/nlopt/archive/v2.5.0.tar.gz"
URL_HASH SHA256=c6dd7a5701fff8ad5ebb45a3dc8e757e61d52658de3918e38bab233e7fd3b4ae
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DBUILD_SHARED_LIBS=OFF
-DNLOPT_PYTHON=OFF
-DNLOPT_OCTAVE=OFF
-DNLOPT_MATLAB=OFF
-DNLOPT_GUILE=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=d
"-DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR}\\usr\\local"
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
add_debug_dep(dep_nlopt)
if (${DEPS_BITS} EQUAL 32)
set(DEP_LIBCURL_TARGET "x86")
else ()
set(DEP_LIBCURL_TARGET "x64")
endif ()
ExternalProject_Add(dep_libcurl
EXCLUDE_FROM_ALL 1
URL "https://curl.haxx.se/download/curl-7.58.0.tar.gz"
URL_HASH SHA256=cc245bf9a1a42a45df491501d97d5593392a03f7b4f07b952793518d97666115
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ""
BUILD_COMMAND cd winbuild && nmake /f Makefile.vc mode=static "VC=${DEP_VS_VER}" GEN_PDB=yes DEBUG=no "MACHINE=${DEP_LIBCURL_TARGET}"
INSTALL_COMMAND cd builds\\libcurl-*-release-*-winssl
&& "${CMAKE_COMMAND}" -E copy_directory include "${DESTDIR}\\usr\\local\\include"
&& "${CMAKE_COMMAND}" -E copy_directory lib "${DESTDIR}\\usr\\local\\lib"
)
if (${DEP_DEBUG})
ExternalProject_Get_Property(dep_libcurl SOURCE_DIR)
ExternalProject_Add_Step(dep_libcurl build_debug
DEPENDEES build
DEPENDERS install
COMMAND cd winbuild && nmake /f Makefile.vc mode=static "VC=${DEP_VS_VER}" GEN_PDB=yes DEBUG=yes "MACHINE=${DEP_LIBCURL_TARGET}"
WORKING_DIRECTORY "${SOURCE_DIR}"
)
ExternalProject_Add_Step(dep_libcurl install_debug
DEPENDEES install
COMMAND cd builds\\libcurl-*-debug-*-winssl
&& "${CMAKE_COMMAND}" -E copy_directory include "${DESTDIR}\\usr\\local\\include"
&& "${CMAKE_COMMAND}" -E copy_directory lib "${DESTDIR}\\usr\\local\\lib"
WORKING_DIRECTORY "${SOURCE_DIR}"
)
endif ()
ExternalProject_Add(dep_qhull
EXCLUDE_FROM_ALL 1
#URL "https://github.com/qhull/qhull/archive/v7.3.2.tar.gz"
#URL_HASH SHA256=619c8a954880d545194bc03359404ef36a1abd2dde03678089459757fd790cb0
GIT_REPOSITORY https://github.com/qhull/qhull.git
GIT_TAG 7afedcc73666e46a9f1d74632412ebecf53b1b30 # v7.3.2 plus the mac build patch
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=d
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
add_debug_dep(dep_qhull)
if (${DEPS_BITS} EQUAL 32)
set(DEP_WXWIDGETS_TARGET "")
set(DEP_WXWIDGETS_LIBDIR "vc_lib")
@ -210,90 +62,3 @@ else ()
endif ()
find_package(Git REQUIRED)
ExternalProject_Add(dep_blosc
EXCLUDE_FROM_ALL 1
#URL https://github.com/Blosc/c-blosc/archive/v1.17.0.zip
#URL_HASH SHA256=7463a1df566704f212263312717ab2c36b45d45cba6cd0dccebf91b2cc4b4da9
GIT_REPOSITORY https://github.com/Blosc/c-blosc.git
GIT_TAG e63775855294b50820ef44d1b157f4de1cc38d3e #v1.17.0
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_DEBUG_POSTFIX=d
-DBUILD_SHARED=OFF
-DBUILD_STATIC=ON
-DBUILD_TESTS=OFF
-DBUILD_BENCHMARKS=OFF
-DPREFER_EXTERNAL_ZLIB=ON
-DBLOSC_IS_SUBPROJECT:BOOL=ON
-DBLOSC_INSTALL:BOOL=ON
PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df &&
${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/blosc-mods.patch
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
add_debug_dep(dep_blosc)
ExternalProject_Add(dep_openexr
EXCLUDE_FROM_ALL 1
GIT_REPOSITORY https://github.com/openexr/openexr.git
GIT_TAG eae0e337c9f5117e78114fd05f7a415819df413a #v2.4.0
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DBUILD_TESTING=OFF
-DPYILMBASE_ENABLE:BOOL=OFF
-DOPENEXR_VIEWERS_ENABLE:BOOL=OFF
-DOPENEXR_BUILD_UTILS:BOOL=OFF
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
INSTALL_COMMAND ""
)
add_debug_dep(dep_openexr)
ExternalProject_Add(dep_openvdb
EXCLUDE_FROM_ALL 1
#URL https://github.com/AcademySoftwareFoundation/openvdb/archive/v6.2.1.zip
#URL_HASH SHA256=dc337399dce8e1c9f21f20e97b1ce7e4933cb0a63bb3b8b734d8fcc464aa0c48
GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb.git
GIT_TAG aebaf8d95be5e57fd33949281ec357db4a576c2e #v6.2.1
DEPENDS dep_blosc dep_openexr dep_tbb dep_boost
CMAKE_GENERATOR "${DEP_MSVC_GEN}"
CMAKE_GENERATOR_PLATFORM "${DEP_PLATFORM}"
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${DESTDIR}/usr/local
-DCMAKE_DEBUG_POSTFIX=d
-DCMAKE_PREFIX_PATH=${DESTDIR}/usr/local
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DOPENVDB_BUILD_PYTHON_MODULE=OFF
-DUSE_BLOSC=ON
-DOPENVDB_CORE_SHARED=OFF
-DOPENVDB_CORE_STATIC=ON
-DTBB_STATIC=ON
-DOPENVDB_BUILD_VDB_PRINT=ON
BUILD_COMMAND msbuild /m /P:Configuration=Release INSTALL.vcxproj
PATCH_COMMAND ${GIT_EXECUTABLE} checkout -f -- . && git clean -df &&
${GIT_EXECUTABLE} apply --whitespace=fix ${CMAKE_CURRENT_SOURCE_DIR}/openvdb-mods.patch
INSTALL_COMMAND ""
)
if (${DEP_DEBUG})
ExternalProject_Get_Property(dep_openvdb BINARY_DIR)
ExternalProject_Add_Step(dep_openvdb build_debug
DEPENDEES build
DEPENDERS install
COMMAND ${CMAKE_COMMAND} ../dep_openvdb -DOPENVDB_BUILD_VDB_PRINT=OFF
COMMAND msbuild /m /P:Configuration=Debug INSTALL.vcxproj
WORKING_DIRECTORY "${BINARY_DIR}"
)
endif ()

1908
deps/openvdb-mods.patch vendored

File diff suppressed because it is too large Load Diff

49
deps/qhull-mods.patch vendored
View File

@ -1,49 +0,0 @@
From 7f55a56b3d112f4dffbf21b1722f400c64bf03b1 Mon Sep 17 00:00:00 2001
From: tamasmeszaros <meszaros.q@gmail.com>
Date: Mon, 21 Oct 2019 16:52:04 +0200
Subject: [PATCH] Fix the build on macOS
---
CMakeLists.txt | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 07d3da2..14df8e9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -626,18 +626,18 @@ install(TARGETS ${qhull_TARGETS_INSTALL} EXPORT QhullTargets
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake"
VERSION ${qhull_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT QhullTargets
- FILE "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullTargets.cmake"
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullTargets.cmake"
NAMESPACE Qhull::
)
configure_file(${PROJECT_SOURCE_DIR}/build/config.cmake.in
- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake"
@ONLY
)
@@ -652,8 +652,8 @@ install(EXPORT QhullTargets
)
install(
FILES
- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfig.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/Qhull/QhullConfigVersion.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/QhullExport/QhullConfigVersion.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
--
2.17.1

View File

@ -1,6 +1,5 @@
set(_wx_git_tag v3.1.4-patched)
# set(_patch_command "")
set(_wx_toolkit "")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(_gtk_ver 2)
@ -11,10 +10,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
endif()
prusaslicer_add_cmake_project(wxWidgets
GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
GIT_TAG ${_wx_git_tag}
# PATCH_COMMAND "${_patch_command}"
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG}
# GIT_REPOSITORY "https://github.com/prusa3d/wxWidgets"
# GIT_TAG tm_cross_compile #${_wx_git_tag}
URL https://github.com/prusa3d/wxWidgets/archive/refs/heads/v3.1.4-patched.zip
URL_HASH SHA256=a1e145a083d173cf320c0bd8522c7ee5829052b49b68fe5268ac84f0c576b940
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG
CMAKE_ARGS
-DwxBUILD_PRECOMP=ON
${_wx_toolkit}
@ -28,9 +28,11 @@ prusaslicer_add_cmake_project(wxWidgets
-DwxUSE_ZLIB=sys
-DwxUSE_REGEX=builtin
-DwxUSE_LIBXPM=builtin
-DwxUSE_LIBJPEG=builtin
-DwxUSE_LIBTIFF=builtin
-DwxUSE_LIBJPEG=sys
-DwxUSE_LIBTIFF=sys
-DwxUSE_EXPAT=sys
-DwxUSE_LIBSDL=OFF
-DwxUSE_XTEST=OFF
)
if (MSVC)

View File

@ -1,168 +0,0 @@
// Patched in PrusaSlicer: These two were missing:
#define png_write_eXIf wx_png_write_eXIf
#define png_handle_eXIf wx_png_handle_eXIf
#define png_sRGB_table wx_png_sRGB_table
#define png_sRGB_base wx_png_sRGB_base
#define png_sRGB_delta wx_png_sRGB_delta
#define png_zstream_error wx_png_zstream_error
#define png_free_buffer_list wx_png_free_buffer_list
#define png_fixed wx_png_fixed
#define png_user_version_check wx_png_user_version_check
#define png_malloc_base wx_png_malloc_base
#define png_malloc_array wx_png_malloc_array
#define png_realloc_array wx_png_realloc_array
#define png_create_png_struct wx_png_create_png_struct
#define png_destroy_png_struct wx_png_destroy_png_struct
#define png_free_jmpbuf wx_png_free_jmpbuf
#define png_zalloc wx_png_zalloc
#define png_zfree wx_png_zfree
#define png_default_read_data wx_png_default_read_data
#define png_push_fill_buffer wx_png_push_fill_buffer
#define png_default_write_data wx_png_default_write_data
#define png_default_flush wx_png_default_flush
#define png_reset_crc wx_png_reset_crc
#define png_write_data wx_png_write_data
#define png_read_sig wx_png_read_sig
#define png_read_chunk_header wx_png_read_chunk_header
#define png_read_data wx_png_read_data
#define png_crc_read wx_png_crc_read
#define png_crc_finish wx_png_crc_finish
#define png_crc_error wx_png_crc_error
#define png_calculate_crc wx_png_calculate_crc
#define png_flush wx_png_flush
#define png_write_IHDR wx_png_write_IHDR
#define png_write_PLTE wx_png_write_PLTE
#define png_compress_IDAT wx_png_compress_IDAT
#define png_write_IEND wx_png_write_IEND
#define png_write_gAMA_fixed wx_png_write_gAMA_fixed
#define png_write_sBIT wx_png_write_sBIT
#define png_write_cHRM_fixed wx_png_write_cHRM_fixed
#define png_write_sRGB wx_png_write_sRGB
#define png_write_iCCP wx_png_write_iCCP
#define png_write_sPLT wx_png_write_sPLT
#define png_write_tRNS wx_png_write_tRNS
#define png_write_bKGD wx_png_write_bKGD
#define png_write_hIST wx_png_write_hIST
#define png_write_tEXt wx_png_write_tEXt
#define png_write_zTXt wx_png_write_zTXt
#define png_write_iTXt wx_png_write_iTXt
#define png_set_text_2 wx_png_set_text_2
#define png_write_oFFs wx_png_write_oFFs
#define png_write_pCAL wx_png_write_pCAL
#define png_write_pHYs wx_png_write_pHYs
#define png_write_tIME wx_png_write_tIME
#define png_write_sCAL_s wx_png_write_sCAL_s
#define png_write_finish_row wx_png_write_finish_row
#define png_write_start_row wx_png_write_start_row
#define png_combine_row wx_png_combine_row
#define png_do_read_interlace wx_png_do_read_interlace
#define png_do_write_interlace wx_png_do_write_interlace
#define png_read_filter_row wx_png_read_filter_row
#define png_write_find_filter wx_png_write_find_filter
#define png_read_IDAT_data wx_png_read_IDAT_data
#define png_read_finish_IDAT wx_png_read_finish_IDAT
#define png_read_finish_row wx_png_read_finish_row
#define png_read_start_row wx_png_read_start_row
#define png_zlib_inflate wx_png_zlib_inflate
#define png_read_transform_info wx_png_read_transform_info
#define png_do_strip_channel wx_png_do_strip_channel
#define png_do_swap wx_png_do_swap
#define png_do_packswap wx_png_do_packswap
#define png_do_invert wx_png_do_invert
#define png_do_bgr wx_png_do_bgr
#define png_handle_IHDR wx_png_handle_IHDR
#define png_handle_PLTE wx_png_handle_PLTE
#define png_handle_IEND wx_png_handle_IEND
#define png_handle_bKGD wx_png_handle_bKGD
#define png_handle_cHRM wx_png_handle_cHRM
#define png_handle_gAMA wx_png_handle_gAMA
#define png_handle_hIST wx_png_handle_hIST
#define png_handle_iCCP wx_png_handle_iCCP
#define png_handle_iTXt wx_png_handle_iTXt
#define png_handle_oFFs wx_png_handle_oFFs
#define png_handle_pCAL wx_png_handle_pCAL
#define png_handle_pHYs wx_png_handle_pHYs
#define png_handle_sBIT wx_png_handle_sBIT
#define png_handle_sCAL wx_png_handle_sCAL
#define png_handle_sPLT wx_png_handle_sPLT
#define png_handle_sRGB wx_png_handle_sRGB
#define png_handle_tEXt wx_png_handle_tEXt
#define png_handle_tIME wx_png_handle_tIME
#define png_handle_tRNS wx_png_handle_tRNS
#define png_handle_zTXt wx_png_handle_zTXt
#define png_check_chunk_name wx_png_check_chunk_name
#define png_check_chunk_length wx_png_check_chunk_length
#define png_handle_unknown wx_png_handle_unknown
#define png_chunk_unknown_handling wx_png_chunk_unknown_handling
#define png_do_read_transformations wx_png_do_read_transformations
#define png_do_write_transformations wx_png_do_write_transformations
#define png_init_read_transformations wx_png_init_read_transformations
#define png_push_read_chunk wx_png_push_read_chunk
#define png_push_read_sig wx_png_push_read_sig
#define png_push_check_crc wx_png_push_check_crc
#define png_push_save_buffer wx_png_push_save_buffer
#define png_push_restore_buffer wx_png_push_restore_buffer
#define png_push_read_IDAT wx_png_push_read_IDAT
#define png_process_IDAT_data wx_png_process_IDAT_data
#define png_push_process_row wx_png_push_process_row
#define png_push_handle_unknown wx_png_push_handle_unknown
#define png_push_have_info wx_png_push_have_info
#define png_push_have_end wx_png_push_have_end
#define png_push_have_row wx_png_push_have_row
#define png_push_read_end wx_png_push_read_end
#define png_process_some_data wx_png_process_some_data
#define png_read_push_finish_row wx_png_read_push_finish_row
#define png_push_handle_tEXt wx_png_push_handle_tEXt
#define png_push_read_tEXt wx_png_push_read_tEXt
#define png_push_handle_zTXt wx_png_push_handle_zTXt
#define png_push_read_zTXt wx_png_push_read_zTXt
#define png_push_handle_iTXt wx_png_push_handle_iTXt
#define png_push_read_iTXt wx_png_push_read_iTXt
#define png_colorspace_set_gamma wx_png_colorspace_set_gamma
#define png_colorspace_sync_info wx_png_colorspace_sync_info
#define png_colorspace_sync wx_png_colorspace_sync
#define png_colorspace_set_chromaticities wx_png_colorspace_set_chromaticities
#define png_colorspace_set_endpoints wx_png_colorspace_set_endpoints
#define png_colorspace_set_sRGB wx_png_colorspace_set_sRGB
#define png_colorspace_set_ICC wx_png_colorspace_set_ICC
#define png_icc_check_length wx_png_icc_check_length
#define png_icc_check_header wx_png_icc_check_header
#define png_icc_check_tag_table wx_png_icc_check_tag_table
#define png_icc_set_sRGB wx_png_icc_set_sRGB
#define png_colorspace_set_rgb_coefficients wx_png_colorspace_set_rgb_coefficients
#define png_check_IHDR wx_png_check_IHDR
#define png_do_check_palette_indexes wx_png_do_check_palette_indexes
#define png_fixed_error wx_png_fixed_error
#define png_safecat wx_png_safecat
#define png_format_number wx_png_format_number
#define png_warning_parameter wx_png_warning_parameter
#define png_warning_parameter_unsigned wx_png_warning_parameter_unsigned
#define png_warning_parameter_signed wx_png_warning_parameter_signed
#define png_formatted_warning wx_png_formatted_warning
#define png_app_warning wx_png_app_warning
#define png_app_error wx_png_app_error
#define png_chunk_report wx_png_chunk_report
#define png_ascii_from_fp wx_png_ascii_from_fp
#define png_ascii_from_fixed wx_png_ascii_from_fixed
#define png_check_fp_number wx_png_check_fp_number
#define png_check_fp_string wx_png_check_fp_string
#define png_muldiv wx_png_muldiv
#define png_muldiv_warn wx_png_muldiv_warn
#define png_reciprocal wx_png_reciprocal
#define png_reciprocal2 wx_png_reciprocal2
#define png_gamma_significant wx_png_gamma_significant
#define png_gamma_correct wx_png_gamma_correct
#define png_gamma_16bit_correct wx_png_gamma_16bit_correct
#define png_gamma_8bit_correct wx_png_gamma_8bit_correct
#define png_destroy_gamma_table wx_png_destroy_gamma_table
#define png_build_gamma_table wx_png_build_gamma_table
#define png_safe_error wx_png_safe_error
#define png_safe_warning wx_png_safe_warning
#define png_safe_execute wx_png_safe_execute
#define png_image_error wx_png_image_error
#define png_check_keyword wx_png_check_keyword

168
resources/data/hints.ini Normal file
View File

@ -0,0 +1,168 @@
[hint:Perspective camera]
text = Perspective camera\nDid you know that you can use the <b>K</b> key to quickly switch between an orthographic and perspective camera?
[hint:Camera Views]
text = Camera Views\nDid you know that you can use the number keys <b>0-6</b> to quickly switch between predefined camera angles?
[hint:Place on face]
text = Place on face\nDid you know that you can quickly orient a model so that one of its faces sits on the print bed? Select the<a>Place on face</a>function or press the <b>F</b> key.
hypertext_type = gizmo
hypertext_gizmo_item = place
[hint:Set number of instances]
text = Set number of instances\nDid you know that you can right-click a model and set an exact number of instances instead of copy-pasting it several times?
[hint:Combine infill]
text = Combine infill\nDid you know that you can print the infill with a higher layer height compared to perimeters to save print time using the setting<a>Combine infill every.</a>
hypertext_type = settings
hypertext_settings_opt = infill_every_layers
hypertext_settings_type = 1
hypertext_settings_category = Infill
disabled_modes = SLA; simple
[hint:Hiding sidebar]
text = Hiding sidebar\nDid you know that you can hide the right sidebar using the shortcut <b>Shift+Tab</b>? You can also enable the icon for this from the<a>Preferences.</a>
hypertext_type = preferences
hypertext_preferences_page = 2
[hint:Variable layer height]
text = Variable layer height\nDid you know that you can print different regions of your model with a different layer height and smooth the transitions between them? Try the<a>Variable layer height tool.</a>(Not available for SLA printers.)
hypertext_type = plater
hypertext_plater_item = layersediting
disabled_modes = SLA
[hint:Undo/redo history]
text = Undo/redo history\nDid you know that you can right-click the<a>undo/redo arrows</a>to see the history of changes and to undo or redo several actions at once?
hypertext_type = plater
hypertext_plater_item = undo
[hint:Auto-arrange settings]
text = Auto-arrange settings\nDid you know that you can right-click the<a>auto-arrange icon</a>to adjust the size of the gap between objects and to allow automatic rotations?
hypertext_type = plater
hypertext_plater_item = arrange
[hint:Reload from disk]
text = Reload from disk\nDid you know that if you created a newer version of your model, you can simply reload it in PrusaSlicer? Right-click the model in the 3D view and choose Reload from disk. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/reload-from-disk_120427
[hint:Different layer height for each model]
text = Different layer height for each model\nDid you know that you can print each model on the plater with a different layer height? Right-click the model in the 3D view, choose Layers and Perimeters and adjust the values in the right panel. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/per-model-settings_1674
[hint:Solid infill threshold area]
text = Solid infill threshold area\nDid you know that you can make parts of your model with a small cross-section be filled with solid infill automatically? Set the<a>Solid infill threshold area.</a>(Expert mode only.)
hypertext_type = settings
hypertext_settings_opt = solid_infill_below_area
hypertext_settings_type = 1
hypertext_settings_category = Infill
disabled_modes = SLA; simple; advanced
[hint:Search functionality]
text = Search functionality\n Did you know that you use the<a>Search</a>tool to quickly find a specific PrusaSlicer setting? Or use the familiar shortcut <b>Ctrl+F</b>.
hypertext_type = plater
hypertext_plater_item = search
[hint:Box selection]
text = Box selection\nDid you know that you can do a box selection with Shift+Mouse drag? You can also box-deselect objects with <b>Alt+Mouse drag</b>.
[hint:Zoom on selected objects or on all objects if none selected]
text =Zoom on selected objects or on all objects if none selected\nDid you know that you can zoom in on selected objects by pressing the <b>Z</b> key? If none are selected, the camera will zoom on all objects in the scene.
[hint:Shapes gallery]
text = Shapes gallery\nDid you know that PrusaSlicer has a Shapes Gallery? You can use the included models as modifiers, negative volumes or as printable objects. Right-click the platter and select<a>Add Shape - Gallery.</a>
hypertext_type = gallery
disable_modes = simple
[hint:Printable toggle]
text = Printable toggle\nDid you know that you can disable the G-code generation for the selected model without having to move or delete it? Toggle the Printable property of a model from the Right-click context menu.
[hint:Mirror]
text = Mirror\nDid you know that you can mirror the selected model to create a reversed version of it? Right-click the model, select Mirror and pick the mirror axis.
[hint:PageUp / PageDown quick rotation by 45 degrees]
text = PageUp / PageDown quick rotation by 45 degrees\nDid you know that you can quickly rotate selected models by 45 degrees around the Z-axis clockwise or counter-clockwise by pressing <b>Page Up</b> or <b>Page Down</b> respectively?
[hint:Load config from G-code]
text = Load config from G-code\nDid you know that you can use File-Import Config to load print, filament and printer profiles from an existing G-code file? Similarly, you can use File-Import SL1 archive, which also lets you reconstruct 3D models from the voxel data.
[hint:Ironing]
text = Ironing\nDid you know that you can smooth top surfaces of prints using Ironing? The nozzle will run a special second infill phase at the same layer to fill in holes and flatten any lifted plastic. Read more in the<a>documentation.</a> (Requires Advanced or Expert mode.)
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/ironing_177488
disabled_modes = SLA; simple
[hint:Fuzzy skin]
text = Fuzzy skin\nDid you know that you can create rough fibre-like texture on the sides of your models using the<a>Fuzzy skin</a>feature? You can also use modifiers to apply fuzzy-skin only to a portion of your model.
hypertext_type = settings
hypertext_settings_opt = fuzzy_skin
hypertext_settings_type = 1
hypertext_settings_category = Layers and perimeters
disabled_modes = SLA
[hint:Negative volume]
text = Negative volume\nDid you know that you can subtract one mesh from another using the Negative volume modifier? That way you can, for example, create easily resizable holes directly in PrusaSlicer. Read more in the<a>documentation.</a>(Requires Advanced or Expert mode.)
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/negative-volume_238503
disabled_modes = SLA; simple
[hint:Paint-on supports]
text = Paint-on supports\nDid you know that you can paint directly on the object and select areas, where supports should be enforced or blocked? Try the<a>Paint-on supports</a>feature. (Requires Advanced or Expert mode.)
hypertext_type = gizmo
hypertext_gizmo_item = fdm_supports
disabled_modes = SLA; simple
[hint:Paint-on seam]
text = Paint-on seam\nDid you know that you can paint directly on the object and select where to place the start/endpoint of each perimeter loop? Try the<a>Seam painting</a>feature. (Requires Advanced or Expert mode.)
hypertext_type = gizmo
hypertext_gizmo_item = seam
disabled_modes = SLA; simple
[hint:Insert Pause]
text = Insert Pause\nDid you know that you can schedule the print to pause at a specific layer? Right-click the layer slider in the Preview and select Add pause print (M601). This can be used to insert magnets, weights or nuts into your prints. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/insert-pause-or-custom-g-code-at-layer_120490#insert-pause-at-layer
[hint:Insert Custom G-code]
text = Insert Custom G-code\nDid you know that you can insert a custom G-code at a specific layer? Right-click the layer in the Preview and select Add custom G-code. With this function you can, for example, create a temperature tower. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/insert-pause-or-custom-g-code-at-layer_120490#insert-custom-g-code-at-layer
[hint:Configuration snapshots]
text = Configuration snapshots\nDid you know that roll back to a complete backup of all system and user profiles? You can view and move back and forth between snapshots using the Configuration - Configuration snapshots menu. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/configuration-snapshots_1776
[hint:Minimum wall thickness]
text = Minimum wall thickness\nDid you know that instead of the number of top and bottom layers, you can define the<a>Minimum shell thickness</a>in millimeters? This feature is especially useful when using the variable layer height function.
hypertext_type = settings
hypertext_settings_opt = top_solid_min_thickness
hypertext_settings_type = 1
hypertext_settings_category = Layers and perimeters
disabled_modes = SLA
[hint:Settings in non-modal window]
text = Settings in non-modal window\nDid you know that you can open the Settings in a new non-modal window? This means you can have settings open on one screen and the G-code Preview on the other. Go to the<a>Preferences</a>and select Settings in non-modal window.
hypertext_type = preferences
hypertext_preferences_page = 2
[hint:Adaptive infills]
text = Adaptive infills\nDid you know that you can use the Adaptive cubic and Support cubic infills to decrease the print time and lower the filament consumption? Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/infill-patterns_177130
[hint:Fullscreen mode]
text = Fullscreen mode\nDid you know that you can switch PrusaSlicer to fullscreen mode? Use the <b>F11</b> hotkey.
[hint:Simplify mesh]
text = Simplify mesh\nDid you know that you can reduce the number of triangles in a mesh using the Simplify mesh feature? Right-click the model and select Simplify model. Read more in the<a>documentation.</a>
hypertext_type = link
hypertext_link = https://help.prusa3d.com/en/article/simplify-mesh_238941
#[hint:]
#text =
#hypertext =
#follow_text =

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="notification_preferences.svg"
xml:space="preserve"
style="enable-background:new 0 0 100 100;"
viewBox="0 0 100 100"
y="0px"
x="0px"
id="minimalize_window"
version="1.1"><metadata
id="metadata17"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs15" /><sodipodi:namedview
inkscape:current-layer="minimalize_window"
inkscape:window-maximized="1"
inkscape:window-y="-8"
inkscape:window-x="-8"
inkscape:cy="50"
inkscape:cx="50"
inkscape:zoom="10.08"
showgrid="false"
id="namedview13"
inkscape:window-height="1377"
inkscape:window-width="2560"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<style
id="style2"
type="text/css">
.st0{fill:#ED6B21;}
</style>
<g
id="g6">
<path
id="path4"
d="M80,92.8H20c-7.1,0-12.8-5.8-12.8-12.8V20c0-7.1,5.8-12.8,12.8-12.8h60c7.1,0,12.8,5.8,12.8,12.8v60 C92.8,87.1,87.1,92.8,80,92.8z M20,12.8c-4,0-7.2,3.2-7.2,7.2v60c0,3.9,3.2,7.2,7.2,7.2h60c3.9,0,7.2-3.2,7.2-7.2V20 c0-4-3.2-7.2-7.2-7.2H20z"
class="st0" />
</g>
<g
id="g10">
<path
id="path8"
d="M80.5,44l-5.7-0.7c-0.6-2.2-1.4-4.2-2.5-6.2l3.6-4.5c0.5-0.7,0.5-1.8-0.1-2.4l-5.9-5.9 c-0.6-0.6-1.7-0.7-2.4-0.1l-4.5,3.6c-1.9-1.1-4-2-6.1-2.5L56,19.6c-0.1-0.9-0.9-1.6-1.8-1.6h-8.3c-0.9,0-1.7,0.7-1.8,1.6l-0.7,5.7 c-2.2,0.6-4.2,1.4-6.1,2.5l-4.5-3.6c-0.7-0.5-1.8-0.5-2.4,0.1l-5.9,5.9c-0.6,0.6-0.7,1.7-0.1,2.4l3.6,4.5c-1.1,1.9-2,4-2.5,6.1 L19.6,44C18.7,44.1,18,45,18,45.8v8.3c0,0.9,0.7,1.7,1.6,1.8l5.7,0.7c0.6,2.2,1.4,4.2,2.5,6.1l-3.6,4.5c-0.5,0.7-0.5,1.8,0.1,2.4 l5.9,5.9c0.6,0.6,1.7,0.7,2.4,0.1l4.5-3.6c1.9,1.1,4,2,6.1,2.5l0.7,5.7c0.1,0.9,0.9,1.6,1.8,1.6h8.3c0.9,0,1.7-0.7,1.8-1.6l0.7-5.7 c2.2-0.6,4.2-1.4,6.1-2.5l4.5,3.6c0.7,0.5,1.8,0.5,2.4-0.1l5.9-5.9c0.6-0.6,0.7-1.7,0.1-2.4l-3.6-4.5c1.1-1.9,2-4,2.5-6.1l5.7-0.7 c0.9-0.1,1.6-0.9,1.6-1.8v-8.3C82,44.9,81.3,44.1,80.5,44z M50,66.8c-9.3,0-16.8-7.5-16.8-16.8S40.7,33.2,50,33.2 S66.8,40.7,66.8,50S59.3,66.8,50,66.8z"
class="st0" />
</g>
<path
id="path19"
d="M 18.75,92.696085 C 16.846525,92.418222 15.645289,92.057103 14.248486,91.342827 10.768164,89.563113 8.3399658,86.370876 7.4768461,82.440476 7.2982304,81.627112 7.2916667,80.477245 7.2916667,50 c 0,-30.186048 0.00806,-31.633856 0.1805113,-32.417478 C 8.6132236,12.397531 12.392318,8.6115694 17.559524,7.4768461 18.372888,7.2982304 19.522755,7.2916667 50,7.2916667 c 30.186048,0 31.633856,0.00806 32.417478,0.1805113 3.232976,0.7114715 5.949953,2.4425305 7.826838,4.98669 1.078165,1.461476 1.917759,3.360629 2.286745,5.172592 0.168029,0.825133 0.177272,2.515491 0.177272,32.418143 0,30.365281 -0.0069,31.579027 -0.184138,32.385657 -0.592788,2.697863 -1.665191,4.687627 -3.53325,6.555685 -1.820587,1.820588 -3.639881,2.823244 -6.352056,3.500774 l -0.843254,0.210654 -31.39881,0.01496 C 33.12748,92.725556 18.886409,92.716002 18.75,92.696085 Z m 63.033409,-5.68899 c 2.670161,-0.682912 4.81496,-2.945768 5.315692,-5.608285 0.08202,-0.436105 0.104156,-8.923253 0.08281,-31.746032 L 87.152778,18.501984 86.882499,17.708333 C 86.496691,16.575445 85.97299,15.736341 85.118324,14.881675 84.26366,14.02701 83.424556,13.503308 82.291667,13.117501 L 81.498016,12.847222 H 50 18.501984 l -0.793651,0.270279 c -1.132888,0.385807 -1.971992,0.909509 -2.826658,1.764174 -0.854665,0.854666 -1.378367,1.69377 -1.764174,2.826658 l -0.270279,0.793651 -0.02736,31.200397 c -0.0307,35.008562 -0.09842,31.873352 0.723863,33.513124 0.958398,1.911204 2.60508,3.255124 4.642945,3.789286 0.689685,0.180778 1.691694,0.186837 31.772663,0.192128 30.5793,0.0054 31.07235,0.0024 31.82408,-0.189824 z"
style="fill:#ed6b21;stroke-width:0.0992064" /><path
id="path21"
d="m 44.978562,81.556238 c -0.224588,-0.101989 -0.532838,-0.348659 -0.685,-0.548154 -0.25981,-0.340629 -0.296222,-0.518004 -0.597889,-2.912583 -0.176677,-1.402427 -0.35155,-2.806563 -0.388607,-3.120303 -0.04985,-0.42206 -0.107657,-0.570436 -0.222242,-0.570436 -0.426828,0 -3.130028,-1.019464 -4.485271,-1.691541 l -1.535713,-0.761572 -2.217643,1.778586 c -1.219703,0.978222 -2.37837,1.873418 -2.574815,1.989323 -0.425644,0.251135 -1.144099,0.270643 -1.57406,0.04274 -0.427236,-0.226462 -6.56291,-6.418305 -6.684742,-6.745938 -0.156941,-0.422049 -0.124807,-1.076279 0.07174,-1.460661 0.09658,-0.188868 0.985279,-1.352579 1.974895,-2.586024 l 1.799302,-2.242628 -0.575072,-1.130388 c -0.662867,-1.30296 -1.372055,-3.060993 -1.696609,-4.205785 -0.123752,-0.436508 -0.230017,-0.802816 -0.236144,-0.814019 -0.0061,-0.0112 -1.32638,-0.180242 -2.933895,-0.375643 -1.607514,-0.1954 -3.047348,-0.404462 -3.199631,-0.464579 -0.431862,-0.170489 -0.752876,-0.463248 -0.96597,-0.880946 -0.186214,-0.365011 -0.195644,-0.600505 -0.195644,-4.885734 v -4.502237 l 0.230916,-0.437231 c 0.436456,-0.826411 0.686836,-0.90879 4.179995,-1.375297 1.689394,-0.225616 3.075684,-0.419348 3.080644,-0.430516 0.005,-0.01117 0.115383,-0.39977 0.245386,-0.86356 0.343695,-1.226154 0.908071,-2.626283 1.629448,-4.04241 l 0.633472,-1.24356 -1.914391,-2.391737 c -1.866668,-2.332114 -2.229549,-2.912724 -2.092735,-3.348375 0.02325,-0.07405 0.07126,-0.268561 0.10669,-0.432251 0.04712,-0.217734 0.921421,-1.159194 3.257294,-3.507505 1.772449,-1.781888 3.334904,-3.271425 3.512118,-3.348214 0.438165,-0.189863 1.107839,-0.173444 1.519909,0.03726 0.188868,0.09658 1.352579,0.985279 2.586024,1.974895 l 2.242628,1.799302 1.151296,-0.588289 c 1.264016,-0.645888 2.953562,-1.3236 4.184877,-1.678644 0.436508,-0.125864 0.802816,-0.234062 0.814019,-0.240439 0.0112,-0.0064 0.180242,-1.326833 0.375643,-2.934348 0.1954,-1.607514 0.404462,-3.047348 0.464579,-3.199631 0.170489,-0.431862 0.463248,-0.752876 0.880946,-0.96597 0.365084,-0.186251 0.600598,-0.195644 4.905289,-0.195644 4.304692,0 4.540206,0.0094 4.905289,0.195644 0.41844,0.213473 0.711641,0.535411 0.879741,0.96597 0.05945,0.152283 0.313415,1.592373 0.564355,3.200201 0.250941,1.607827 0.465165,2.928375 0.476055,2.93455 0.01089,0.0062 0.332298,0.09235 0.714243,0.191496 1.067209,0.277031 2.798352,0.970587 4.182307,1.675576 l 1.252472,0.638011 2.391738,-1.914391 c 2.611882,-2.090599 2.873711,-2.23593 3.656618,-2.029642 0.366653,0.09661 0.840141,0.527191 3.631513,3.302435 1.783364,1.77306 3.271361,3.333213 3.348214,3.510574 0.189862,0.438165 0.173443,1.107839 -0.03727,1.519909 -0.09658,0.188868 -0.983684,1.350589 -1.971348,2.581602 l -1.795755,2.238205 0.534553,1.085208 c 0.645239,1.309911 1.426175,3.276043 1.731373,4.359017 0.123015,0.436508 0.227955,0.802093 0.233198,0.812412 0.0052,0.01032 1.359355,0.185141 3.009137,0.388494 3.155152,0.388906 3.405425,0.454071 3.747182,0.975657 0.14834,0.226397 0.163254,0.723673 0.149347,4.979853 -0.01647,5.040469 -0.0249,5.133596 -0.511957,5.652039 -0.380147,0.404648 -0.910219,0.526693 -3.819033,0.879306 -1.587713,0.192465 -2.915838,0.349937 -2.951389,0.349937 -0.03555,0 -0.06464,0.0729 -0.06464,0.162006 0,0.432927 -1.014133,3.126418 -1.691162,4.491646 l -0.761194,1.534947 1.91048,2.386851 c 1.862745,2.327215 2.225586,2.907999 2.088823,3.34349 -0.02325,0.07405 -0.07126,0.26856 -0.106691,0.432251 -0.04712,0.217734 -0.92142,1.159193 -3.257293,3.507504 -1.77245,1.781887 -3.334904,3.271425 -3.512118,3.348215 -0.438165,0.189862 -1.107839,0.173443 -1.519909,-0.03727 -0.188868,-0.09658 -1.352579,-0.98528 -2.586025,-1.974896 l -2.242628,-1.799302 -1.130388,0.575073 c -1.302959,0.662866 -3.060993,1.372054 -4.205784,1.696608 -0.436508,0.123752 -0.802817,0.230017 -0.814019,0.236145 -0.0112,0.0061 -0.179836,1.32638 -0.374739,2.933894 -0.357089,2.945162 -0.478368,3.474208 -0.883739,3.855033 -0.528135,0.496158 -0.637275,0.506365 -5.389595,0.504034 -4.124538,-0.002 -4.471911,-0.01546 -4.851013,-0.187615 z m 6.62303,-14.79524 c 2.138902,-0.216686 3.933005,-0.72075 5.797738,-1.62891 7.586919,-3.694968 11.2377,-12.430258 8.574373,-20.516058 -0.413275,-1.254694 -1.457004,-3.302898 -2.260641,-4.436267 -0.85516,-1.206028 -2.686797,-3.037665 -3.892825,-3.892825 -1.133369,-0.803637 -3.181573,-1.847366 -4.436267,-2.260641 -4.232216,-1.394021 -8.811951,-1.092505 -12.7833,0.841615 -7.586197,3.694616 -11.246703,12.45544 -8.572156,20.516058 1.286909,3.878519 4.151034,7.334154 7.715295,9.308687 2.191048,1.213798 4.039987,1.769517 7.016112,2.108768 0.65982,0.07521 1.870159,0.058 2.841671,-0.04043 z"
style="fill:#ed6b21;stroke-width:0.0992064" /></svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="minimalize_window"
x="0px"
y="0px"
viewBox="0 0 100 100"
style="enable-background:new 0 0 100 100;"
xml:space="preserve"
sodipodi:docname="notification_preferences_hover.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"><metadata
id="metadata17"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs15" /><sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1377"
id="namedview13"
showgrid="false"
inkscape:zoom="10.08"
inkscape:cx="50"
inkscape:cy="50"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="minimalize_window" />
<style
type="text/css"
id="style2">
.st0{fill:#ED6B21;}
</style>
<g
transform="matrix(1.15,0,0,1.15,-7.5,-7.5)"
id="g6">
<path
class="st0"
d="M 80,92.8 H 20 C 12.9,92.8 7.2,87 7.2,80 V 20 C 7.2,12.9 13,7.2 20,7.2 h 60 c 7.1,0 12.8,5.8 12.8,12.8 v 60 c 0,7.1 -5.7,12.8 -12.8,12.8 z m -60,-80 c -4,0 -7.2,3.2 -7.2,7.2 v 60 c 0,3.9 3.2,7.2 7.2,7.2 h 60 c 3.9,0 7.2,-3.2 7.2,-7.2 V 20 C 87.2,16 84,12.8 80,12.8 Z"
id="path4" />
</g>
<g
transform="matrix(1.15,0,0,1.15,-7.5,-7.5)"
id="g10">
<path
class="st0"
d="m 80.5,44 -5.7,-0.7 c -0.6,-2.2 -1.4,-4.2 -2.5,-6.2 l 3.6,-4.5 c 0.5,-0.7 0.5,-1.8 -0.1,-2.4 L 69.9,24.3 C 69.3,23.7 68.2,23.6 67.5,24.2 L 63,27.8 c -1.9,-1.1 -4,-2 -6.1,-2.5 L 56,19.6 C 55.9,18.7 55.1,18 54.2,18 h -8.3 c -0.9,0 -1.7,0.7 -1.8,1.6 l -0.7,5.7 c -2.2,0.6 -4.2,1.4 -6.1,2.5 L 32.8,24.2 C 32.1,23.7 31,23.7 30.4,24.3 l -5.9,5.9 c -0.6,0.6 -0.7,1.7 -0.1,2.4 l 3.6,4.5 c -1.1,1.9 -2,4 -2.5,6.1 L 19.6,44 C 18.7,44.1 18,45 18,45.8 v 8.3 c 0,0.9 0.7,1.7 1.6,1.8 l 5.7,0.7 c 0.6,2.2 1.4,4.2 2.5,6.1 l -3.6,4.5 c -0.5,0.7 -0.5,1.8 0.1,2.4 l 5.9,5.9 c 0.6,0.6 1.7,0.7 2.4,0.1 L 37.1,72 c 1.9,1.1 4,2 6.1,2.5 l 0.7,5.7 c 0.1,0.9 0.9,1.6 1.8,1.6 H 54 c 0.9,0 1.7,-0.7 1.8,-1.6 l 0.7,-5.7 c 2.2,-0.6 4.2,-1.4 6.1,-2.5 l 4.5,3.6 c 0.7,0.5 1.8,0.5 2.4,-0.1 l 5.9,-5.9 C 76,69 76.1,67.9 75.5,67.2 l -3.6,-4.5 c 1.1,-1.9 2,-4 2.5,-6.1 l 5.7,-0.7 C 81,55.8 81.7,55 81.7,54.1 V 45.8 C 82,44.9 81.3,44.1 80.5,44 Z M 50,66.8 c -9.3,0 -16.8,-7.5 -16.8,-16.8 0,-9.3 7.5,-16.8 16.8,-16.8 9.3,0 16.8,7.5 16.8,16.8 0,9.3 -7.5,16.8 -16.8,16.8 z"
id="path8" />
</g>
<path
style="fill:#ed6b21;stroke-width:0.114087"
d="M 14.0625,99.100498 C 11.873504,98.780955 10.492082,98.365668 8.8857589,97.544251 4.8833886,95.49758 2.0909607,91.826507 1.098373,87.306547 0.89296496,86.371179 0.88541671,85.048832 0.88541671,50 c 0,-34.713955 0.009269,-36.378934 0.20758799,-37.2801 C 2.4052071,6.7571607 6.7511657,2.4033048 12.693453,1.098373 13.628821,0.89296496 14.951168,0.88541671 50,0.88541671 c 34.713955,0 36.378934,0.009269 37.2801,0.20758799 3.717922,0.8181922 6.842446,2.8089101 9.000863,5.7346935 1.23989,1.6806974 2.205423,3.8647238 2.629757,5.9484808 0.193234,0.948903 0.203863,2.892815 0.203863,37.280864 0,34.920074 -0.0079,36.315882 -0.211759,37.243506 -0.681706,3.102542 -1.914969,5.390771 -4.063237,7.539038 -2.093675,2.093676 -4.185863,3.24673 -7.304865,4.02589 l -0.969742,0.242252 -36.108631,0.0172 c -19.859747,0.0095 -36.236979,-0.0015 -36.393849,-0.02443 z m 72.48842,-6.542339 c 3.070686,-0.785349 5.537204,-3.387633 6.113046,-6.449527 0.09432,-0.501521 0.11978,-10.261741 0.09523,-36.507937 l -0.0335,-35.823413 -0.310821,-0.912699 C 91.971195,11.561762 91.368939,10.596792 90.386073,9.6139263 89.403209,8.6310615 88.438239,8.0288042 87.135417,7.5851262 L 86.222718,7.2743053 H 50 13.777282 L 12.864583,7.5851262 C 11.561762,8.0288042 10.596792,8.6310615 9.6139263,9.6139263 8.6310615,10.596792 8.0288042,11.561762 7.5851262,12.864583 l -0.3108209,0.912699 -0.031464,35.880456 c -0.035305,40.259846 -0.113183,36.654355 0.8324425,38.540093 1.1021577,2.197884 2.9958422,3.743392 5.3393872,4.357679 0.793137,0.207894 1.945448,0.214862 36.538562,0.220947 35.166195,0.0062 35.733202,0.0028 36.597692,-0.218298 z"
id="path19" /><path
style="fill:#ed6b21;stroke-width:0.114087"
d="m 44.225346,86.289674 c -0.258276,-0.117288 -0.612763,-0.400958 -0.78775,-0.630377 -0.298781,-0.391724 -0.340655,-0.595705 -0.687572,-3.349471 -0.203179,-1.612791 -0.404283,-3.227547 -0.446898,-3.588348 -0.05733,-0.485369 -0.123806,-0.656002 -0.255578,-0.656002 -0.490853,0 -3.599533,-1.172383 -5.158062,-1.945272 l -1.76607,-0.875808 -2.550289,2.045374 c -1.402659,1.124956 -2.735126,2.154431 -2.961038,2.287722 -0.48949,0.288805 -1.315714,0.311239 -1.810169,0.04915 -0.491321,-0.260432 -7.547346,-7.381051 -7.687453,-7.757829 -0.180482,-0.485356 -0.143528,-1.237721 0.0825,-1.67976 0.111067,-0.217198 1.133071,-1.555466 2.271129,-2.973928 l 2.069198,-2.579022 -0.661333,-1.299946 c -0.762297,-1.498404 -1.577863,-3.520142 -1.951101,-4.836653 -0.142314,-0.501984 -0.264519,-0.923238 -0.271565,-0.936122 -0.007,-0.01288 -1.525337,-0.207278 -3.373979,-0.431989 -1.848642,-0.22471 -3.504451,-0.465131 -3.679576,-0.534266 -0.496641,-0.196062 -0.865807,-0.532735 -1.110866,-1.013088 -0.214146,-0.419763 -0.22499,-0.690581 -0.22499,-5.618594 v -5.177573 l 0.265553,-0.502815 c 0.501925,-0.950373 0.789862,-1.045109 4.806994,-1.581592 1.942804,-0.259458 3.537037,-0.48225 3.542741,-0.495093 0.0057,-0.01285 0.132691,-0.459736 0.282194,-0.993094 0.395249,-1.410077 1.044282,-3.020226 1.873865,-4.648772 l 0.728493,-1.430094 -2.20155,-2.750497 c -2.146668,-2.681931 -2.563981,-3.349633 -2.406645,-3.850631 0.02674,-0.08516 0.08195,-0.308846 0.122694,-0.497089 0.05419,-0.250394 1.059634,-1.333073 3.745888,-4.033631 2.038316,-2.049171 3.835139,-3.762139 4.038935,-3.850446 0.50389,-0.218342 1.274015,-0.199461 1.747896,0.04285 0.217198,0.111067 1.555466,1.133071 2.973927,2.271129 l 2.579023,2.069198 1.32399,-0.676533 c 1.453618,-0.742771 3.396596,-1.52214 4.812608,-1.93044 0.501985,-0.144744 0.923239,-0.269172 0.936122,-0.276505 0.01288,-0.0074 0.207279,-1.525858 0.43199,-3.3745 0.22471,-1.848642 0.465131,-3.504451 0.534266,-3.679576 0.196062,-0.496641 0.532735,-0.865807 1.013088,-1.110866 0.419846,-0.214188 0.690687,-0.22499 5.641082,-0.22499 4.950396,0 5.221237,0.01081 5.641082,0.22499 0.481206,0.245494 0.818387,0.615723 1.011702,1.110866 0.06837,0.175125 0.360428,1.831229 0.649009,3.680231 0.288582,1.849001 0.534939,3.367631 0.547463,3.374733 0.01252,0.0071 0.382143,0.106202 0.821379,0.22022 1.227291,0.318586 3.218105,1.116175 4.809653,1.926912 L 64.97767,24.53555 67.728169,22.334 c 3.003664,-2.404188 3.304768,-2.571319 4.205111,-2.334088 0.421651,0.111102 0.966162,0.60627 4.17624,3.7978 2.050868,2.039019 3.762065,3.833195 3.850446,4.03716 0.218341,0.50389 0.199459,1.274015 -0.04286,1.747896 -0.111067,0.217198 -1.131236,1.553177 -2.26705,2.968842 l -2.065118,2.573936 0.614736,1.247989 c 0.742024,1.506398 1.640101,3.767449 1.991079,5.01287 0.141467,0.501984 0.262148,0.922407 0.268177,0.934273 0.006,0.01187 1.563259,0.212913 3.460508,0.446768 3.628425,0.447242 3.916239,0.522182 4.309259,1.122006 0.170591,0.260357 0.187742,0.832224 0.171749,5.726831 -0.01894,5.796539 -0.02864,5.903635 -0.58875,6.499845 -0.437169,0.465345 -1.046752,0.605697 -4.391888,1.011202 -1.82587,0.221334 -3.353214,0.402427 -3.394098,0.402427 -0.04088,0 -0.07434,0.08384 -0.07434,0.186307 0,0.497866 -1.166253,3.595381 -1.944836,5.165393 l -0.875373,1.765189 2.197052,2.744879 c 2.142157,2.676297 2.559424,3.344199 2.402146,3.845013 -0.02674,0.08516 -0.08195,0.308844 -0.122694,0.497089 -0.05419,0.250394 -1.059633,1.333072 -3.745887,4.03363 -2.038318,2.04917 -3.83514,3.762138 -4.038936,3.850447 -0.50389,0.218341 -1.274015,0.199459 -1.747895,-0.04286 -0.217198,-0.111067 -1.555466,-1.133072 -2.973929,-2.27113 l -2.579022,-2.069197 -1.299946,0.661334 c -1.498403,0.762295 -3.520142,1.577862 -4.836652,1.951099 -0.501984,0.142315 -0.92324,0.264519 -0.936122,0.271566 -0.01288,0.007 -0.206811,1.525337 -0.43095,3.373979 -0.410652,3.386936 -0.550123,3.995339 -1.0163,4.433288 -0.607355,0.570581 -0.732866,0.582319 -6.198034,0.579639 -4.743219,-0.0023 -5.142697,-0.01778 -5.578665,-0.215758 z m 7.616485,-17.014526 c 2.459737,-0.249189 4.522956,-0.828863 6.667399,-1.873247 8.724956,-4.249213 12.923355,-14.294796 9.860528,-23.593466 -0.475266,-1.442899 -1.675554,-3.798333 -2.599737,-5.101708 -0.983434,-1.386932 -3.089816,-3.493314 -4.476748,-4.476748 -1.303375,-0.924183 -3.658809,-2.124471 -5.101707,-2.599737 -4.867049,-1.603125 -10.133744,-1.256381 -14.700795,0.967857 -8.724127,4.248808 -12.933709,14.323756 -9.85798,23.593467 1.479945,4.460296 4.773689,8.434277 8.872589,10.70499 2.519706,1.395867 4.645985,2.034944 8.068529,2.425083 0.758793,0.08649 2.150683,0.0667 3.267922,-0.0465 z"
id="path21" /></svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 800 800"
style="enable-background:new 0 0 800 800;"
xml:space="preserve"
sodipodi:docname="notification_right.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"><metadata
id="metadata15"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs13" /><sodipodi:namedview
inkscape:document-rotation="0"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2066"
id="namedview11"
showgrid="false"
inkscape:zoom="2.52"
inkscape:cx="227.47556"
inkscape:cy="335.392"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<style
type="text/css"
id="style2">
.st0{fill:#ED6B21;}
</style>
<path
style="stroke-width:0.85"
class="st0"
d="m 501.14231,400.1595 -155.29499,116.96 v -233.75 l 155.29499,116.79 m 66.63999,0 c 0,-6.12 -2.72,-12.155 -8.15999,-16.235 L 330.12233,211.2895 c -13.43,-10.115 -32.555,-0.51 -32.555,16.235 v 345.355 c 0,16.745 19.125,26.35 32.555,16.235 l 229.49998,-172.805 c 5.44,-3.995 8.16,-10.03 8.15999,-16.15 z"
id="path6" />
<g
id="g4"
transform="matrix(0.9775,0,0,0.9775,53.547005,53.547755)">
<path
id="path2"
class="st0"
d="M 597.2,701.3 H 110.6 C 53.2,701.3 6.5,654.6 6.5,597.2 V 110.6 C 6.5,53.2 53.2,6.5 110.6,6.5 h 486.6 c 57.4,0 104.1,46.7 104.1,104.1 v 486.6 c 0,57.4 -46.7,104.1 -104.1,104.1 z M 110.6,52.4 c -32,0 -58.2,26 -58.2,58.2 v 486.6 c 0,32 26,58.2 58.2,58.2 h 486.6 c 32,0 58.2,-26 58.2,-58.2 V 110.6 c 0,-32 -26,-58.2 -58.2,-58.2 z" />
</g>
<path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.674602"
d="m 150.65676,738.12999 c -12.4717,-1.39663 -26.66772,-5.94191 -37.84321,-12.11671 -17.754565,-9.80992 -33.768845,-26.68981 -42.418125,-44.71089 -5.98506,-12.4701 -8.76024,-23.35456 -9.82192,-38.5225 -0.48062,-6.8663 -0.64046,-87.42616 -0.4973,-250.61508 0.1956,-222.88026 0.29494,-240.94222 1.35676,-246.58758 4.2349,-22.51562 13.68014,-40.62012 29.20092,-55.971935 14.237945,-14.08294 31.958665,-23.42796 52.602245,-27.7398 5.87892,-1.22794 14.00696,-1.26814 256.3492,-1.26814 h 250.27778 l 7.08334,1.5615 c 21.30688,4.69708 36.90336,13.21608 51.96052,28.3815 14.67866,14.784215 23.1932,30.350375 27.76124,50.752695 l 1.56792,7.0027 v 250.9524 c 0,242.72256 -0.0418,251.15148 -1.26428,257.0238 -9.30592,44.69035 -45.18963,77.43352 -89.75567,81.90028 -9.17897,0.92003 -488.33076,0.87926 -496.55942,-0.0426 z m 502.21598,-45.64 c 19.93824,-6.17834 34.6922,-21.42494 40.00112,-41.33676 l 1.51306,-5.67491 V 399.58544 153.69258 l -1.52572,-5.7341 c -5.66288,-21.28292 -21.4158,-36.89778 -42.2051,-41.83524 -5.63964,-1.3394 -7.66026,-1.3488 -253.17948,-1.17612 l -247.49446,0.174 -4.72222,1.5953 c -18.05932,6.10094 -31.7315,19.23924 -37.4918,36.02779 -1.04762,3.05335 -2.22128,7.52472 -2.60814,9.93642 -0.47858,2.98361 -0.705,81.91877 -0.70846,246.99891 -0.004,218.14116 0.1022,243.18289 1.05916,248.25395 4.27172,22.63803 22.24346,40.86392 44.80876,45.44251 3.58848,0.7281 49.16894,0.8701 250.95238,0.7817 l 246.56746,-0.108 z"
id="path17" /><path
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.674602"
d="m 300.17824,218.44362 c 2.06443,-4.13128 4.83026,-6.86894 9.40917,-9.3133 3.43647,-1.83451 12.82007,-1.79344 16.52778,0.0724 3.22403,1.6224 232.7236,174.17374 235.79013,177.281 3.35767,3.4022 4.88323,7.0012 5.23218,12.34324 0.27168,4.159 0.0718,5.32914 -1.5138,8.86232 -1.00471,2.23886 -2.78731,4.97342 -3.96129,6.07682 -4.28583,4.02812 -232.27571,175.25818 -235.54572,176.9048 -4.6586,2.34584 -12.1025,2.3876 -16.52928,0.0928 -3.87486,-2.00878 -7.80538,-5.7435 -9.67029,-9.18862 l -1.46069,-2.69842 -0.1736,-178.1462 -0.1736,-178.14618 z m 45.66908,298.67588 c 1.00351,-0.0612 154.99009,-116.48774 154.99009,-117.18534 0,-0.71184 -154.02593,-116.84804 -154.99009,-116.86318 -0.27827,-0.004 -0.50595,52.66168 -0.50595,117.03568 0,64.37402 0.22768,117.0298 0.50595,117.01284 z"
id="path19" /></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="notification_right_hover.svg"
xml:space="preserve"
style="enable-background:new 0 0 800 800;"
viewBox="0 0 800 800"
y="0px"
x="0px"
id="Layer_1"
version="1.1"><metadata
id="metadata15"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs13" /><sodipodi:namedview
inkscape:current-layer="Layer_1"
inkscape:window-maximized="1"
inkscape:window-y="-11"
inkscape:window-x="-11"
inkscape:cy="396.42857"
inkscape:cx="400"
inkscape:zoom="1.26"
showgrid="false"
id="namedview11"
inkscape:window-height="2066"
inkscape:window-width="3840"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff"
inkscape:document-rotation="0" />
<style
id="style2"
type="text/css">
.st0{fill:#ED6B21;}
</style>
<path
id="path6"
d="m 460.47909,399.8897 -93.177,70.176 v -140.25 l 93.177,70.074 m 39.984,0 c 0,-3.672 -1.632,-7.293 -4.896,-9.741 l -137.7,-103.581 c -8.058,-6.069 -19.533,-0.306 -19.533,9.741 v 207.213 c 0,10.047 11.475,15.81 19.533,9.741 l 137.7,-103.683 c 3.264,-2.397 4.896,-6.018 4.896,-9.69 z"
class="st0"
style="stroke-width:0.51" />
<g
transform="matrix(0.5865,0,0,0.5865,191.9219,191.92265)"
id="g4">
<path
d="M 597.2,701.3 H 110.6 C 53.2,701.3 6.5,654.6 6.5,597.2 V 110.6 C 6.5,53.2 53.2,6.5 110.6,6.5 h 486.6 c 57.4,0 104.1,46.7 104.1,104.1 v 486.6 c 0,57.4 -46.7,104.1 -104.1,104.1 z M 110.6,52.4 c -32,0 -58.2,26 -58.2,58.2 v 486.6 c 0,32 26,58.2 58.2,58.2 h 486.6 c 32,0 58.2,-26 58.2,-58.2 V 110.6 c 0,-32 -26,-58.2 -58.2,-58.2 z"
class="st0"
id="path2" />
</g>
<path
id="path17"
d="m 250.18776,602.67199 c -7.48302,-0.83798 -16.00064,-3.56515 -22.70593,-7.27002 -10.65273,-5.88596 -20.26131,-16.01389 -25.45087,-26.82654 -3.59104,-7.48206 -5.25614,-14.01273 -5.89316,-23.11349 -0.28836,-4.11978 -0.38427,-52.4557 -0.29837,-150.36905 0.11733,-133.72816 0.17696,-144.56534 0.81405,-147.95255 2.54094,-13.50937 8.20808,-24.37207 17.52056,-33.58317 8.54276,-8.44975 19.17518,-14.05676 31.56134,-16.64387 3.52735,-0.73676 8.40418,-0.76089 153.80952,-0.76089 h 150.16667 l 4.25,0.93691 c 12.78413,2.81824 22.14202,7.92964 31.17631,17.0289 8.80719,8.87052 13.91592,18.21022 16.65675,30.45161 l 0.94075,4.20163 v 150.57143 c 0,145.63353 -0.0251,150.69089 -0.75857,154.21428 -5.58355,26.8142 -27.11378,46.46011 -53.85339,49.14017 -5.50739,0.55201 -292.99846,0.52756 -297.93567,-0.0255 z M 551.51735,575.288 c 11.96295,-3.707 20.81532,-12.85496 24.00067,-24.80205 l 0.90783,-3.40497 V 399.54526 252.00955 l -0.91542,-3.44047 c -3.39773,-12.76975 -12.84948,-22.13867 -25.32306,-25.10114 -3.38379,-0.80364 -4.59616,-0.80928 -151.90769,-0.70567 l -148.49668,0.10443 -2.83334,0.95718 c -10.83559,3.66055 -19.0389,11.54353 -22.49508,21.61668 -0.62857,1.83199 -1.33276,4.51483 -1.56487,5.96185 -0.28716,1.79016 -0.423,49.15126 -0.42509,148.19933 -0.003,130.8847 0.0614,145.90974 0.6355,148.95238 2.56303,13.58281 13.34608,24.51835 26.88526,27.2655 2.15309,0.43687 29.50136,0.52206 150.57143,0.46903 l 147.94048,-0.0648 z"
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.404762" /><path
id="path19"
d="m 339.90065,290.86016 c 1.23866,-2.47877 2.89816,-4.12137 5.64549,-5.58799 2.06189,-1.1007 7.69205,-1.07605 9.91667,0.0434 1.93443,0.97344 139.63418,104.50426 141.47409,106.36861 2.01459,2.04133 2.92994,4.20072 3.13931,7.40596 0.16301,2.49539 0.0431,3.19748 -0.90827,5.31738 -0.60285,1.34333 -1.67241,2.98406 -2.37679,3.6461 -2.5715,2.41688 -139.36543,105.1549 -141.32744,106.14288 -2.79516,1.4075 -7.2615,1.43255 -9.91757,0.0556 -2.32491,-1.20527 -4.68322,-3.44611 -5.80216,-5.51318 l -0.87642,-1.61905 -0.10417,-106.88772 -0.10417,-106.88771 z m 27.40144,179.20554 c 0.6021,-0.0367 92.99405,-69.89265 92.99405,-70.31121 0,-0.4271 -92.41555,-70.10883 -92.99405,-70.11792 -0.16696,-0.002 -0.30357,31.59702 -0.30357,70.22143 0,38.6244 0.13661,70.21787 0.30357,70.2077 z"
style="fill:#ed6b21;fill-opacity:1;stroke-width:0.404762" /></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="toolbar_arrow1.svg"
id="svg10"
version="1.1"
viewBox="0 0 119.8 298.8"
height="298.8"
width="119.8">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs14" />
<sodipodi:namedview
inkscape:current-layer="svg10"
inkscape:window-maximized="0"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:cy="149.39999"
inkscape:cx="59.900002"
inkscape:zoom="3.3734941"
showgrid="false"
id="namedview12"
inkscape:window-height="1299"
inkscape:window-width="2295"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<line
id="line2"
style="fill: none;stroke: #ed6b21;stroke-linecap: round;stroke-miterlimit: 10;stroke-width: 17.007874015748033px"
y2="99.8"
x2="59.2"
y1="290.3"
x1="59.2" />
<line
id="line4"
style="fill: none;stroke: #ed6b21;stroke-linecap: round;stroke-miterlimit: 10;stroke-width: 17.007874015748033px"
y2="8.5"
x2="59.2"
y1="96.6"
x1="8.5" />
<line
id="line6"
style="fill: none;stroke: #ed6b21;stroke-linecap: round;stroke-miterlimit: 10;stroke-width: 17.007874015748033px"
y2="8.5"
x2="59.2"
y1="96.6"
x1="111.2" />
<line
id="line8"
style="fill: none;stroke: #ed6b21;stroke-linecap: round;stroke-miterlimit: 10;stroke-width: 17.007874015748033px"
y2="96.6"
x2="111.2"
y1="96.6"
x1="8.5" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.4.0-alpha0
1.4.0-alpha5 Added multiple add:north and Extrudr filament profiles. Updated support head settings (SL1S).
1.4.0-alpha4 Decreased Area Fill (SL1S).
1.4.0-alpha3 Updated SL1S tilt times.
1.4.0-alpha2 Updated Prusa MINI machine limits.
@ -8,8 +9,10 @@ min_slic3r_version = 2.4.0-alpha0
1.3.0-alpha1 Added Prusament PCCF. Increased travel acceleration for Prusa MINI. Updated start g-code for Prusa MINI. Added multiple add:north and Extrudr filament profiles. Updated Z travel speed values.
1.3.0-alpha0 Disabled thick bridges, updated support settings.
min_slic3r_version = 2.3.2-alpha0
1.3.1 Added multiple add:north and Extrudr filament profiles. Updated support head settings (SL1S).
1.3.0 Added SL1S profiles.
min_slic3r_version = 2.3.0-rc1
1.2.8 Added multiple add:north and Extrudr filament profiles.
1.2.7 Updated "Prusament PC Blend Carbon Fiber" profile for Prusa MINI.
1.2.6 Added filament profile for "Prusament PC Blend Carbon Fiber".
1.2.5 Updated firmware version. Added filament profiles. Various improvements.

View File

@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 1.4.0-alpha4
config_version = 1.4.0-alpha5
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -2025,7 +2025,7 @@ first_layer_temperature = 220
temperature = 220
filament_max_volumetric_speed = 10
compatible_printers_condition = ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
filament_spool_weight = 0
filament_spool_weight = 230
[filament:Extrudr PETG]
inherits = *PET*
@ -2040,7 +2040,7 @@ temperature = 220
slowdown_below_layer_time = 20
filament_retract_length = nil
filament_retract_lift = nil
filament_spool_weight = 0
filament_spool_weight = 262
full_fan_speed_layer = 0
compatible_printers_condition = printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
@ -2056,6 +2056,7 @@ filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=198"
first_layer_temperature = 235
temperature = 235
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
filament_spool_weight = 230
[filament:Extrudr XPETG CF @MINI]
inherits = Extrudr XPETG CF; *PETMINI*
@ -2086,7 +2087,7 @@ max_fan_speed = 45
min_fan_speed = 25
slowdown_below_layer_time = 20
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.07{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K43{endif} ; Filament gcode LA 1.0"
filament_spool_weight = 0
filament_spool_weight = 230
[filament:Extrudr Flax]
inherits = *PLA*
@ -2100,19 +2101,19 @@ max_fan_speed = 80
min_fan_speed = 30
full_fan_speed_layer = 0
slowdown_below_layer_time = 20
filament_max_volumetric_speed = 10
filament_spool_weight = 0
filament_max_volumetric_speed = 11
filament_spool_weight = 262
[filament:Extrudr GreenTEC]
inherits = *PLA*
filament_vendor = Extrudr
filament_cost = 23.63
filament_density = 1.35
filament_cost = 56
filament_density = 1.3
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=106"
first_layer_temperature = 208
temperature = 208
slowdown_below_layer_time = 20
filament_spool_weight = 0
filament_spool_weight = 230
[filament:Extrudr GreenTEC Pro]
inherits = *PLA*
@ -2125,7 +2126,7 @@ max_fan_speed = 80
min_fan_speed = 30
full_fan_speed_layer = 0
slowdown_below_layer_time = 20
filament_spool_weight = 0
filament_spool_weight = 230
[filament:Extrudr GreenTEC Pro Carbon]
inherits = *PLA*
@ -2139,7 +2140,7 @@ min_fan_speed = 30
temperature = 225
full_fan_speed_layer = 0
slowdown_below_layer_time = 20
filament_spool_weight = 0
filament_spool_weight = 230
compatible_printers_condition = nozzle_diameter[0]>=0.4 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Extrudr PLA NX1]
@ -2156,7 +2157,7 @@ full_fan_speed_layer = 0
max_fan_speed = 90
min_fan_speed = 30
slowdown_below_layer_time = 20
filament_spool_weight = 0
filament_spool_weight = 262
[filament:Extrudr PLA NX2]
inherits = Extrudr PLA NX1
@ -2176,7 +2177,7 @@ filament_max_volumetric_speed = 3
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=115"
filament_retract_length = 0.4
filament_wipe = nil
filament_spool_weight = 0
filament_spool_weight = 230
slowdown_below_layer_time = 20
[filament:Extrudr Flex Medium]
@ -2191,7 +2192,7 @@ filament_max_volumetric_speed = 2
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=115"
filament_retract_length = 0.4
filament_wipe = nil
filament_spool_weight = 0
filament_spool_weight = 230
slowdown_below_layer_time = 20
[filament:Extrudr Flex SemiSoft]
@ -2206,7 +2207,7 @@ filament_max_volumetric_speed = 1.2
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=115"
filament_retract_length = 0.4
filament_wipe = nil
filament_spool_weight = 0
filament_spool_weight = 230
slowdown_below_layer_time = 20
[filament:addnorth Adamant S1]
@ -2221,6 +2222,7 @@ bed_temperature = 50
first_layer_temperature = 245
first_layer_bed_temperature = 50
slowdown_below_layer_time = 20
min_print_speed = 20
fan_below_layer_time = 15
fan_always_on = 1
cooling = 1
@ -2233,6 +2235,7 @@ filament_retract_length = 0.6
filament_retract_lift = 0.5
filament_spool_weight = 0
filament_retract_restart_extra = 0.1
filament_wipe = nil
[filament:addnorth Adura X]
inherits = *PET*
@ -2257,14 +2260,23 @@ full_fan_speed_layer = 0
filament_retract_length = 1.4
filament_retract_lift = 0.4
filament_max_volumetric_speed = 4
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0"
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.08{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0"
filament_spool_weight = 0
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
## [filament:addnorth Adura X @MINI]
## inherits = addnorth Adura X
## filament_retract_length = nil
## filament_retract_lift = nil
## compatible_printers_condition = printer_model=="MINI"
[filament:addnorth Adura X @MINI]
inherits = addnorth Adura X
filament_retract_length = nil
filament_retract_lift = nil
filament_retract_speed = 40
filament_deretract_speed = 25
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI"
[filament:addnorth Adura X @MMU1]
inherits = addnorth Adura X
filament_retract_length = nil
filament_retract_lift = nil
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MK2SMM"
[filament:addnorth E-PLA]
inherits = *PLA*
@ -2304,13 +2316,21 @@ filament_retract_lift = 0
filament_max_volumetric_speed = 2
filament_spool_weight = 0
## [filament:addnorth ESD-PETG @MINI]
## inherits = addnorth ESD-PETG
## filament_retract_length = nil
## filament_max_volumetric_speed = 2
## compatible_printers_condition = printer_model=="MINI"
[filament:addnorth ESD-PETG @MINI]
inherits = addnorth ESD-PETG
filament_retract_length = nil
filament_retract_speed = 40
filament_deretract_speed = 25
filament_max_volumetric_speed = 2
compatible_printers_condition = printer_model=="MINI"
[filament:addnorth OBC]
[filament:addnorth ESD-PETG @MMU1]
inherits = addnorth ESD-PETG
filament_retract_length = nil
filament_max_volumetric_speed = 2
compatible_printers_condition = printer_model=="MK2SMM"
[filament:addnorth OBC Polyethylene]
inherits = *FLEX*
filament_vendor = addnorth
disable_fan_first_layers = 3
@ -2363,9 +2383,18 @@ filament_spool_weight = 0
inherits = addnorth PETG
filament_retract_length = nil
filament_retract_lift = nil
filament_retract_speed = 40
filament_deretract_speed = 25
filament_max_volumetric_speed = 7
compatible_printers_condition = printer_model=="MINI"
[filament:addnorth PETG @MMU1]
inherits = addnorth PETG
filament_retract_length = nil
filament_retract_lift = nil
filament_max_volumetric_speed = 7
compatible_printers_condition = printer_model=="MK2SMM"
[filament:addnorth Rigid X]
inherits = *PET*
filament_vendor = addnorth
@ -2389,14 +2418,21 @@ filament_retract_length = 1.4
filament_max_volumetric_speed = 5
filament_spool_weight = 0
filament_notes = "Please use a nozzle that is resistant to abrasive filaments, like hardened steel."
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
## [filament:addnorth Rigid X @MINI]
## inherits = addnorth Rigid X
## filament_retract_length = nil
## filament_retract_lift = nil
## filament_max_volumetric_speed = 5
## filament_notes = "Please use a nozzle that is resistant to abrasive filaments, like hardened steel."
## compatible_printers_condition = printer_model=="MINI"
[filament:addnorth Rigid X @MINI]
inherits = addnorth Rigid X
filament_retract_length = nil
filament_retract_lift = nil
filament_retract_speed = 40
filament_deretract_speed = 25
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MINI"
[filament:addnorth Rigid X @MMU1]
inherits = addnorth Rigid X
filament_retract_length = nil
filament_retract_lift = nil
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model=="MK2SMM"
[filament:addnorth Textura]
inherits = *PLA*
@ -2418,10 +2454,15 @@ filament_spool_weight = 0
filament_retract_length = 1
compatible_printers_condition = printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
## [filament:addnorth Textura @MINI]
## inherits = addnorth Textura
## filament_retract_length = nil
## compatible_printers_condition = printer_model=="MINI"
[filament:addnorth Textura @MINI]
inherits = addnorth Textura
filament_retract_length = nil
compatible_printers_condition = printer_model=="MINI"
[filament:addnorth Textura @MMU1]
inherits = addnorth Textura
filament_retract_length = nil
compatible_printers_condition = printer_model=="MK2SMM"
[filament:Filament PM PETG]
inherits = *PET*
@ -2481,16 +2522,43 @@ filament_cost = 33.99
filament_density = 1.20
filament_spool_weight = 230
filament_max_volumetric_speed = 1.2
filament_retract_length = 0
filament_retract_length = 0.4
filament_retract_speed = nil
filament_retract_lift = nil
filament_deretract_speed = 20
fan_always_on = 1
cooling = 0
max_fan_speed = 50
min_fan_speed = 50
max_fan_speed = 60
min_fan_speed = 60
disable_fan_first_layers = 4
full_fan_speed_layer = 6
[filament:AmazonBasics TPU]
inherits = *FLEX*
filament_vendor = AmazonBasics
fan_always_on = 1
filament_max_volumetric_speed = 1.8
extrusion_multiplier = 1.14
first_layer_temperature = 235
first_layer_bed_temperature = 50
temperature = 235
bed_temperature = 50
bridge_fan_speed = 100
max_fan_speed = 80
min_fan_speed = 80
filament_retract_before_travel = 3
filament_cost = 19.99
filament_density = 1.21
filament_retract_length = 2
filament_retract_speed = 45
filament_deretract_speed = 20
filament_retract_lift = 0
filament_wipe = 0
disable_fan_first_layers = 4
full_fan_speed_layer = 6
min_print_speed = 15
slowdown_below_layer_time = 10
cooling = 1
[filament:SainSmart TPU]
inherits = *FLEX*
filament_vendor = SainSmart
@ -3068,12 +3136,19 @@ filament_cost = 35.48
filament_density = 1.24
filament_spool_weight = 230
[filament:SemiFlex or Flexfill 98A]
[filament:SemiFlex]
inherits = *FLEX*
renamed_from = "SemiFlex or Flexfill 98A"
filament_vendor = Generic
filament_cost = 82.26
filament_density = 1.22
extrusion_multiplier = 1.12
filament_max_volumetric_speed = 1.35
fan_always_on = 1
cooling = 0
max_fan_speed = 30
min_fan_speed = 30
filament_retract_length = nil
[filament:Fillamentum Flexfill 98A]
inherits = *FLEX*
@ -3081,13 +3156,16 @@ filament_vendor = Fillamentum
filament_cost = 82.26
filament_density = 1.23
filament_spool_weight = 230
extrusion_multiplier = 1.12
filament_max_volumetric_speed = 1.35
fan_always_on = 1
cooling = 0
max_fan_speed = 50
min_fan_speed = 50
max_fan_speed = 60
min_fan_speed = 60
disable_fan_first_layers = 4
full_fan_speed_layer = 6
filament_retract_length = 1.2
filament_deretract_speed = 20
[filament:Taulman Bridge]
inherits = *common*
@ -3410,16 +3488,22 @@ fan_always_on = 1
max_fan_speed = 15
min_fan_speed = 15
[filament:SemiFlex or Flexfill 98A @MMU1]
[filament:SemiFlex @MMU1]
inherits = *FLEX*
renamed_from = "SemiFlex or Flexfill 98A @MMU1"
filament_vendor = Generic
filament_cost = 82.26
filament_density = 1.22
extrusion_multiplier = 1.12
filament_max_volumetric_speed = 1.35
filament_retract_length = nil
filament_retract_speed = nil
filament_retract_lift = nil
compatible_printers_condition = printer_model=="MK2SMM"
fan_always_on = 1
cooling = 0
max_fan_speed = 30
min_fan_speed = 30
[filament:Generic FLEX @MMU1]
inherits = *FLEX*
@ -3550,16 +3634,18 @@ bed_temperature = 100
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.8
[filament:Fillamentum Flexfill 98A @MINI]
inherits = SemiFlex or Flexfill 98A; *FLEXMINI*
inherits = SemiFlex; *FLEXMINI*
filament_vendor = Fillamentum
first_layer_temperature = 240
temperature = 240
filament_max_volumetric_speed = 1.35
filament_cost = 82.26
filament_spool_weight = 230
max_fan_speed = 60
min_fan_speed = 60
[filament:Generic FLEX @MINI]
inherits = SemiFlex or Flexfill 98A; *FLEXMINI*
inherits = SemiFlex; *FLEXMINI*
filament_vendor = Generic
fan_always_on = 0
bridge_fan_speed = 80
@ -3639,8 +3725,8 @@ filament_cost = 33.95
bridge_fan_speed = 70
fan_always_on = 1
cooling = 0
max_fan_speed = 50
min_fan_speed = 50
max_fan_speed = 60
min_fan_speed = 60
filament_max_volumetric_speed = 1.2
compatible_printers_condition = nozzle_diameter[0]>0.35 and printer_model=="MINI"
disable_fan_first_layers = 4
@ -4080,6 +4166,8 @@ layer_height = 0.05
[sla_print:0.1 Fast @SL1S]
inherits = *SL1S*
layer_height = 0.1
support_head_front_diameter = 0.6
support_head_penetration = 0.6
########### Materials

View File

@ -1,14 +0,0 @@
#version 110
uniform vec4 uniform_color;
uniform bool viewed_from_top;
varying float world_pos_z;
void main()
{
if (viewed_from_top && world_pos_z < 0.0)
discard;
gl_FragColor = uniform_color;
}

View File

@ -1,11 +0,0 @@
#version 110
uniform mat4 world_matrix;
varying float world_pos_z;
void main()
{
world_pos_z = (world_matrix * gl_Vertex).z;
gl_Position = ftransform();
}

View File

@ -57,26 +57,23 @@ if (SLIC3R_GUI)
include(${wxWidgets_USE_FILE})
find_package(JPEG QUIET)
find_package(TIFF QUIET)
string(REGEX MATCH "wxpng" WX_PNG_BUILTIN ${wxWidgets_LIBRARIES})
if (NOT WX_PNG_BUILTIN)
find_package(JPEG QUIET)
if (PNG_FOUND)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX png)
list(APPEND wxWidgets_LIBRARIES ${PNG_LIBRARIES})
endif ()
if (PNG_FOUND AND NOT WX_PNG_BUILTIN)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX png)
list(APPEND wxWidgets_LIBRARIES ${PNG_LIBRARIES})
endif ()
string(REGEX MATCH "wxtiff" WX_TIFF_BUILTIN ${wxWidgets_LIBRARIES})
if (NOT WX_TIFF_BUILTIN)
find_package(TIFF QUIET)
if (TIFF_FOUND)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX tiff)
list(APPEND wxWidgets_LIBRARIES ${TIFF_LIBRARIES})
endif ()
if (TIFF_FOUND AND NOT WX_TIFF_BUILTIN)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX tiff)
list(APPEND wxWidgets_LIBRARIES ${TIFF_LIBRARIES})
endif ()
string(REGEX MATCH "wxjpeg" WX_JPEG_BUILTIN ${wxWidgets_LIBRARIES})
if (TIFF_FOUND AND NOT WX_JPEG_BUILTIN)
if (JPEG_FOUND AND NOT WX_JPEG_BUILTIN)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX jpeg)
list(APPEND wxWidgets_LIBRARIES ${JPEG_LIBRARIES})
endif ()
@ -86,6 +83,7 @@ if (SLIC3R_GUI)
list(FILTER wxWidgets_LIBRARIES EXCLUDE REGEX expat)
list(APPEND wxWidgets_LIBRARIES ${EXPAT_LIBRARIES})
endif ()
# This is an issue in the new wxWidgets cmake build, doesn't deal with librt
find_library(LIBRT rt)
if(LIBRT)

View File

@ -49,7 +49,7 @@
#include "libslic3r/Format/SL1.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Thread.hpp"
#include "libslic3r/LibraryCheck.hpp"
#include "libslic3r/BlacklistedLibraryCheck.hpp"
#include "PrusaSlicer.hpp"
@ -622,13 +622,18 @@ bool CLI::setup(int argc, char **argv)
detect_platform();
#ifdef WIN32
// Notify user if blacklisted library is already loaded (Nahimic)
// If there are cases of no reports with blacklisted lib - this check should be performed later.
// Some libraries are loaded when we load libraries during startup.
if (LibraryCheck::get_instance().perform_check()) {
std::wstring text = L"Following libraries has been detected inside of the PrusaSlicer process."
L" We suggest stopping or uninstalling these services if you experience crashes or unexpected behaviour while using PrusaSlicer.\n\n";
text += LibraryCheck::get_instance().get_blacklisted_string();
// Notify user that a blacklisted DLL was injected into PrusaSlicer process (for example Nahimic, see GH #5573).
// We hope that if a DLL is being injected into a PrusaSlicer process, it happens at the very start of the application,
// thus we shall detect them now.
if (BlacklistedLibraryCheck::get_instance().perform_check()) {
std::wstring text = L"Following DLLs have been injected into the PrusaSlicer process:\n\n";
text += BlacklistedLibraryCheck::get_instance().get_blacklisted_string();
text += L"\n\n"
L"PrusaSlicer is known to not run correctly with these DLLs injected. "
L"We suggest stopping or uninstalling these services if you experience "
L"crashes or unexpected behaviour while using PrusaSlicer.\n"
L"For example, ASUS Sonic Studio injects a Nahimic driver, which makes PrusaSlicer "
L"to crash on a secondary monitor, see PrusaSlicer github issue #5573";
MessageBoxW(NULL, text.c_str(), L"Warning"/*L"Incopatible library found"*/, MB_OK);
}
#endif

View File

@ -131,8 +131,6 @@ namespace ImGui
const char MaterialIconMarker = 0x8;
const char CloseNotifButton = 0xB;
const char CloseNotifHoverButton = 0xC;
// const char TimerDotMarker = 0xE;
// const char TimerDotEmptyMarker = 0xF;
const char MinimalizeButton = 0xE;
const char MinimalizeHoverButton = 0xF;
const char WarningMarker = 0x10;
@ -141,6 +139,19 @@ namespace ImGui
const char EjectHoverButton = 0x13;
const char CancelButton = 0x14;
const char CancelHoverButton = 0x15;
const char VarLayerHeightMarker = 0x16;
const char RightArrowButton = 0x18;
const char RightArrowHoverButton = 0x19;
const char PreferencesButton = 0x1A;
const char PreferencesHoverButton = 0x1B;
const char SinkingObjectMarker = 0x1C;
const char CustomSupportsMarker = 0x1D;
const char CustomSeamMarker = 0x1E;
const char MmuSegmentationMarker = 0x1F;
// void MyFunction(const char* name, const MyMatrix44& v);
}

View File

@ -155,11 +155,6 @@ void AppConfig::set_defaults()
if (get("seq_top_layer_only").empty())
set("seq_top_layer_only", "1");
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (get("seq_top_gcode_indices").empty())
set("seq_top_gcode_indices", "1");
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (get("use_perspective_camera").empty())
set("use_perspective_camera", "1");
@ -172,6 +167,12 @@ void AppConfig::set_defaults()
if (get("show_splash_screen").empty())
set("show_splash_screen", "1");
if (get("last_hint").empty())
set("last_hint", "0");
if (get("show_hints").empty())
set("show_hints", "1");
#ifdef _WIN32
if (get("use_legacy_3DConnexion").empty())
set("use_legacy_3DConnexion", "0");
@ -544,6 +545,8 @@ void AppConfig::update_config_dir(const std::string &dir)
void AppConfig::update_skein_dir(const std::string &dir)
{
if (is_shapes_dir(dir))
return; // do not save "shapes gallery" directory
this->set("recent", "skein_directory", dir);
}
/*
@ -576,7 +579,7 @@ std::string AppConfig::get_last_output_dir(const std::string& alt, const bool re
if (it2 != it->second.end() && it3 != it->second.end() && !it2->second.empty() && it3->second == "1")
return it2->second;
}
return alt;
return is_shapes_dir(alt) ? get_last_dir() : alt;
}
void AppConfig::update_last_output_dir(const std::string& dir, const bool removable)

View File

@ -1,4 +1,4 @@
#include "LibraryCheck.hpp"
#include "BlacklistedLibraryCheck.hpp"
#include <cstdio>
#include <boost/nowide/convert.hpp>
@ -12,61 +12,46 @@ namespace Slic3r {
#ifdef WIN32
//only dll name with .dll suffix - currently case sensitive
const std::vector<std::wstring> LibraryCheck::blacklist({ L"NahimicOSD.dll" });
const std::vector<std::wstring> BlacklistedLibraryCheck::blacklist({ L"NahimicOSD.dll" });
bool LibraryCheck::get_blacklisted(std::vector<std::wstring>& names)
bool BlacklistedLibraryCheck::get_blacklisted(std::vector<std::wstring>& names)
{
if (m_found.empty())
return false;
for (const auto& lib : m_found)
names.emplace_back(lib);
return true;
}
std::wstring LibraryCheck::get_blacklisted_string()
std::wstring BlacklistedLibraryCheck::get_blacklisted_string()
{
std::wstring ret;
if (m_found.empty())
return ret;
//ret = L"These libraries has been detected inside of the PrusaSlicer process.\n"
// L"We suggest stopping or uninstalling these services if you experience crashes while using PrusaSlicer.\n\n";
for (const auto& lib : m_found)
{
ret += lib;
ret += L"\n";
}
ret += lib + L"\n";
return ret;
}
bool LibraryCheck::perform_check()
{
DWORD processID = GetCurrentProcessId();
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
bool BlacklistedLibraryCheck::perform_check()
{
// Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
if (NULL == hProcess)
return false;
// Get a list of all the modules in this process.
HMODULE hMods[1024];
DWORD cbNeeded;
if (EnumProcessModulesEx(hProcess, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL))
{
//printf("Total Dlls: %d\n", cbNeeded / sizeof(HMODULE));
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
for (unsigned int i = 0; i < cbNeeded / sizeof(HMODULE); ++ i)
{
TCHAR szModName[MAX_PATH];
wchar_t szModName[MAX_PATH];
// Get the full path to the module's file.
if (GetModuleFileNameEx(hProcess, hMods[i], szModName,
sizeof(szModName) / sizeof(TCHAR)))
if (GetModuleFileNameExW(hProcess, hMods[i], szModName, MAX_PATH))
{
// Add to list if blacklisted
if(LibraryCheck::is_blacklisted(szModName)) {
if (BlacklistedLibraryCheck::is_blacklisted(szModName)) {
//wprintf(L"Contains library: %s\n", szModName);
if (std::find(m_found.begin(), m_found.end(), szModName) == m_found.end())
m_found.emplace_back(szModName);
@ -79,23 +64,22 @@ bool LibraryCheck::perform_check()
CloseHandle(hProcess);
//printf("\n");
return !m_found.empty();
}
bool LibraryCheck::is_blacklisted(std::wstring dllpath)
bool BlacklistedLibraryCheck::is_blacklisted(const std::wstring &dllpath)
{
std::wstring dllname = boost::filesystem::path(dllpath).filename().wstring();
//std::transform(dllname.begin(), dllname.end(), dllname.begin(), std::tolower);
if (std::find(LibraryCheck::blacklist.begin(), LibraryCheck::blacklist.end(), dllname) != LibraryCheck::blacklist.end()) {
if (std::find(BlacklistedLibraryCheck::blacklist.begin(), BlacklistedLibraryCheck::blacklist.end(), dllname) != BlacklistedLibraryCheck::blacklist.end()) {
//std::wprintf(L"%s is blacklisted\n", dllname.c_str());
return true;
}
//std::wprintf(L"%s is NOT blacklisted\n", dllname.c_str());
return false;
}
bool LibraryCheck::is_blacklisted(std::string dllpath)
bool BlacklistedLibraryCheck::is_blacklisted(const std::string &dllpath)
{
return LibraryCheck::is_blacklisted(boost::nowide::widen(dllpath));
return BlacklistedLibraryCheck::is_blacklisted(boost::nowide::widen(dllpath));
}
#endif //WIN32

View File

@ -1,5 +1,5 @@
#ifndef slic3r_LibraryCheck_hpp_
#define slic3r_LibraryCheck_hpp_
#ifndef slic3r_BlacklistedLibraryCheck_hpp_
#define slic3r_BlacklistedLibraryCheck_hpp_
#ifdef WIN32
#include <windows.h>
@ -10,30 +10,31 @@
namespace Slic3r {
#ifdef WIN32
class LibraryCheck
class BlacklistedLibraryCheck
{
public:
static LibraryCheck& get_instance()
static BlacklistedLibraryCheck& get_instance()
{
static LibraryCheck instance;
static BlacklistedLibraryCheck instance;
return instance;
}
private:
LibraryCheck() {}
BlacklistedLibraryCheck() = default;
std::vector<std::wstring> m_found;
public:
LibraryCheck(LibraryCheck const&) = delete;
void operator=(LibraryCheck const&) = delete;
BlacklistedLibraryCheck(BlacklistedLibraryCheck const&) = delete;
void operator=(BlacklistedLibraryCheck const&) = delete;
// returns all found blacklisted dlls
bool get_blacklisted(std::vector<std::wstring>& names);
std::wstring get_blacklisted_string();
// returns true if enumerating found blacklisted dll
bool perform_check();
static bool is_blacklisted(std::string dllpath);
static bool is_blacklisted(std::wstring dllpath);
// UTF-8 encoded path
static bool is_blacklisted(const std::string &dllpath);
static bool is_blacklisted(const std::wstring &dllpath);
private:
static const std::vector<std::wstring> blacklist;
};
@ -42,4 +43,4 @@ private:
} // namespace Slic3r
#endif //slic3r_LibraryCheck_hpp_
#endif //slic3r_BlacklistedLibraryCheck_hpp_

View File

@ -1,5 +1,5 @@
project(libslic3r)
cmake_minimum_required(VERSION 3.13)
project(libslic3r)
include(PrecompiledHeader)
@ -125,8 +125,8 @@ add_library(libslic3r STATIC
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
Line.cpp
Line.hpp
LibraryCheck.cpp
LibraryCheck.hpp
BlacklistedLibraryCheck.cpp
BlacklistedLibraryCheck.hpp
LocalesUtils.cpp
LocalesUtils.hpp
Model.cpp

View File

@ -20,10 +20,13 @@ public:
Contour(const Slic3r::Point *data, size_t size, bool open) : Contour(data, data + size, open) {}
Contour(const std::vector<Slic3r::Point> &pts, bool open) : Contour(pts.data(), pts.size(), open) {}
const Slic3r::Point *begin() const { return m_begin; }
const Slic3r::Point *end() const { return m_end; }
bool open() const { return m_open; }
bool closed() const { return ! m_open; }
const Slic3r::Point *begin() const { return m_begin; }
const Slic3r::Point *end() const { return m_end; }
bool open() const { return m_open; }
bool closed() const { return !m_open; }
const Slic3r::Point &front() const { return *m_begin; }
const Slic3r::Point &back() const { return *(m_end - 1); }
// Start point of a segment idx.
const Slic3r::Point& segment_start(size_t idx) const {
@ -61,6 +64,23 @@ public:
size_t num_segments() const { return this->size() - (m_open ? 1 : 0); }
Line get_segment(size_t idx) const
{
assert(idx < this->num_segments());
return Line(this->segment_start(idx), this->segment_end(idx));
}
Lines get_segments() const
{
Lines lines;
lines.reserve(this->num_segments());
if (this->num_segments() > 2) {
for (auto it = this->begin(); it != this->end() - 1; ++it) lines.push_back(Line(*it, *(it + 1)));
if (!m_open) lines.push_back(Line(this->back(), this->front()));
}
return lines;
}
private:
size_t size() const { return m_end - m_begin; }

View File

@ -666,7 +666,6 @@ namespace Slic3r {
close_zip_reader(&archive);
#if ENABLE_RELOAD_FROM_DISK_FOR_3MF
if (m_version == 0) {
// if the 3mf was not produced by PrusaSlicer and there is more than one instance,
// split the object in as many objects as instances
@ -711,7 +710,6 @@ namespace Slic3r {
++i;
}
}
#endif // ENABLE_RELOAD_FROM_DISK_FOR_3MF
for (const IdToModelObjectMap::value_type& object : m_objects) {
if (object.second >= int(m_model->objects.size())) {
@ -779,7 +777,6 @@ namespace Slic3r {
return false;
}
#if ENABLE_RELOAD_FROM_DISK_FOR_3MF
int object_idx = 0;
for (ModelObject* o : model.objects) {
int volume_idx = 0;
@ -795,7 +792,6 @@ namespace Slic3r {
}
++object_idx;
}
#endif // ENABLE_RELOAD_FROM_DISK_FOR_3MF
// // fixes the min z of the model if negative
// model.adjust_min_z();
@ -1877,7 +1873,6 @@ namespace Slic3r {
stl_get_size(&stl);
triangle_mesh.repair();
#if ENABLE_RELOAD_FROM_DISK_FOR_3MF
if (m_version == 0) {
// if the 3mf was not produced by PrusaSlicer and there is only one instance,
// bake the transformation into the geometry to allow the reload from disk command
@ -1887,7 +1882,6 @@ namespace Slic3r {
object.instances.front()->set_transformation(Slic3r::Geometry::Transformation());
}
}
#endif // ENABLE_RELOAD_FROM_DISK_FOR_3MF
ModelVolume* volume = object.add_volume(std::move(triangle_mesh));
// stores the volume matrix taken from the metadata, if present

View File

@ -172,11 +172,7 @@ namespace Slic3r {
// subdivide the retraction in segments
if (!wipe_path.empty()) {
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_Start) + "\n";
#else
gcode += ";" + GCodeProcessor::Wipe_Start_Tag + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
for (const Line& line : wipe_path.lines()) {
double segment_length = line.length();
/* Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one
@ -192,11 +188,7 @@ namespace Slic3r {
);
}
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Wipe_End) + "\n";
#else
gcode += ";" + GCodeProcessor::Wipe_End_Tag + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcodegen.set_last_pos(wipe_path.points.back());
}
@ -655,7 +647,6 @@ namespace DoExport {
print_statistics.filament_stats = result.print_statistics.volumes_per_extruder;
}
#if ENABLE_VALIDATE_CUSTOM_GCODE
// if any reserved keyword is found, returns a std::vector containing the first MAX_COUNT keywords found
// into pairs containing:
// first: source
@ -714,7 +705,6 @@ namespace DoExport {
return ret;
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
} // namespace DoExport
void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb)
@ -729,7 +719,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
print->set_started(psGCodeExport);
#if ENABLE_VALIDATE_CUSTOM_GCODE
// check if any custom gcode contains keywords used by the gcode processor to
// produce time estimation and gcode toolpaths
std::vector<std::pair<std::string, std::string>> validation_res = DoExport::validate_custom_gcode(*print);
@ -743,7 +732,6 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
reports +
_(L("This may cause problems in g-code visualization and printing time estimation.")));
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
BOOST_LOG_TRIVIAL(info) << "Exporting G-code..." << log_memory_info();
@ -794,16 +782,11 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
m_processor.process_file(path_tmp, true, [print]() { print->throw_if_canceled(); });
// DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics);
DoExport::update_print_estimated_stats(m_processor, m_writer.extruders(), print->m_print_statistics);
#if ENABLE_GCODE_WINDOW
if (result != nullptr) {
*result = std::move(m_processor.extract_result());
// set the filename to the correct value
result->filename = path;
}
#else
if (result != nullptr)
*result = std::move(m_processor.extract_result());
#endif // ENABLE_GCODE_WINDOW
BOOST_LOG_TRIVIAL(debug) << "Finished processing gcode, " << log_memory_info();
if (rename_file(path_tmp, path))
@ -1168,11 +1151,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// adds tags for time estimators
if (print.config().remaining_times.value)
#if ENABLE_VALIDATE_CUSTOM_GCODE
_write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::First_Line_M73_Placeholder).c_str());
#else
_writeln(file, GCodeProcessor::First_Line_M73_Placeholder_Tag);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
m_placeholder_parser = print.placeholder_parser();
@ -1279,11 +1258,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false);
// adds tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
_write_format(file, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
#else
_write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
// Write the custom start G-code
_writeln(file, start_gcode);
@ -1444,11 +1419,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
_write(file, m_writer.set_fan(false));
// adds tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
_write_format(file, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
#else
_write_format(file, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(erCustom).c_str());
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
// Process filament-specific gcode in extruder order.
{
@ -1475,11 +1446,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
// adds tags for time estimators
if (print.config().remaining_times.value)
#if ENABLE_VALIDATE_CUSTOM_GCODE
_write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str());
#else
_writeln(file, GCodeProcessor::Last_Line_M73_Placeholder_Tag);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
print.throw_if_canceled();
@ -1495,11 +1462,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
_write_format(file, "; total filament cost = %.2lf\n", print.m_print_statistics.total_cost);
if (print.m_print_statistics.total_toolchanges > 0)
_write_format(file, "; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
#if ENABLE_VALIDATE_CUSTOM_GCODE
_write_format(file, ";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
#else
_writeln(file, GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
// Append full config.
_write(file, "\n");
@ -1799,11 +1762,11 @@ namespace ProcessLayer
assert(m600_extruder_before_layer >= 0);
// Color Change or Tool Change as Color Change.
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(m600_extruder_before_layer) + "," + custom_gcode->color + "\n";
#else
gcode += ";" + GCodeProcessor::Color_Change_Tag + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Color_Change) + ",T" + std::to_string(m600_extruder_before_layer) + "\n";
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
if (!single_extruder_printer && m600_extruder_before_layer >= 0 && first_extruder_id != (unsigned)m600_extruder_before_layer
// && !MMU1
@ -1828,11 +1791,7 @@ namespace ProcessLayer
if (gcode_type == CustomGCode::PausePrint) // Pause print
{
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Pause_Print) + "\n";
#else
gcode += ";" + GCodeProcessor::Pause_Print_Tag + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
//! FIXME_in_fw show message during print pause
if (!pause_print_msg.empty())
gcode += "M117 " + pause_print_msg + "\n";
@ -1840,11 +1799,7 @@ namespace ProcessLayer
}
else {
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Custom_Code) + "\n";
#else
gcode += ";" + GCodeProcessor::Custom_Code_Tag + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
if (gcode_type == CustomGCode::Template) // Template Custom Gcode
gcode += gcodegen.placeholder_parser_process("template_custom_gcode", config.template_custom_gcode, current_extruder_id);
else // custom Gcode
@ -1991,22 +1946,14 @@ void GCode::process_layer(
assert(is_decimal_separator_point()); // for the sprintfs
// add tag for processor
#if ENABLE_VALIDATE_CUSTOM_GCODE
gcode += ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Layer_Change) + "\n";
#else
gcode += ";" + GCodeProcessor::Layer_Change_Tag + "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
// export layer z
char buf[64];
sprintf(buf, ";Z:%g\n", print_z);
gcode += buf;
// export layer height
float height = first_layer ? static_cast<float>(print_z) : static_cast<float>(print_z) - m_last_layer_z;
#if ENABLE_VALIDATE_CUSTOM_GCODE
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), height);
#else
sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), height);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcode += buf;
// update caches
m_last_layer_z = static_cast<float>(print_z);
@ -2835,21 +2782,13 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (path.role() != m_last_processor_extrusion_role) {
m_last_processor_extrusion_role = path.role();
#if ENABLE_VALIDATE_CUSTOM_GCODE
sprintf(buf, ";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str());
#else
sprintf(buf, ";%s%s\n", GCodeProcessor::Extrusion_Role_Tag.c_str(), ExtrusionEntity::role_to_string(m_last_processor_extrusion_role).c_str());
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcode += buf;
}
if (last_was_wipe_tower || m_last_width != path.width) {
m_last_width = path.width;
#if ENABLE_VALIDATE_CUSTOM_GCODE
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width).c_str(), m_last_width);
#else
sprintf(buf, ";%s%g\n", GCodeProcessor::Width_Tag.c_str(), m_last_width);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcode += buf;
}
@ -2863,11 +2802,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (last_was_wipe_tower || std::abs(m_last_height - path.height) > EPSILON) {
m_last_height = path.height;
#if ENABLE_VALIDATE_CUSTOM_GCODE
sprintf(buf, ";%s%g\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height).c_str(), m_last_height);
#else
sprintf(buf, ";%s%g\n", GCodeProcessor::Height_Tag.c_str(), m_last_height);
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gcode += buf;
}

View File

@ -5,15 +5,11 @@
#include "GCodeProcessor.hpp"
#include <boost/log/trivial.hpp>
#if ENABLE_VALIDATE_CUSTOM_GCODE
#include <boost/algorithm/string/predicate.hpp>
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
#include <boost/algorithm/string/split.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/nowide/cstdio.hpp>
#if ENABLE_GCODE_WINDOW
#include <boost/filesystem/path.hpp>
#endif // ENABLE_GCODE_WINDOW
#include <float.h>
#include <assert.h>
@ -37,7 +33,6 @@ static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
namespace Slic3r {
#if ENABLE_VALIDATE_CUSTOM_GCODE
const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
"TYPE:",
"WIPE_START",
@ -52,21 +47,6 @@ const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
"_GP_LAST_LINE_M73_PLACEHOLDER",
"_GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER"
};
#else
const std::string GCodeProcessor::Extrusion_Role_Tag = "TYPE:";
const std::string GCodeProcessor::Wipe_Start_Tag = "WIPE_START";
const std::string GCodeProcessor::Wipe_End_Tag = "WIPE_END";
const std::string GCodeProcessor::Height_Tag = "HEIGHT:";
const std::string GCodeProcessor::Width_Tag = "WIDTH:";
const std::string GCodeProcessor::Layer_Change_Tag = "LAYER_CHANGE";
const std::string GCodeProcessor::Color_Change_Tag = "COLOR_CHANGE";
const std::string GCodeProcessor::Pause_Print_Tag = "PAUSE_PRINT";
const std::string GCodeProcessor::Custom_Code_Tag = "CUSTOM_GCODE";
const std::string GCodeProcessor::First_Line_M73_Placeholder_Tag = "; _GP_FIRST_LINE_M73_PLACEHOLDER";
const std::string GCodeProcessor::Last_Line_M73_Placeholder_Tag = "; _GP_LAST_LINE_M73_PLACEHOLDER";
const std::string GCodeProcessor::Estimated_Printing_Time_Placeholder_Tag = "; _GP_ESTIMATED_PRINTING_TIME_PLACEHOLDER";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
const float GCodeProcessor::Wipe_Width = 0.05f;
const float GCodeProcessor::Wipe_Height = 0.05f;
@ -202,9 +182,7 @@ void GCodeProcessor::TimeMachine::reset()
max_travel_acceleration = 0.0f;
extrude_factor_override_percentage = 1.0f;
time = 0.0f;
#if ENABLE_EXTENDED_M73_LINES
stop_times = std::vector<StopTime>();
#endif // ENABLE_EXTENDED_M73_LINES
curr.reset();
prev.reset();
gcode_time.reset();
@ -332,13 +310,11 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks)
layers_time[block.layer_id - 1] += block_time;
}
g1_times_cache.push_back({ block.g1_line_id, time });
#if ENABLE_EXTENDED_M73_LINES
// update times for remaining time to printer stop placeholders
auto it_stop_time = std::lower_bound(stop_times.begin(), stop_times.end(), block.g1_line_id,
[](const StopTime& t, unsigned int value) { return t.g1_line_id < value; });
if (it_stop_time != stop_times.end() && it_stop_time->g1_line_id == block.g1_line_id)
it_stop_time->elapsed_time = time;
#endif // ENABLE_EXTENDED_M73_LINES
}
if (keep_last_n_blocks)
@ -361,11 +337,7 @@ void GCodeProcessor::TimeProcessor::reset()
machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].enabled = true;
}
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, std::vector<MoveVertex>& moves)
#else
void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
{
boost::nowide::ifstream in(filename);
if (!in.good())
@ -381,16 +353,12 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
return int(::roundf(time_in_seconds / 60.0f));
};
#if ENABLE_EXTENDED_M73_LINES
auto time_in_last_minute = [](float time_in_seconds) {
assert(time_in_seconds <= 60.0f);
return time_in_seconds / 60.0f;
};
auto format_line_M73_main = [](const std::string& mask, int percent, int time) {
#else
auto format_line_M73 = [](const std::string& mask, int percent, int time) {
#endif // ENABLE_EXTENDED_M73_LINES
char line_M73[64];
sprintf(line_M73, mask.c_str(),
std::to_string(percent).c_str(),
@ -398,7 +366,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
return std::string(line_M73);
};
#if ENABLE_EXTENDED_M73_LINES
auto format_line_M73_stop_int = [](const std::string& mask, int time) {
char line_M73[64];
sprintf(line_M73, mask.c_str(), std::to_string(time).c_str());
@ -414,13 +381,11 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
sprintf(line_M73, mask.c_str(), format_time_float(time).c_str());
return std::string(line_M73);
};
#endif // ENABLE_EXTENDED_M73_LINES
GCodeReader parser;
std::string gcode_line;
size_t g1_lines_counter = 0;
// keeps track of last exported pair <percent, remaining time>
#if ENABLE_EXTENDED_M73_LINES
std::array<std::pair<int, int>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported_main;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_main[i] = { 0, time_in_minutes(machines[i].time) };
@ -431,27 +396,18 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported_stop[i] = time_in_minutes(machines[i].time);
}
#else
std::array<std::pair<int, int>, static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count)> last_exported;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
last_exported[i] = { 0, time_in_minutes(machines[i].time) };
}
#endif // ENABLE_EXTENDED_M73_LINES
// buffer line to export only when greater than 64K to reduce writing calls
std::string export_line;
// replace placeholder lines with the proper final value
auto process_placeholders = [&](const std::string& gcode_line) {
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
unsigned int extra_lines_count = 0;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// remove trailing '\n'
std::string line = gcode_line.substr(0, gcode_line.length() - 1);
std::string ret;
#if ENABLE_VALIDATE_CUSTOM_GCODE
if (line.length() > 1) {
line = line.substr(1);
if (export_remaining_time_enabled &&
@ -459,49 +415,23 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
#if ENABLE_EXTENDED_M73_LINES
// export pair <percent, remaining time>
ret += format_line_M73_main(machine.line_m73_main_mask.c_str(),
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100,
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0);
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++extra_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// export remaining time to next printer stop
if (line == reserved_tag(ETags::First_Line_M73_Placeholder) && !machine.stop_times.empty()) {
int to_export_stop = time_in_minutes(machine.stop_times.front().elapsed_time);
ret += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
last_exported_stop[i] = to_export_stop;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++extra_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
}
#else
ret += format_line_M73(machine.line_m73_mask.c_str(),
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? 0 : 100,
(line == reserved_tag(ETags::First_Line_M73_Placeholder)) ? time_in_minutes(machine.time) : 0);
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++extra_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#endif // ENABLE_EXTENDED_M73_LINES
}
}
}
else if (line == reserved_tag(ETags::Estimated_Printing_Time_Placeholder)) {
#else
if (export_remaining_time_enabled && (line == First_Line_M73_Placeholder_Tag || line == Last_Line_M73_Placeholder_Tag)) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
if (machine.enabled) {
ret += format_line_M73(machine.line_m73_mask.c_str(),
(line == First_Line_M73_Placeholder_Tag) ? 0 : 100,
(line == First_Line_M73_Placeholder_Tag) ? time_in_minutes(machines[i].time) : 0);
}
}
}
else if (line == Estimated_Printing_Time_Placeholder_Tag) {
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
PrintEstimatedStatistics::ETimeMode mode = static_cast<PrintEstimatedStatistics::ETimeMode>(i);
@ -514,15 +444,9 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
}
}
}
#if ENABLE_VALIDATE_CUSTOM_GCODE
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
return std::tuple(!ret.empty(), ret.empty() ? gcode_line : ret, (extra_lines_count == 0) ? extra_lines_count : extra_lines_count - 1);
#else
return std::make_pair(!ret.empty(), ret.empty() ? gcode_line : ret);
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
};
// check for temporary lines
@ -546,9 +470,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
// add lines M73 to exported gcode
auto process_line_G1 = [&]() {
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
unsigned int exported_lines_count = 0;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (export_remaining_time_enabled) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
const TimeMachine& machine = machines[i];
@ -559,30 +481,14 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
while (it != machine.g1_times_cache.end() && it->id < g1_lines_counter)
++it;
if (it != machine.g1_times_cache.end() && it->id == g1_lines_counter) {
#if ENABLE_EXTENDED_M73_LINES
std::pair<int, int> to_export_main = { int(100.0f * it->elapsed_time / machine.time),
time_in_minutes(machine.time - it->elapsed_time) };
if (last_exported_main[i] != to_export_main) {
export_line += format_line_M73_main(machine.line_m73_main_mask.c_str(),
to_export_main.first, to_export_main.second);
last_exported_main[i] = to_export_main;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++exported_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#else
float elapsed_time = it->elapsed_time;
std::pair<int, int> to_export = { int(100.0f * elapsed_time / machine.time),
time_in_minutes(machine.time - elapsed_time) };
if (last_exported[i] != to_export) {
export_line += format_line_M73(machine.line_m73_mask.c_str(),
to_export.first, to_export.second);
last_exported[i] = to_export;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++exported_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#endif // ENABLE_EXTENDED_M73_LINES
}
#if ENABLE_EXTENDED_M73_LINES
// export remaining time to next printer stop
auto it_stop = std::upper_bound(machine.stop_times.begin(), machine.stop_times.end(), it->elapsed_time,
[](float value, const TimeMachine::StopTime& t) { return value < t.elapsed_time; });
@ -593,9 +499,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
if (last_exported_stop[i] != to_export_stop) {
export_line += format_line_M73_stop_int(machine.line_m73_stop_mask.c_str(), to_export_stop);
last_exported_stop[i] = to_export_stop;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++exported_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
}
}
else {
@ -620,21 +524,16 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
export_line += format_line_M73_stop_float(machine.line_m73_stop_mask.c_str(), time_in_last_minute(it_stop->elapsed_time - it->elapsed_time));
last_exported_stop[i] = to_export_stop;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++exported_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
}
}
}
}
#endif // ENABLE_EXTENDED_M73_LINES
}
}
}
}
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
return exported_lines_count;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
};
// helper function to write to disk
@ -649,10 +548,8 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
export_line.clear();
};
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
unsigned int line_id = 0;
std::vector<std::pair<unsigned int, unsigned int>> offsets;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
while (std::getline(in, gcode_line)) {
if (!in.good()) {
@ -660,19 +557,13 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
throw Slic3r::RuntimeError(std::string("Time estimator post process export failed.\nError while reading from file.\n"));
}
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++line_id;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
gcode_line += "\n";
// replace placeholder lines
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
auto [processed, result, lines_added_count] = process_placeholders(gcode_line);
if (processed && lines_added_count > 0)
offsets.push_back({ line_id, lines_added_count });
#else
auto [processed, result] = process_placeholders(gcode_line);
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
gcode_line = result;
if (!processed) {
// remove temporary lines
@ -683,15 +574,10 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
parser.parse_line(gcode_line,
[&](GCodeReader& reader, const GCodeReader::GCodeLine& line) {
if (line.cmd_is("G1")) {
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
unsigned int extra_lines_count = process_line_G1();
++g1_lines_counter;
if (extra_lines_count > 0)
offsets.push_back({ line_id, extra_lines_count });
#else
process_line_G1();
++g1_lines_counter;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
}
});
}
@ -707,7 +593,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
fclose(out);
in.close();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// updates moves' gcode ids which have been modified by the insertion of the M73 lines
unsigned int curr_offset_id = 0;
unsigned int total_offset = 0;
@ -718,7 +603,6 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
}
move.gcode_id += total_offset;
}
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (rename_file(out_path, filename))
throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + filename + '\n' +
@ -800,6 +684,9 @@ void GCodeProcessor::Result::reset() {
extruder_colors = std::vector<std::string>();
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
time = 0;
}
#else
@ -811,6 +698,9 @@ void GCodeProcessor::Result::reset() {
extruder_colors = std::vector<std::string>();
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
}
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -827,7 +717,6 @@ const std::vector<std::pair<GCodeProcessor::EProducer, std::string>> GCodeProces
unsigned int GCodeProcessor::s_result_id = 0;
#if ENABLE_VALIDATE_CUSTOM_GCODE
bool GCodeProcessor::contains_reserved_tag(const std::string& gcode, std::string& found_tag)
{
bool ret = false;
@ -879,20 +768,14 @@ bool GCodeProcessor::contains_reserved_tags(const std::string& gcode, unsigned i
return ret;
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
GCodeProcessor::GCodeProcessor()
{
reset();
#if ENABLE_EXTENDED_M73_LINES
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_main_mask = "M73 P%s R%s\n";
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_stop_mask = "M73 C%s\n";
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_main_mask = "M73 Q%s S%s\n";
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_stop_mask = "M73 D%s\n";
#else
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Normal)].line_m73_mask = "M73 P%s R%s\n";
m_time_processor.machines[static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Stealth)].line_m73_mask = "M73 Q%s S%s\n";
#endif // ENABLE_EXTENDED_M73_LINES
}
void GCodeProcessor::apply_config(const PrintConfig& config)
@ -959,11 +842,9 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_time_processor.export_remaining_time_enabled = config.remaining_times.value;
m_use_volumetric_e = config.use_volumetric_e;
#if ENABLE_START_GCODE_VISUALIZATION
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
if (first_layer_height != nullptr)
m_first_layer_height = std::abs(first_layer_height->value);
#endif // ENABLE_START_GCODE_VISUALIZATION
}
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
@ -1188,11 +1069,9 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
if (use_volumetric_e != nullptr)
m_use_volumetric_e = use_volumetric_e->value;
#if ENABLE_START_GCODE_VISUALIZATION
const ConfigOptionFloatOrPercent* first_layer_height = config.option<ConfigOptionFloatOrPercent>("first_layer_height");
if (first_layer_height != nullptr)
m_first_layer_height = std::abs(first_layer_height->value);
#endif // ENABLE_START_GCODE_VISUALIZATION
}
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
@ -1214,12 +1093,8 @@ void GCodeProcessor::reset()
m_cached_position.reset();
m_wiping = false;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
m_line_id = 0;
#if ENABLE_SEAMS_VISUALIZATION
m_last_line_id = 0;
#endif // ENABLE_SEAMS_VISUALIZATION
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
m_feedrate = 0.0f;
m_width = 0.0f;
m_height = 0.0f;
@ -1240,10 +1115,8 @@ void GCodeProcessor::reset()
}
m_extruded_last_z = 0.0f;
#if ENABLE_START_GCODE_VISUALIZATION
m_first_layer_height = 0.0f;
m_processing_start_custom_gcode = false;
#endif // ENABLE_START_GCODE_VISUALIZATION
m_g1_line_id = 0;
m_layer_id = 0;
m_cp_color.reset();
@ -1258,6 +1131,9 @@ void GCodeProcessor::reset()
m_result.id = ++s_result_id;
m_use_volumetric_e = false;
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
m_last_default_color_id = 0;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_mm3_per_mm_compare.reset();
@ -1284,11 +1160,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
if (cmd.length() == 0) {
const std::string_view comment = line.comment();
if (comment.length() > 1 && detect_producer(comment))
#if ENABLE_VALIDATE_CUSTOM_GCODE
m_parser.quit_parsing();
#else
m_parser.quit_parsing_file();
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
}
});
@ -1308,9 +1180,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
}
// process gcode
#if ENABLE_GCODE_WINDOW
m_result.filename = filename;
#endif // ENABLE_GCODE_WINDOW
m_result.id = ++s_result_id;
// 1st move must be a dummy move
m_result.moves.emplace_back(MoveVertex());
@ -1349,11 +1219,7 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
// post-process to add M73 lines into the gcode
if (apply_postprocess)
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
m_time_processor.post_process(filename, m_result.moves);
#else
m_time_processor.post_process(filename);
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
std::cout << "\n";
@ -1500,9 +1366,7 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
{
/* std::cout << line.raw() << std::endl; */
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
++m_line_id;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// update start position
m_start_position = m_end_position;
@ -1627,17 +1491,12 @@ void GCodeProcessor::process_tags(const std::string_view comment)
if (m_producers_enabled && process_producers_tags(comment))
return;
#if ENABLE_VALIDATE_CUSTOM_GCODE
// extrusion role tag
if (boost::starts_with(comment, reserved_tag(ETags::Role))) {
set_extrusion_role(ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length())));
#if ENABLE_SEAMS_VISUALIZATION
if (m_extrusion_role == erExternalPerimeter)
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
#if ENABLE_START_GCODE_VISUALIZATION
m_processing_start_custom_gcode = (m_extrusion_role == erCustom && m_g1_line_id == 0);
#endif // ENABLE_START_GCODE_VISUALIZATION
return;
}
@ -1652,28 +1511,8 @@ void GCodeProcessor::process_tags(const std::string_view comment)
m_wiping = false;
return;
}
#else
// extrusion role tag
if (boost::starts_with(comment, Extrusion_Role_Tag)) {
set_extrusion_role(ExtrusionEntity::string_to_role(comment.substr(Extrusion_Role_Tag.length())));
return;
}
// wipe start tag
if (boost::starts_with(comment, Wipe_Start_Tag)) {
m_wiping = true;
return;
}
// wipe end tag
if (boost::starts_with(comment, Wipe_End_Tag)) {
m_wiping = false;
return;
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
if (!m_producers_enabled || m_producer == EProducer::PrusaSlicer) {
#if ENABLE_VALIDATE_CUSTOM_GCODE
// height tag
if (boost::starts_with(comment, reserved_tag(ETags::Height))) {
if (!parse_number(comment.substr(reserved_tag(ETags::Height).size()), m_forced_height))
@ -1686,26 +1525,61 @@ void GCodeProcessor::process_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
return;
}
#else
// height tag
if (boost::starts_with(comment, Height_Tag)) {
if (!parse_number(comment.substr(Height_Tag.size()), m_forced_height))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Height (" << comment << ").";
return;
}
// width tag
if (boost::starts_with(comment, Width_Tag)) {
if (!parse_number(comment.substr(Width_Tag.size()), m_forced_width))
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Width (" << comment << ").";
return;
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
}
#if ENABLE_VALIDATE_CUSTOM_GCODE
// color change tag
if (boost::starts_with(comment, reserved_tag(ETags::Color_Change))) {
unsigned char extruder_id = 0;
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
static std::vector<std::string> Default_Colors = {
"#0B2C7A", // { 0.043f, 0.173f, 0.478f }, // bluish
"#1C8891", // { 0.110f, 0.533f, 0.569f },
"#AAF200", // { 0.667f, 0.949f, 0.000f },
"#F5CE0A", // { 0.961f, 0.808f, 0.039f },
"#D16830", // { 0.820f, 0.408f, 0.188f },
"#942616", // { 0.581f, 0.149f, 0.087f } // reddish
};
std::string color = Default_Colors[0];
auto is_valid_color = [](const std::string& color) {
auto is_hex_digit = [](char c) {
return ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f'));
};
if (color[0] != '#' || color.length() != 7)
return false;
for (int i = 1; i <= 6; ++i) {
if (!is_hex_digit(color[i]))
return false;
}
return true;
};
std::vector<std::string> tokens;
boost::split(tokens, comment, boost::is_any_of(","), boost::token_compress_on);
if (tokens.size() > 1) {
if (tokens[1][0] == 'T') {
int eid;
if (!parse_number(tokens[1].substr(1), eid) || eid < 0 || eid > 255) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
return;
}
extruder_id = static_cast<unsigned char>(eid);
}
}
if (tokens.size() > 2) {
if (is_valid_color(tokens[2]))
color = tokens[2];
}
else {
color = Default_Colors[m_last_default_color_id];
++m_last_default_color_id;
if (m_last_default_color_id == Default_Colors.size())
m_last_default_color_id = 0;
}
#else
if (boost::starts_with(comment.substr(reserved_tag(ETags::Color_Change).size()), ",T")) {
int eid;
if (!parse_number(comment.substr(reserved_tag(ETags::Color_Change).size() + 2), eid) || eid < 0 || eid > 255) {
@ -1714,6 +1588,7 @@ void GCodeProcessor::process_tags(const std::string_view comment)
}
extruder_id = static_cast<unsigned char>(eid);
}
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
if (extruder_id < m_extruder_colors.size())
m_extruder_colors[extruder_id] = static_cast<unsigned char>(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
@ -1724,10 +1599,18 @@ void GCodeProcessor::process_tags(const std::string_view comment)
if (m_extruder_id == extruder_id) {
m_cp_color.current = m_extruder_colors[extruder_id];
store_move_vertex(EMoveType::Color_change);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
CustomGCode::Item item = { static_cast<double>(m_end_position[2]), CustomGCode::ColorChange, extruder_id + 1, color, "" };
m_result.custom_gcode_per_print_z.emplace_back(item);
process_custom_gcode_time(CustomGCode::ColorChange);
process_filaments(CustomGCode::ColorChange);
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
}
#if !ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
process_custom_gcode_time(CustomGCode::ColorChange);
process_filaments(CustomGCode::ColorChange);
#endif // !ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
return;
}
@ -1735,6 +1618,10 @@ void GCodeProcessor::process_tags(const std::string_view comment)
// pause print tag
if (comment == reserved_tag(ETags::Pause_Print)) {
store_move_vertex(EMoveType::Pause_Print);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
CustomGCode::Item item = { static_cast<double>(m_end_position[2]), CustomGCode::PausePrint, m_extruder_id + 1, "", "" };
m_result.custom_gcode_per_print_z.emplace_back(item);
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
process_custom_gcode_time(CustomGCode::PausePrint);
return;
}
@ -1742,6 +1629,10 @@ void GCodeProcessor::process_tags(const std::string_view comment)
// custom code tag
if (comment == reserved_tag(ETags::Custom_Code)) {
store_move_vertex(EMoveType::Custom_GCode);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
CustomGCode::Item item = { static_cast<double>(m_end_position[2]), CustomGCode::Custom, m_extruder_id + 1, "", "" };
m_result.custom_gcode_per_print_z.emplace_back(item);
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
return;
}
@ -1750,53 +1641,6 @@ void GCodeProcessor::process_tags(const std::string_view comment)
++m_layer_id;
return;
}
#else
// color change tag
if (boost::starts_with(comment, Color_Change_Tag)) {
unsigned char extruder_id = 0;
if (boost::starts_with(comment.substr(Color_Change_Tag.size()), ",T")) {
int eid;
if (! parse_number(comment.substr(Color_Change_Tag.size() + 2), eid) || eid < 0 || eid > 255) {
BOOST_LOG_TRIVIAL(error) << "GCodeProcessor encountered an invalid value for Color_Change (" << comment << ").";
return;
}
extruder_id = static_cast<unsigned char>(eid);
}
m_extruder_colors[extruder_id] = static_cast<unsigned char>(m_extruder_offsets.size()) + m_cp_color.counter; // color_change position in list of color for preview
++m_cp_color.counter;
if (m_cp_color.counter == UCHAR_MAX)
m_cp_color.counter = 0;
if (m_extruder_id == extruder_id) {
m_cp_color.current = m_extruder_colors[extruder_id];
store_move_vertex(EMoveType::Color_change);
}
process_custom_gcode_time(CustomGCode::ColorChange);
return;
}
// pause print tag
if (comment == Pause_Print_Tag) {
store_move_vertex(EMoveType::Pause_Print);
process_custom_gcode_time(CustomGCode::PausePrint);
return;
}
// custom code tag
if (comment == Custom_Code_Tag) {
store_move_vertex(EMoveType::Custom_GCode);
return;
}
// layer change tag
if (comment == Layer_Change_Tag) {
++m_layer_id;
return;
}
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
// mm3_per_mm print tag
@ -1857,10 +1701,9 @@ bool GCodeProcessor::process_cura_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
#if ENABLE_SEAMS_VISUALIZATION
if (m_extrusion_role == erExternalPerimeter)
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@ -1925,9 +1768,7 @@ bool GCodeProcessor::process_simplify3d_tags(const std::string_view comment)
pos = cmt.find(" outer perimeter");
if (pos == 0) {
set_extrusion_role(erExternalPerimeter);
#if ENABLE_SEAMS_VISUALIZATION
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@ -2082,10 +1923,8 @@ bool GCodeProcessor::process_craftware_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
#if ENABLE_SEAMS_VISUALIZATION
if (m_extrusion_role == erExternalPerimeter)
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@ -2126,10 +1965,9 @@ bool GCodeProcessor::process_ideamaker_tags(const std::string_view comment)
BOOST_LOG_TRIVIAL(warning) << "GCodeProcessor found unknown extrusion role: " << type;
}
#if ENABLE_SEAMS_VISUALIZATION
if (m_extrusion_role == erExternalPerimeter)
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@ -2198,9 +2036,7 @@ bool GCodeProcessor::process_kissslicer_tags(const std::string_view comment)
pos = comment.find(" 'Perimeter Path'");
if (pos == 0) {
set_extrusion_role(erExternalPerimeter);
#if ENABLE_SEAMS_VISUALIZATION
m_seams_detector.activate(true);
#endif // ENABLE_SEAMS_VISUALIZATION
return true;
}
@ -2407,11 +2243,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
}
#if ENABLE_START_GCODE_VISUALIZATION
if (type == EMoveType::Extrude && (m_width == 0.0f || m_height == 0.0f))
#else
if (type == EMoveType::Extrude && (m_extrusion_role == erCustom || m_width == 0.0f || m_height == 0.0f))
#endif // ENABLE_START_GCODE_VISUALIZATION
type = EMoveType::Travel;
// time estimate section
@ -2578,7 +2410,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
machine.calculate_time(TimeProcessor::Planner::queue_size);
}
#if ENABLE_SEAMS_VISUALIZATION
if (m_seams_detector.is_active()) {
// check for seam starting vertex
if (type == EMoveType::Extrude && m_extrusion_role == erExternalPerimeter && !m_seams_detector.has_first_vertex())
@ -2602,7 +2433,6 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
m_seams_detector.activate(false);
}
}
#endif // ENABLE_SEAMS_VISUALIZATION
// store move
store_move_vertex(type);
@ -3057,29 +2887,17 @@ void GCodeProcessor::process_T(const std::string_view command)
void GCodeProcessor::store_move_vertex(EMoveType type)
{
#if ENABLE_SEAMS_VISUALIZATION
m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ?
m_line_id + 1 :
((type == EMoveType::Seam) ? m_last_line_id : m_line_id);
#endif // ENABLE_SEAMS_VISUALIZATION
MoveVertex vertex = {
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#if ENABLE_SEAMS_VISUALIZATION
m_last_line_id,
#else
(type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ? m_line_id + 1 : m_line_id,
#endif // ENABLE_SEAMS_VISUALIZATION
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
type,
m_extrusion_role,
m_extruder_id,
m_cp_color.current,
#if ENABLE_START_GCODE_VISUALIZATION
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
#else
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
#endif // ENABLE_START_GCODE_VISUALIZATION
m_end_position[E] - m_start_position[E],
m_feedrate,
m_width,
@ -3091,7 +2909,6 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
};
m_result.moves.emplace_back(vertex);
#if ENABLE_EXTENDED_M73_LINES
// stores stop time placeholders for later use
if (type == EMoveType::Color_change || type == EMoveType::Pause_Print) {
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
@ -3102,7 +2919,6 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
machine.stop_times.push_back({ m_g1_line_id, 0.0f });
}
}
#endif // ENABLE_EXTENDED_M73_LINES
}
void GCodeProcessor::set_extrusion_role(ExtrusionRole role)

View File

@ -12,9 +12,7 @@
#include <vector>
#include <string>
#include <string_view>
#if ENABLE_SEAMS_VISUALIZATION
#include <optional>
#endif // ENABLE_SEAMS_VISUALIZATION
namespace Slic3r {
@ -23,9 +21,7 @@ namespace Slic3r {
Noop,
Retract,
Unretract,
#if ENABLE_SEAMS_VISUALIZATION
Seam,
#endif // ENABLE_SEAMS_VISUALIZATION
Tool_change,
Color_change,
Pause_Print,
@ -82,11 +78,9 @@ namespace Slic3r {
class GCodeProcessor
{
#if ENABLE_VALIDATE_CUSTOM_GCODE
static const std::vector<std::string> Reserved_Tags;
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
public:
#if ENABLE_VALIDATE_CUSTOM_GCODE
enum class ETags : unsigned char
{
Role,
@ -109,20 +103,6 @@ namespace Slic3r {
// checks the given gcode for reserved tags and returns true when finding any
// (the first max_count found tags are returned into found_tag)
static bool contains_reserved_tags(const std::string& gcode, unsigned int max_count, std::vector<std::string>& found_tag);
#else
static const std::string Extrusion_Role_Tag;
static const std::string Wipe_Start_Tag;
static const std::string Wipe_End_Tag;
static const std::string Height_Tag;
static const std::string Layer_Change_Tag;
static const std::string Color_Change_Tag;
static const std::string Pause_Print_Tag;
static const std::string Custom_Code_Tag;
static const std::string First_Line_M73_Placeholder_Tag;
static const std::string Last_Line_M73_Placeholder_Tag;
static const std::string Estimated_Printing_Time_Placeholder_Tag;
static const std::string Width_Tag;
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
static const float Wipe_Width;
static const float Wipe_Height;
@ -210,7 +190,6 @@ namespace Slic3r {
float time() const;
};
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
struct MoveVertex
{
unsigned int gcode_id{ 0 };
@ -230,7 +209,6 @@ namespace Slic3r {
float volumetric_rate() const { return feedrate * mm3_per_mm; }
};
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
private:
struct TimeMachine
@ -269,7 +247,6 @@ namespace Slic3r {
float max_travel_acceleration; // mm/s^2
float extrude_factor_override_percentage;
float time; // s
#if ENABLE_EXTENDED_M73_LINES
struct StopTime
{
unsigned int g1_line_id;
@ -278,9 +255,6 @@ namespace Slic3r {
std::vector<StopTime> stop_times;
std::string line_m73_main_mask;
std::string line_m73_stop_mask;
#else
std::string line_m73_mask;
#endif // ENABLE_EXTENDED_M73_LINES
State curr;
State prev;
CustomGCodeTime gcode_time;
@ -326,12 +300,8 @@ namespace Slic3r {
void reset();
// post process the file with the given filename to add remaining time lines M73
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// and updates moves' gcode ids accordingly
void post_process(const std::string& filename, std::vector<MoveVertex>& moves);
#else
void post_process(const std::string& filename);
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
};
struct UsedFilaments // filaments per ColorChange
@ -358,27 +328,6 @@ namespace Slic3r {
};
public:
#if !ENABLE_GCODE_LINES_ID_IN_H_SLIDER
struct MoveVertex
{
EMoveType type{ EMoveType::Noop };
ExtrusionRole extrusion_role{ erNone };
unsigned char extruder_id{ 0 };
unsigned char cp_color_id{ 0 };
Vec3f position{ Vec3f::Zero() }; // mm
float delta_extruder{ 0.0f }; // mm
float feedrate{ 0.0f }; // mm/s
float width{ 0.0f }; // mm
float height{ 0.0f }; // mm
float mm3_per_mm{ 0.0f };
float fan_speed{ 0.0f }; // percentage
float temperature{ 0.0f }; // Celsius degrees
float time{ 0.0f }; // s
float volumetric_rate() const { return feedrate * mm3_per_mm; }
};
#endif // !ENABLE_GCODE_LINES_ID_IN_H_SLIDER
struct Result
{
struct SettingsIds
@ -393,9 +342,7 @@ namespace Slic3r {
printer = "";
}
};
#if ENABLE_GCODE_WINDOW
std::string filename;
#endif // ENABLE_GCODE_WINDOW
unsigned int id;
std::vector<MoveVertex> moves;
Pointfs bed_shape;
@ -405,6 +352,9 @@ namespace Slic3r {
std::vector<float> filament_diameters;
std::vector<float> filament_densities;
PrintEstimatedStatistics print_statistics;
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
#if ENABLE_GCODE_VIEWER_STATISTICS
int64_t time{ 0 };
@ -412,7 +362,6 @@ namespace Slic3r {
void reset();
};
#if ENABLE_SEAMS_VISUALIZATION
class SeamsDetector
{
bool m_active{ false };
@ -433,7 +382,6 @@ namespace Slic3r {
bool is_active() const { return m_active; }
bool has_first_vertex() const { return m_first_vertex.has_value(); }
};
#endif // ENABLE_SEAMS_VISUALIZATION
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
struct DataChecker
@ -518,12 +466,8 @@ namespace Slic3r {
CachedPosition m_cached_position;
bool m_wiping;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
unsigned int m_line_id;
#if ENABLE_SEAMS_VISUALIZATION
unsigned int m_last_line_id;
#endif // ENABLE_SEAMS_VISUALIZATION
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
float m_feedrate; // mm/s
float m_width; // mm
float m_height; // mm
@ -536,17 +480,16 @@ namespace Slic3r {
ExtruderColors m_extruder_colors;
ExtruderTemps m_extruder_temps;
float m_extruded_last_z;
#if ENABLE_START_GCODE_VISUALIZATION
float m_first_layer_height; // mm
bool m_processing_start_custom_gcode;
#endif // ENABLE_START_GCODE_VISUALIZATION
unsigned int m_g1_line_id;
unsigned int m_layer_id;
CpColor m_cp_color;
bool m_use_volumetric_e;
#if ENABLE_SEAMS_VISUALIZATION
SeamsDetector m_seams_detector;
#endif // ENABLE_SEAMS_VISUALIZATION
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
size_t m_last_default_color_id;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
enum class EProducer
{

View File

@ -34,13 +34,8 @@ public:
{
// adds tag for analyzer:
std::ostringstream str;
#if ENABLE_VALIDATE_CUSTOM_GCODE
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Height) << m_layer_height << "\n"; // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role) << ExtrusionEntity::role_to_string(erWipeTower) << "\n";
#else
str << ";" << GCodeProcessor::Height_Tag << m_layer_height << "\n"; // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming
str << ";" << GCodeProcessor::Extrusion_Role_Tag << ExtrusionEntity::role_to_string(erWipeTower) << "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
m_gcode += str.str();
change_analyzer_line_width(line_width);
}
@ -48,11 +43,7 @@ public:
WipeTowerWriter& change_analyzer_line_width(float line_width) {
// adds tag for analyzer:
std::stringstream str;
#if ENABLE_VALIDATE_CUSTOM_GCODE
str << ";" << GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Width) << line_width << "\n";
#else
str << ";" << GCodeProcessor::Width_Tag << line_width << "\n";
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
m_gcode += str.str();
return *this;
}

View File

@ -120,13 +120,8 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback)
{
boost::nowide::ifstream f(file);
std::string line;
#if ENABLE_VALIDATE_CUSTOM_GCODE
m_parsing = true;
while (m_parsing && std::getline(f, line))
#else
m_parsing_file = true;
while (m_parsing_file && std::getline(f, line))
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
this->parse_line(line, callback);
}

View File

@ -84,12 +84,8 @@ public:
{
const char *ptr = buffer.c_str();
GCodeLine gline;
#if ENABLE_VALIDATE_CUSTOM_GCODE
m_parsing = true;
while (m_parsing && *ptr != 0) {
#else
while (*ptr != 0) {
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
gline.reset();
ptr = this->parse_line(ptr, gline, callback);
}
@ -113,11 +109,7 @@ public:
{ GCodeLine gline; this->parse_line(line.c_str(), gline, callback); }
void parse_file(const std::string &file, callback_t callback);
#if ENABLE_VALIDATE_CUSTOM_GCODE
void quit_parsing() { m_parsing = false; }
#else
void quit_parsing_file() { m_parsing_file = false; }
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
float& x() { return m_position[X]; }
float x() const { return m_position[X]; }
@ -156,11 +148,7 @@ private:
char m_extrusion_axis;
float m_position[NUM_AXES];
bool m_verbose;
#if ENABLE_VALIDATE_CUSTOM_GCODE
bool m_parsing{ false };
#else
bool m_parsing_file{ false };
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
};
} /* namespace Slic3r */

View File

@ -4,6 +4,7 @@
#include "Fill/Fill.hpp"
#include "ShortestPath.hpp"
#include "SVG.hpp"
#include "BoundingBox.hpp"
#include <boost/log/trivial.hpp>
@ -258,4 +259,26 @@ void Layer::export_region_fill_surfaces_to_svg_debug(const char *name) const
this->export_region_fill_surfaces_to_svg(debug_out_path("Layer-fill_surfaces-%s-%d.svg", name, idx ++).c_str());
}
BoundingBox get_extents(const LayerRegion &layer_region)
{
BoundingBox bbox;
if (!layer_region.slices.surfaces.empty()) {
bbox = get_extents(layer_region.slices.surfaces.front());
for (auto it = layer_region.slices.surfaces.cbegin() + 1; it != layer_region.slices.surfaces.cend(); ++it)
bbox.merge(get_extents(*it));
}
return bbox;
}
BoundingBox get_extents(const LayerRegionPtrs &layer_regions)
{
BoundingBox bbox;
if (!layer_regions.empty()) {
bbox = get_extents(*layer_regions.front());
for (auto it = layer_regions.begin() + 1; it != layer_regions.end(); ++it)
bbox.merge(get_extents(**it));
}
return bbox;
}
}

View File

@ -211,6 +211,9 @@ inline std::vector<float> zs_from_layers(const LayerContainer &layers)
return zs;
}
extern BoundingBox get_extents(const LayerRegion &layer_region);
extern BoundingBox get_extents(const LayerRegionPtrs &layer_regions);
}
#endif

View File

@ -918,7 +918,6 @@ BoundingBoxf3 ModelObject::instance_bounding_box(size_t instance_idx, bool dont_
// Calculate 2D convex hull of of a projection of the transformed printable volumes into the XY plane.
// This method is cheap in that it does not make any unnecessary copy of the volume meshes.
// This method is used by the auto arrange function.
#if ENABLE_ALLOW_NEGATIVE_Z
Polygon ModelObject::convex_hull_2d(const Transform3d& trafo_instance) const
{
Points pts;
@ -928,33 +927,6 @@ Polygon ModelObject::convex_hull_2d(const Transform3d& trafo_instance) const
}
return Geometry::convex_hull(std::move(pts));
}
#else
Polygon ModelObject::convex_hull_2d(const Transform3d &trafo_instance) const
{
Points pts;
for (const ModelVolume *v : this->volumes)
if (v->is_model_part()) {
Transform3d trafo = trafo_instance * v->get_matrix();
const indexed_triangle_set &its = v->mesh().its;
if (its.vertices.empty()) {
// Using the STL faces.
const stl_file& stl = v->mesh().stl;
for (const stl_facet &facet : stl.facet_start)
for (size_t j = 0; j < 3; ++ j) {
Vec3d p = trafo * facet.vertex[j].cast<double>();
pts.emplace_back(coord_t(scale_(p.x())), coord_t(scale_(p.y())));
}
} else {
// Using the shared vertices should be a bit quicker than using the STL faces.
for (size_t i = 0; i < its.vertices.size(); ++ i) {
Vec3d p = trafo * its.vertices[i].cast<double>();
pts.emplace_back(coord_t(scale_(p.x())), coord_t(scale_(p.y())));
}
}
}
return Geometry::convex_hull(std::move(pts));
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
void ModelObject::center_around_origin(bool include_modifiers)
{
@ -969,19 +941,12 @@ void ModelObject::center_around_origin(bool include_modifiers)
this->origin_translation += shift;
}
#if ENABLE_ALLOW_NEGATIVE_Z
void ModelObject::ensure_on_bed(bool allow_negative_z)
{
const double min_z = get_min_z();
if (!allow_negative_z || min_z > SINKING_Z_THRESHOLD)
translate_instances({ 0.0, 0.0, -min_z });
}
#else
void ModelObject::ensure_on_bed()
{
translate_instances({ 0.0, 0.0, -get_min_z() });
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
void ModelObject::translate_instances(const Vec3d& vector)
{
@ -1734,6 +1699,10 @@ size_t ModelVolume::split(unsigned int max_extruders)
for (TriangleMesh *mesh : meshptrs) {
mesh->repair();
if (mesh->empty())
// Repair may have removed unconnected triangles, thus emptying the mesh.
continue;
if (idx == 0)
{
this->set_mesh(std::move(*mesh));
@ -1927,20 +1896,10 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const
Vec3d rotation = get_rotation();
rotation.z() = 0.;
Transform3d trafo_instance =
#if ENABLE_ALLOW_NEGATIVE_Z
Geometry::assemble_transform(get_offset().z() * Vec3d::UnitZ(), rotation,
get_scaling_factor(), get_mirror());
#else
Geometry::assemble_transform(Vec3d::Zero(), rotation,
get_scaling_factor(), get_mirror());
#endif // ENABLE_ALLOW_NEGATIVE_Z
Geometry::assemble_transform(get_offset().z() * Vec3d::UnitZ(), rotation, get_scaling_factor(), get_mirror());
Polygon p = get_object()->convex_hull_2d(trafo_instance);
#if !ENABLE_ALLOW_NEGATIVE_Z
assert(!p.points.empty());
#endif // !ENABLE_ALLOW_NEGATIVE_Z
// if (!p.points.empty()) {
// Polygons pp{p};
// pp = p.simplify(scaled<double>(SIMPLIFY_TOLERANCE_MM));
@ -1958,14 +1917,16 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const
indexed_triangle_set FacetsAnnotation::get_facets(const ModelVolume& mv, EnforcerBlockerType type) const
{
TriangleSelector selector(mv.mesh());
selector.deserialize(m_data);
// Reset of TriangleSelector is done inside TriangleSelector's constructor, so we don't need it to perform it again in deserialize().
selector.deserialize(m_data, false);
return selector.get_facets(type);
}
indexed_triangle_set FacetsAnnotation::get_facets_strict(const ModelVolume& mv, EnforcerBlockerType type) const
{
TriangleSelector selector(mv.mesh());
selector.deserialize(m_data);
// Reset of TriangleSelector is done inside TriangleSelector's constructor, so we don't need it to perform it again in deserialize().
selector.deserialize(m_data, false);
return selector.get_facets_strict(type);
}

View File

@ -322,12 +322,8 @@ public:
Polygon convex_hull_2d(const Transform3d &trafo_instance) const;
void center_around_origin(bool include_modifiers = true);
#if ENABLE_ALLOW_NEGATIVE_Z
void ensure_on_bed(bool allow_negative_z = false);
#else
void ensure_on_bed();
#endif // ENABLE_ALLOW_NEGATIVE_Z
void translate_instances(const Vec3d& vector);
void translate_instance(size_t instance_idx, const Vec3d& vector);
void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
@ -1176,9 +1172,7 @@ void check_model_ids_validity(const Model &model);
void check_model_ids_equal(const Model &model1, const Model &model2);
#endif /* NDEBUG */
#if ENABLE_ALLOW_NEGATIVE_Z
static const float SINKING_Z_THRESHOLD = -0.001f;
#endif // ENABLE_ALLOW_NEGATIVE_Z
} // namespace Slic3r

View File

@ -12,6 +12,8 @@
#include <boost/log/trivial.hpp>
#include <tbb/parallel_for.h>
#include <mutex>
#include <boost/thread/lock_guard.hpp>
namespace Slic3r {
struct ColoredLine {
@ -38,6 +40,10 @@ struct segment_traits<Slic3r::ColoredLine> {
};
}
//#define MMU_SEGMENTATION_DEBUG_GRAPH
//#define MMU_SEGMENTATION_DEBUG_REGIONS
//#define MMU_SEGMENTATION_DEBUG_INPUT
namespace Slic3r {
// Assumes that is at most same projected_l length or below than projection_l
@ -74,7 +80,7 @@ struct PaintedLine
struct PaintedLineVisitor
{
PaintedLineVisitor(const EdgeGrid::Grid &grid, std::vector<PaintedLine> &painted_lines, size_t reserve) : grid(grid), painted_lines(painted_lines)
PaintedLineVisitor(const EdgeGrid::Grid &grid, std::vector<PaintedLine> &painted_lines, std::mutex &painted_lines_mutex, size_t reserve) : grid(grid), painted_lines(painted_lines), painted_lines_mutex(painted_lines_mutex)
{
painted_lines_set.reserve(reserve);
}
@ -115,8 +121,11 @@ struct PaintedLineVisitor
if ((line_to_test_projected.a - grid_line.a).cast<double>().squaredNorm() > (line_to_test_projected.b - grid_line.a).cast<double>().squaredNorm())
line_to_test_projected.reverse();
painted_lines.push_back({it_contour_and_segment->first, it_contour_and_segment->second, line_to_test_projected, this->color});
painted_lines_set.insert(*it_contour_and_segment);
{
boost::lock_guard<std::mutex> lock(painted_lines_mutex);
painted_lines.push_back({it_contour_and_segment->first, it_contour_and_segment->second, line_to_test_projected, this->color});
}
}
}
}
@ -127,6 +136,7 @@ struct PaintedLineVisitor
const EdgeGrid::Grid &grid;
std::vector<PaintedLine> &painted_lines;
std::mutex &painted_lines_mutex;
Line line_to_test;
std::unordered_set<std::pair<size_t, size_t>, boost::hash<std::pair<size_t, size_t>>> painted_lines_set;
int color = -1;
@ -136,14 +146,14 @@ struct PaintedLineVisitor
static inline const double append_threshold2 = Slic3r::sqr(append_threshold);
};
static std::vector<ColoredLine> to_colored_lines(const Polygon &polygon, int color)
static std::vector<ColoredLine> to_colored_lines(const EdgeGrid::Contour &contour, int color)
{
std::vector<ColoredLine> lines;
if (polygon.points.size() > 2) {
lines.reserve(polygon.points.size());
for (auto it = polygon.points.begin(); it != polygon.points.end() - 1; ++it)
if (contour.num_segments() > 2) {
lines.reserve(contour.num_segments());
for (auto it = contour.begin(); it != contour.end() - 1; ++it)
lines.push_back({Line(*it, *(it + 1)), color});
lines.push_back({Line(polygon.points.back(), polygon.points.front()), color});
lines.push_back({Line(contour.back(), contour.front()), color});
}
return lines;
}
@ -238,7 +248,9 @@ static std::vector<ColoredLine> colorize_line(const Line & line_to_
std::vector<PaintedLine> &painted_lines)
{
std::vector<PaintedLine> internal_painted;
for (size_t line_idx = start_idx; line_idx <= end_idx; ++line_idx) { internal_painted.emplace_back(painted_lines[line_idx]); }
for (size_t line_idx = start_idx; line_idx <= end_idx; ++line_idx)
internal_painted.emplace_back(painted_lines[line_idx]);
const int filter_eps_value = scale_(0.1f);
std::vector<PaintedLine> filtered_lines;
filtered_lines.emplace_back(internal_painted.front());
@ -324,18 +336,18 @@ static std::vector<ColoredLine> colorize_line(const Line & line_to_
if (line_1.line.length() <= scale_(0.2)) line_1.color = line_0.color;
}
std::vector<ColoredLine> colored_lines_simpl;
colored_lines_simpl.emplace_back(final_lines.front());
std::vector<ColoredLine> colored_lines_simple;
colored_lines_simple.emplace_back(final_lines.front());
for (size_t line_idx = 1; line_idx < final_lines.size(); ++line_idx) {
const ColoredLine &line_0 = final_lines[line_idx];
if (colored_lines_simpl.back().color == line_0.color)
colored_lines_simpl.back().line.b = line_0.line.b;
if (colored_lines_simple.back().color == line_0.color)
colored_lines_simple.back().line.b = line_0.line.b;
else
colored_lines_simpl.emplace_back(line_0);
colored_lines_simple.emplace_back(line_0);
}
final_lines = colored_lines_simpl;
final_lines = colored_lines_simple;
if (final_lines.size() > 1) {
if (final_lines.front().color != final_lines[1].color && final_lines.front().line.length() <= scale_(0.2)) {
@ -354,13 +366,12 @@ static std::vector<ColoredLine> colorize_line(const Line & line_to_
return final_lines;
}
static std::vector<ColoredLine> colorize_polygon(const Polygon &poly, const size_t start_idx, const size_t end_idx, std::vector<PaintedLine> &painted_lines)
static std::vector<ColoredLine> colorize_polygon(const EdgeGrid::Contour &contour, const size_t start_idx, const size_t end_idx, std::vector<PaintedLine> &painted_lines)
{
std::vector<ColoredLine> new_lines;
Lines lines = poly.lines();
new_lines.reserve(end_idx - start_idx + 1);
for (size_t idx = 0; idx < painted_lines[start_idx].line_idx; ++idx)
new_lines.emplace_back(ColoredLine{lines[idx], 0});
new_lines.emplace_back(ColoredLine{contour.get_segment(idx), 0});
for (size_t first_idx = start_idx; first_idx <= end_idx; ++first_idx) {
size_t second_idx = first_idx;
@ -368,18 +379,18 @@ static std::vector<ColoredLine> colorize_polygon(const Polygon &poly, const size
--second_idx;
assert(painted_lines[first_idx].line_idx == painted_lines[second_idx].line_idx);
std::vector<ColoredLine> lines_c_line = colorize_line(lines[painted_lines[first_idx].line_idx], first_idx, second_idx, painted_lines);
std::vector<ColoredLine> lines_c_line = colorize_line(contour.get_segment(painted_lines[first_idx].line_idx), first_idx, second_idx, painted_lines);
new_lines.insert(new_lines.end(), lines_c_line.begin(), lines_c_line.end());
if (second_idx + 1 <= end_idx)
for (size_t idx = painted_lines[second_idx].line_idx + 1; idx < painted_lines[second_idx + 1].line_idx; ++idx)
new_lines.emplace_back(ColoredLine{lines[idx], 0});
new_lines.emplace_back(ColoredLine{contour.get_segment(idx), 0});
first_idx = second_idx;
}
for (size_t idx = painted_lines[end_idx].line_idx + 1; idx < poly.size(); ++idx)
new_lines.emplace_back(ColoredLine{lines[idx], 0});
for (size_t idx = painted_lines[end_idx].line_idx + 1; idx < contour.num_segments(); ++idx)
new_lines.emplace_back(ColoredLine{contour.get_segment(idx), 0});
for (size_t line_idx = 2; line_idx < new_lines.size(); ++line_idx) {
const ColoredLine &line_0 = new_lines[line_idx - 2];
@ -456,15 +467,16 @@ static std::vector<ColoredLine> colorize_polygon(const Polygon &poly, const size
return new_lines;
}
static std::vector<std::vector<ColoredLine>> colorize_polygons(const Polygons &polygons, std::vector<PaintedLine> &painted_lines)
static std::vector<std::vector<ColoredLine>> colorize_polygons(const std::vector<EdgeGrid::Contour> &contours, std::vector<PaintedLine> &painted_lines)
{
const size_t start_idx = 0;
const size_t end_idx = painted_lines.size() - 1;
std::vector<std::vector<ColoredLine>> new_polygons;
new_polygons.reserve(contours.size());
for (size_t idx = 0; idx < painted_lines[start_idx].contour_idx; ++idx)
new_polygons.emplace_back(to_colored_lines(polygons[idx], 0));
new_polygons.emplace_back(to_colored_lines(contours[idx], 0));
for (size_t first_idx = start_idx; first_idx <= end_idx; ++first_idx) {
size_t second_idx = first_idx;
@ -473,18 +485,17 @@ static std::vector<std::vector<ColoredLine>> colorize_polygons(const Polygons &p
--second_idx;
assert(painted_lines[first_idx].contour_idx == painted_lines[second_idx].contour_idx);
std::vector<ColoredLine> polygon_c = colorize_polygon(polygons[painted_lines[first_idx].contour_idx], first_idx, second_idx, painted_lines);
new_polygons.emplace_back(polygon_c);
new_polygons.emplace_back(colorize_polygon(contours[painted_lines[first_idx].contour_idx], first_idx, second_idx, painted_lines));
if (second_idx + 1 <= end_idx)
for (size_t idx = painted_lines[second_idx].contour_idx + 1; idx < painted_lines[second_idx + 1].contour_idx; ++idx)
new_polygons.emplace_back(to_colored_lines(polygons[idx], 0));
new_polygons.emplace_back(to_colored_lines(contours[idx], 0));
first_idx = second_idx;
}
for (size_t idx = painted_lines[end_idx].contour_idx + 1; idx < polygons.size(); ++idx)
new_polygons.emplace_back(to_colored_lines(polygons[idx], 0));
for (size_t idx = painted_lines[end_idx].contour_idx + 1; idx < contours.size(); ++idx)
new_polygons.emplace_back(to_colored_lines(contours[idx], 0));
return new_polygons;
}
@ -507,7 +518,6 @@ struct MMU_Graph
size_t to_idx;
int color;
ARC_TYPE type;
bool used{false};
bool operator==(const Arc &rhs) const { return (from_idx == rhs.from_idx) && (to_idx == rhs.to_idx) && (color == rhs.color) && (type == rhs.type); }
bool operator!=(const Arc &rhs) const { return !operator==(rhs); }
@ -515,15 +525,16 @@ struct MMU_Graph
struct Node
{
Point point;
std::list<MMU_Graph::Arc> neighbours;
Point point;
std::list<size_t> arc_idxs;
void remove_edge(const size_t to_idx)
void remove_edge(const size_t to_idx, MMU_Graph &graph)
{
for (auto arc_it = this->neighbours.begin(); arc_it != this->neighbours.end(); ++arc_it) {
if (arc_it->to_idx == to_idx) {
assert(arc_it->type != ARC_TYPE::BORDER);
this->neighbours.erase(arc_it);
for (auto arc_it = this->arc_idxs.begin(); arc_it != this->arc_idxs.end(); ++arc_it) {
MMU_Graph::Arc &arc = graph.arcs[*arc_it];
if (arc.to_idx == to_idx) {
assert(arc.type != ARC_TYPE::BORDER);
this->arc_idxs.erase(arc_it);
break;
}
}
@ -539,8 +550,8 @@ struct MMU_Graph
void remove_edge(const size_t from_idx, const size_t to_idx)
{
nodes[from_idx].remove_edge(to_idx);
nodes[to_idx].remove_edge(from_idx);
nodes[from_idx].remove_edge(to_idx, *this);
nodes[to_idx].remove_edge(from_idx, *this);
}
[[nodiscard]] size_t get_global_index(const size_t poly_idx, const size_t point_idx) const { return polygon_idx_offset[poly_idx] + point_idx; }
@ -548,42 +559,55 @@ struct MMU_Graph
void append_edge(const size_t &from_idx, const size_t &to_idx, int color = -1, ARC_TYPE type = ARC_TYPE::NON_BORDER)
{
// Don't append duplicate edges between the same nodes.
for (const MMU_Graph::Arc &arc : this->nodes[from_idx].neighbours)
if (arc.to_idx == to_idx)
for (const size_t &arc_idx : this->nodes[from_idx].arc_idxs)
if (arcs[arc_idx].to_idx == to_idx)
return;
for (const MMU_Graph::Arc &arc : this->nodes[to_idx].neighbours)
if (arc.to_idx == to_idx)
for (const size_t &arc_idx : this->nodes[to_idx].arc_idxs)
if (arcs[arc_idx].to_idx == to_idx)
return;
this->nodes[from_idx].neighbours.push_back({from_idx, to_idx, color, type});
this->nodes[to_idx].neighbours.push_back({to_idx, from_idx, color, type});
this->nodes[from_idx].arc_idxs.push_back(this->arcs.size());
this->arcs.push_back({from_idx, to_idx, color, type});
this->arcs.push_back({to_idx, from_idx, color, type});
// Always insert only one directed arc for the input polygons.
// Two directed arcs in both directions are inserted if arcs aren't between points of the input polygons.
if (type == ARC_TYPE::NON_BORDER) {
this->nodes[to_idx].arc_idxs.push_back(this->arcs.size());
this->arcs.push_back({to_idx, from_idx, color, type});
}
}
// Ignoring arcs in the opposite direction
MMU_Graph::Arc get_arc(size_t idx) { return this->arcs[idx * 2]; }
// It assumes that between points of the input polygons is always only one directed arc,
// with the same direction as lines of the input polygon.
[[nodiscard]] MMU_Graph::Arc get_border_arc(size_t idx) const {
assert(idx < this->all_border_points);
return this->arcs[idx];
}
[[nodiscard]] size_t nodes_count() const { return this->nodes.size(); }
void remove_nodes_with_one_arc()
{
std::queue<size_t> update_queue;
for (const MMU_Graph::Node &node : this->nodes)
if (node.neighbours.size() == 1) update_queue.emplace(&node - &this->nodes.front());
for (const MMU_Graph::Node &node : this->nodes) {
size_t node_idx = &node - &this->nodes.front();
// Skip nodes that represent points of input polygons.
if (node.arc_idxs.size() == 1 && node_idx >= this->all_border_points)
update_queue.emplace(&node - &this->nodes.front());
}
while (!update_queue.empty()) {
size_t node_from_idx = update_queue.front();
MMU_Graph::Node &node_from = this->nodes[update_queue.front()];
update_queue.pop();
if (node_from.neighbours.empty())
if (node_from.arc_idxs.empty())
continue;
assert(node_from.neighbours.size() == 1);
size_t node_to_idx = node_from.neighbours.front().to_idx;
assert(node_from.arc_idxs.size() == 1);
size_t node_to_idx = arcs[node_from.arc_idxs.front()].to_idx;
MMU_Graph::Node &node_to = this->nodes[node_to_idx];
this->remove_edge(node_from_idx, node_to_idx);
if (node_to.neighbours.size() == 1)
if (node_to.arc_idxs.size() == 1 && node_to_idx >= this->all_border_points)
update_queue.emplace(node_to_idx);
}
}
@ -660,17 +684,17 @@ struct MMU_Graph
vertex.color(-1);
Point vertex_point = mk_point(vertex);
const Point &first_point = this->nodes[this->get_arc(vertex.incident_edge()->cell()->source_index()).from_idx].point;
const Point &second_point = this->nodes[this->get_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx].point;
const Point &first_point = this->nodes[this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx].point;
const Point &second_point = this->nodes[this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx].point;
if (vertex_equal_to_point(&vertex, first_point)) {
assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
vertex.color(this->get_arc(vertex.incident_edge()->cell()->source_index()).from_idx);
vertex.color(this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx);
} else if (vertex_equal_to_point(&vertex, second_point)) {
assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
vertex.color(this->get_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx);
vertex.color(this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx);
} else if (bbox.contains(vertex_point)) {
if (auto [contour_pt, c_dist_sqr] = closest_contour_point.find(vertex_point); contour_pt != nullptr && c_dist_sqr < 3 * SCALED_EPSILON) {
vertex.color(this->get_global_index(contour_pt->m_contour_idx, contour_pt->m_point_idx));
@ -684,6 +708,35 @@ struct MMU_Graph
}
}
}
void garbage_collect()
{
std::vector<int> nodes_map(this->nodes.size(), -1);
int nodes_count = 0;
size_t arcs_count = 0;
for (const MMU_Graph::Node &node : this->nodes)
if (size_t node_idx = &node - &this->nodes.front(); !node.arc_idxs.empty()) {
nodes_map[node_idx] = nodes_count++;
arcs_count += node.arc_idxs.size();
}
std::vector<MMU_Graph::Node> new_nodes;
std::vector<MMU_Graph::Arc> new_arcs;
new_nodes.reserve(nodes_count);
new_arcs.reserve(arcs_count);
for (const MMU_Graph::Node &node : this->nodes)
if (size_t node_idx = &node - &this->nodes.front(); nodes_map[node_idx] >= 0) {
new_nodes.push_back({node.point});
for (const size_t &arc_idx : node.arc_idxs) {
const Arc &arc = this->arcs[arc_idx];
new_nodes.back().arc_idxs.emplace_back(new_arcs.size());
new_arcs.push_back({size_t(nodes_map[arc.from_idx]), size_t(nodes_map[arc.to_idx]), arc.color, arc.type});
}
}
this->nodes = std::move(new_nodes);
this->arcs = std::move(new_arcs);
}
};
static inline void mark_processed(const voronoi_diagram<double>::const_edge_iterator &edge_iterator)
@ -825,7 +878,7 @@ static MMU_Graph build_graph(size_t layer_idx, const std::vector<std::vector<Col
Point contour_intersection;
if (line_intersection_with_epsilon(contour_line.line, edge_line, &contour_intersection)) {
const MMU_Graph::Arc &graph_arc = graph.get_arc(edge_it->cell()->source_index());
const MMU_Graph::Arc &graph_arc = graph.get_border_arc(edge_it->cell()->source_index());
const size_t from_idx = (edge_it->vertex1() != nullptr) ? edge_it->vertex1()->color() : edge_it->vertex0()->color();
size_t to_idx = ((contour_line.line.a - contour_intersection).cast<double>().squaredNorm() <
(contour_line.line.b - contour_intersection).cast<double>().squaredNorm()) ?
@ -859,12 +912,12 @@ static MMU_Graph build_graph(size_t layer_idx, const std::vector<std::vector<Col
if (edge_it->vertex1()->color() < graph.nodes_count() && !graph.is_vertex_on_contour(edge_it->vertex1())) {
Line contour_line_twin = lines_colored[edge_it->twin()->cell()->source_index()].line;
if (line_intersection_with_epsilon(contour_line_twin, edge_line, &intersection)) {
const MMU_Graph::Arc &graph_arc = graph.get_arc(edge_it->twin()->cell()->source_index());
const MMU_Graph::Arc &graph_arc = graph.get_border_arc(edge_it->twin()->cell()->source_index());
const size_t to_idx_l = is_point_closer_to_beginning_of_line(contour_line_twin, intersection) ? graph_arc.from_idx :
graph_arc.to_idx;
graph.append_edge(edge_it->vertex1()->color(), to_idx_l);
} else if (line_intersection_with_epsilon(contour_line, edge_line, &intersection)) {
const MMU_Graph::Arc &graph_arc = graph.get_arc(edge_it->cell()->source_index());
const MMU_Graph::Arc &graph_arc = graph.get_border_arc(edge_it->cell()->source_index());
const size_t to_idx_l = is_point_closer_to_beginning_of_line(contour_line, intersection) ? graph_arc.from_idx : graph_arc.to_idx;
graph.append_edge(edge_it->vertex1()->color(), to_idx_l);
}
@ -912,27 +965,25 @@ static MMU_Graph build_graph(size_t layer_idx, const std::vector<std::vector<Col
Line second_part(intersection, real_v1);
if (!has_same_color(contour_line_prev, colored_line)) {
if (points_inside(contour_line_prev.line, contour_line, first_part.b)) {
graph.append_edge(edge_it->vertex0()->color(), graph.get_arc(edge_it->cell()->source_index()).from_idx);
}
if (points_inside(contour_line_prev.line, contour_line, second_part.b)) {
graph.append_edge(edge_it->vertex1()->color(), graph.get_arc(edge_it->cell()->source_index()).from_idx);
}
if (points_inside(contour_line_prev.line, contour_line, first_part.b))
graph.append_edge(edge_it->vertex0()->color(), graph.get_border_arc(edge_it->cell()->source_index()).from_idx);
if (points_inside(contour_line_prev.line, contour_line, second_part.b))
graph.append_edge(edge_it->vertex1()->color(), graph.get_border_arc(edge_it->cell()->source_index()).from_idx);
}
} else {
const size_t int_point_idx = graph.get_arc(edge_it->cell()->source_index()).to_idx;
const size_t int_point_idx = graph.get_border_arc(edge_it->cell()->source_index()).to_idx;
const Point int_point = graph.nodes[int_point_idx].point;
const Line first_part(int_point, real_v0);
const Line second_part(int_point, real_v1);
if (!has_same_color(contour_line_next, colored_line)) {
if (points_inside(contour_line, contour_line_next.line, first_part.b)) {
if (points_inside(contour_line, contour_line_next.line, first_part.b))
graph.append_edge(edge_it->vertex0()->color(), int_point_idx);
}
if (points_inside(contour_line, contour_line_next.line, second_part.b)) {
if (points_inside(contour_line, contour_line_next.line, second_part.b))
graph.append_edge(edge_it->vertex1()->color(), int_point_idx);
}
}
}
}
@ -974,13 +1025,15 @@ static inline Polygon to_polygon(const Lines &lines)
// It iterates through all nodes on the border between two different colors, and from this point,
// start selection always left most edges for every node to construct CCW polygons.
// Assumes that graph is planar (without self-intersection edges)
static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(MMU_Graph &graph)
static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(const MMU_Graph &graph)
{
std::vector<bool> used_arcs(graph.arcs.size(), false);
// When there is no next arc, then is returned original_arc or edge with is marked as used
auto get_next = [&graph](const Line &process_line, MMU_Graph::Arc &original_arc) -> MMU_Graph::Arc & {
std::vector<std::pair<MMU_Graph::Arc *, double>> sorted_arcs;
for (MMU_Graph::Arc &arc : graph.nodes[original_arc.to_idx].neighbours) {
if (graph.nodes[arc.to_idx].point == process_line.a || arc.used)
auto get_next = [&graph, &used_arcs](const Line &process_line, const MMU_Graph::Arc &original_arc) -> const MMU_Graph::Arc & {
std::vector<std::pair<const MMU_Graph::Arc *, double>> sorted_arcs;
for (const size_t &arc_idx : graph.nodes[original_arc.to_idx].arc_idxs) {
const MMU_Graph::Arc &arc = graph.arcs[arc_idx];
if (graph.nodes[arc.to_idx].point == process_line.a || used_arcs[arc_idx])
continue;
assert(original_arc.to_idx == arc.from_idx);
@ -995,11 +1048,11 @@ static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(MMU_Grap
}
std::sort(sorted_arcs.begin(), sorted_arcs.end(),
[](std::pair<MMU_Graph::Arc *, double> &l, std::pair<MMU_Graph::Arc *, double> &r) -> bool { return l.second < r.second; });
[](std::pair<const MMU_Graph::Arc *, double> &l, std::pair<const MMU_Graph::Arc *, double> &r) -> bool { return l.second < r.second; });
// Try to return left most edge witch is unused
for (auto &sorted_arc : sorted_arcs)
if (!sorted_arc.first->used)
if (size_t arc_idx = sorted_arc.first - &graph.arcs.front(); !used_arcs[arc_idx])
return *sorted_arc.first;
if (sorted_arcs.empty())
@ -1008,35 +1061,39 @@ static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(MMU_Grap
return *(sorted_arcs.front().first);
};
auto all_arc_used = [&used_arcs](const MMU_Graph::Node &node) -> bool {
return std::all_of(node.arc_idxs.cbegin(), node.arc_idxs.cend(), [&used_arcs](const size_t &arc_idx) -> bool { return used_arcs[arc_idx]; });
};
std::vector<std::pair<Polygon, size_t>> polygons_segments;
for (MMU_Graph::Node &node : graph.nodes)
for (MMU_Graph::Arc &arc : node.neighbours)
arc.used = false;
for (size_t node_idx = 0; node_idx < graph.all_border_points; ++node_idx) {
MMU_Graph::Node &node = graph.nodes[node_idx];
const MMU_Graph::Node &node = graph.nodes[node_idx];
for (const size_t &arc_idx : node.arc_idxs) {
const MMU_Graph::Arc &arc = graph.arcs[arc_idx];
if (arc.type == MMU_Graph::ARC_TYPE::NON_BORDER || used_arcs[arc_idx])continue;
for (MMU_Graph::Arc &arc : node.neighbours) {
if (arc.type == MMU_Graph::ARC_TYPE::NON_BORDER || arc.used) continue;
Line process_line(node.point, graph.nodes[arc.to_idx].point);
arc.used = true;
used_arcs[arc_idx] = true;
Lines face_lines;
face_lines.emplace_back(process_line);
Point start_p = process_line.a;
Line p_vec = process_line;
MMU_Graph::Arc *p_arc = &arc;
Line p_vec = process_line;
const MMU_Graph::Arc *p_arc = &arc;
do {
MMU_Graph::Arc &next = get_next(p_vec, *p_arc);
face_lines.emplace_back(Line(graph.nodes[next.from_idx].point, graph.nodes[next.to_idx].point));
if (next.used) break;
const MMU_Graph::Arc &next = get_next(p_vec, *p_arc);
size_t next_arc_idx = &next - &graph.arcs.front();
face_lines.emplace_back(graph.nodes[next.from_idx].point, graph.nodes[next.to_idx].point);
if (used_arcs[next_arc_idx])
break;
next.used = true;
p_vec = Line(graph.nodes[next.from_idx].point, graph.nodes[next.to_idx].point);
p_arc = &next;
} while (graph.nodes[p_arc->to_idx].point != start_p);
used_arcs[next_arc_idx] = true;
p_vec = Line(graph.nodes[next.from_idx].point, graph.nodes[next.to_idx].point);
p_arc = &next;
} while (graph.nodes[p_arc->to_idx].point != start_p || !all_arc_used(graph.nodes[p_arc->to_idx]));
Polygon poly = to_polygon(face_lines);
if (poly.is_counter_clockwise() && poly.is_valid())
@ -1049,20 +1106,19 @@ static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(MMU_Grap
// Used in remove_multiple_edges_in_vertices()
// Returns length of edge with is connected to contour. To this length is include other edges with follows it if they are almost straight (with the
// tolerance of 15) And also if node between two subsequent edges is connected only to these two edges.
static inline double compute_edge_length(MMU_Graph &graph, size_t start_idx, MMU_Graph::Arc &start_edge)
static inline double compute_edge_length(const MMU_Graph &graph, const size_t start_idx, const size_t &start_arc_idx)
{
for (MMU_Graph::Node &node : graph.nodes)
for (MMU_Graph::Arc &arc : node.neighbours)
arc.used = false;
assert(start_arc_idx < graph.arcs.size());
std::vector<bool> used_arcs(graph.arcs.size(), false);
start_edge.used = true;
MMU_Graph::Arc *arc = &start_edge;
size_t idx = start_idx;
double line_total_length = Line(graph.nodes[idx].point, graph.nodes[arc->to_idx].point).length();
while (graph.nodes[arc->to_idx].neighbours.size() == 2) {
used_arcs[start_arc_idx] = true;
const MMU_Graph::Arc *arc = &graph.arcs[start_arc_idx];
size_t idx = start_idx;
double line_total_length = (graph.nodes[arc->to_idx].point - graph.nodes[idx].point).cast<double>().norm();;
while (graph.nodes[arc->to_idx].arc_idxs.size() == 2) {
bool found = false;
for (MMU_Graph::Arc &arc_n : graph.nodes[arc->to_idx].neighbours) {
if (arc_n.type == MMU_Graph::ARC_TYPE::NON_BORDER && !arc_n.used && arc_n.to_idx != idx) {
for (const size_t &arc_idx : graph.nodes[arc->to_idx].arc_idxs) {
if (const MMU_Graph::Arc &arc_n = graph.arcs[arc_idx]; arc_n.type == MMU_Graph::ARC_TYPE::NON_BORDER && !used_arcs[arc_idx] && arc_n.to_idx != idx) {
Line first_line(graph.nodes[idx].point, graph.nodes[arc->to_idx].point);
Line second_line(graph.nodes[arc->to_idx].point, graph.nodes[arc_n.to_idx].point);
@ -1080,8 +1136,8 @@ static inline double compute_edge_length(MMU_Graph &graph, size_t start_idx, MMU
idx = arc->to_idx;
arc = &arc_n;
line_total_length += Line(graph.nodes[idx].point, graph.nodes[arc->to_idx].point).length();
arc_n.used = true;
line_total_length += (graph.nodes[arc->to_idx].point - graph.nodes[idx].point).cast<double>().norm();
used_arcs[arc_idx] = true;
found = true;
break;
}
@ -1104,11 +1160,12 @@ static void remove_multiple_edges_in_vertices(MMU_Graph &graph, const std::vecto
size_t second_idx = graph.get_global_index(poly_idx, (colored_segment.second + 1) % graph.polygon_sizes[poly_idx]);
Line seg_line(graph.nodes[first_idx].point, graph.nodes[second_idx].point);
if (graph.nodes[first_idx].neighbours.size() >= 3) {
if (graph.nodes[first_idx].arc_idxs.size() >= 3) {
std::vector<std::pair<MMU_Graph::Arc *, double>> arc_to_check;
for (MMU_Graph::Arc &n_arc : graph.nodes[first_idx].neighbours) {
for (const size_t &arc_idx : graph.nodes[first_idx].arc_idxs) {
MMU_Graph::Arc &n_arc = graph.arcs[arc_idx];
if (n_arc.type == MMU_Graph::ARC_TYPE::NON_BORDER) {
double total_len = compute_edge_length(graph, first_idx, n_arc);
double total_len = compute_edge_length(graph, first_idx, arc_idx);
arc_to_check.emplace_back(&n_arc, total_len);
}
}
@ -1478,18 +1535,18 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
LayerColorStat out;
const Layer &layer = *layers[layer_idx];
for (const LayerRegion *region : layer.regions())
if (const PrintRegionConfig &config = region->region().config();
if (const PrintRegionConfig &config = region->region().config();
// color_idx == 0 means "don't know" extruder aka the underlying extruder.
// As this region may split existing regions, we collect statistics over all regions for color_idx == 0.
color_idx == 0 || config.perimeter_extruder == int(color_idx)) {
out.extrusion_width = std::max<float>(out.extrusion_width, config.perimeter_extrusion_width);
out.top_solid_layers = std::max<float>(out.top_solid_layers, config.top_solid_layers);
out.bottom_solid_layers = std::max<float>(out.bottom_solid_layers, config.bottom_solid_layers);
out.small_region_threshold = config.gap_fill_enabled.value && config.gap_fill_speed.value > 0 ?
// Gap fill enabled. Enable a single line of 1/2 extrusion width.
0.5 * config.perimeter_extrusion_width :
// Gap fill disabled. Enable two lines slightly overlapping.
config.perimeter_extrusion_width + 0.7f * Flow::rounded_rectangle_extrusion_spacing(config.perimeter_extrusion_width, layer.height);
out.extrusion_width = std::max<float>(out.extrusion_width, float(config.perimeter_extrusion_width));
out.top_solid_layers = std::max<int>(out.top_solid_layers, config.top_solid_layers);
out.bottom_solid_layers = std::max<int>(out.bottom_solid_layers, config.bottom_solid_layers);
out.small_region_threshold = config.gap_fill_enabled.value && config.gap_fill_speed.value > 0 ?
// Gap fill enabled. Enable a single line of 1/2 extrusion width.
0.5f * float(config.perimeter_extrusion_width) :
// Gap fill disabled. Enable two lines slightly overlapping.
float(config.perimeter_extrusion_width) + 0.7f * Flow::rounded_rectangle_extrusion_spacing(float(config.perimeter_extrusion_width), float(layer.height));
out.small_region_threshold = scaled<float>(out.small_region_threshold * 0.5f);
++ out.num_regions;
}
@ -1603,14 +1660,70 @@ static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_la
return segmented_regions_merged;
}
#ifdef MMU_SEGMENTATION_DEBUG_REGIONS
static void export_regions_to_svg(const std::string &path, const std::vector<std::pair<ExPolygon, size_t>> &regions, const ExPolygons &lslices)
{
const std::vector<std::string> colors = {"blue", "cyan", "red", "orange", "magenta", "pink", "purple", "yellow"};
coordf_t stroke_width = scale_(0.05);
BoundingBox bbox = get_extents(lslices);
bbox.offset(scale_(1.));
::Slic3r::SVG svg(path.c_str(), bbox);
svg.draw_outline(lslices, "green", "lime", stroke_width);
for (const std::pair<ExPolygon, size_t> &region : regions) {
int region_color = region.second;
if (region_color >= 0 && region_color < int(colors.size()))
svg.draw(region.first, colors[region_color]);
else
svg.draw(region.first, "black");
}
}
#endif // MMU_SEGMENTATION_DEBUG_REGIONS
#ifdef MMU_SEGMENTATION_DEBUG_GRAPH
static void export_graph_to_svg(const std::string &path, const MMU_Graph &graph, const ExPolygons &lslices)
{
const std::vector<std::string> colors = {"blue", "cyan", "red", "orange", "magenta", "pink", "purple", "green", "yellow"};
coordf_t stroke_width = scale_(0.05);
BoundingBox bbox = get_extents(lslices);
bbox.offset(scale_(1.));
::Slic3r::SVG svg(path.c_str(), bbox);
for (const MMU_Graph::Node &node : graph.nodes)
for (const size_t &arc_idx : node.arc_idxs) {
const MMU_Graph::Arc &arc = graph.arcs[arc_idx];
Line arc_line(node.point, graph.nodes[arc.to_idx].point);
if (arc.type == MMU_Graph::ARC_TYPE::BORDER && arc.color >= 0 && arc.color < int(colors.size()))
svg.draw(arc_line, colors[arc.color], stroke_width);
else
svg.draw(arc_line, "black", stroke_width);
}
}
#endif // MMU_SEGMENTATION_DEBUG_GRAPH
#ifdef MMU_SEGMENTATION_DEBUG_INPUT
void export_processed_input_expolygons_to_svg(const std::string &path, const LayerRegionPtrs &regions, const ExPolygons &processed_input_expolygons)
{
coordf_t stroke_width = scale_(0.05);
BoundingBox bbox = get_extents(regions);
bbox.merge(get_extents(processed_input_expolygons));
bbox.offset(scale_(1.));
::Slic3r::SVG svg(path.c_str(), bbox);
for (LayerRegion *region : regions)
svg.draw_outline(region->slices.surfaces, "blue", "cyan", stroke_width);
svg.draw_outline(processed_input_expolygons, "red", "pink", stroke_width);
}
#endif // MMU_SEGMENTATION_DEBUG_INPUT
std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
{
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions(print_object.layers().size());
std::vector<std::vector<PaintedLine>> painted_lines(print_object.layers().size());
std::array<std::mutex, 64> painted_lines_mutex;
std::vector<EdgeGrid::Grid> edge_grids(print_object.layers().size());
const ConstLayerPtrsAdaptor layers = print_object.layers();
std::vector<ExPolygons> input_expolygons(layers.size());
std::vector<Polygons> input_polygons(layers.size());
throw_on_cancel_callback();
@ -1636,86 +1749,99 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
// This consequently leads to issues with the extraction of colored segments by function extract_colored_segments.
// Calling expolygons_simplify fixed these issues.
input_expolygons[layer_idx] = smooth_outward(expolygons_simplify(offset_ex(ex_polygons, -10.f * float(SCALED_EPSILON)), 5 * SCALED_EPSILON), 10 * coord_t(SCALED_EPSILON));
input_polygons[layer_idx] = to_polygons(input_expolygons[layer_idx]);
#ifdef MMU_SEGMENTATION_DEBUG_INPUT
{
static int iRun = 0;
export_processed_input_expolygons_to_svg(debug_out_path("mm-input-%d-%d.svg", layer_idx, iRun++), layers[layer_idx]->regions(), input_expolygons[layer_idx]);
}
#endif // MMU_SEGMENTATION_DEBUG_INPUT
}
}); // end of parallel_for
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - slices preparation in parallel - end";
for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) {
throw_on_cancel_callback();
BoundingBox bbox(get_extents(input_polygons[layer_idx]));
BoundingBox bbox(get_extents(layers[layer_idx]->regions()));
bbox.merge(get_extents(input_expolygons[layer_idx]));
// Projected triangles may slightly exceed the input polygons.
bbox.offset(20 * SCALED_EPSILON);
edge_grids[layer_idx].set_bbox(bbox);
edge_grids[layer_idx].create(input_polygons[layer_idx], coord_t(scale_(10.)));
edge_grids[layer_idx].create(input_expolygons[layer_idx], coord_t(scale_(10.)));
}
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - projection of painted triangles - begin";
for (const ModelVolume *mv : print_object.model_object()->volumes) {
const size_t num_extruders = print_object.print()->config().nozzle_diameter.size() + 1;
for (size_t extruder_idx = 1; extruder_idx < num_extruders; ++extruder_idx) {
throw_on_cancel_callback();
const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
if (!mv->is_model_part() || custom_facets.indices.empty())
continue;
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_extruders), [&mv, &print_object, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
for (size_t extruder_idx = range.begin(); extruder_idx < range.end(); ++extruder_idx) {
throw_on_cancel_callback();
const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
if (!mv->is_model_part() || custom_facets.indices.empty())
continue;
const Transform3f tr = print_object.trafo().cast<float>() * mv->get_matrix().cast<float>();
for (size_t facet_idx = 0; facet_idx < custom_facets.indices.size(); ++facet_idx) {
float min_z = std::numeric_limits<float>::max();
float max_z = std::numeric_limits<float>::lowest();
const Transform3f tr = print_object.trafo().cast<float>() * mv->get_matrix().cast<float>();
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
for (size_t facet_idx = range.begin(); facet_idx < range.end(); ++facet_idx) {
float min_z = std::numeric_limits<float>::max();
float max_z = std::numeric_limits<float>::lowest();
std::array<Vec3f, 3> facet;
for (int p_idx = 0; p_idx < 3; ++p_idx) {
facet[p_idx] = tr * custom_facets.vertices[custom_facets.indices[facet_idx](p_idx)];
max_z = std::max(max_z, facet[p_idx].z());
min_z = std::min(min_z, facet[p_idx].z());
}
std::array<Vec3f, 3> facet;
for (int p_idx = 0; p_idx < 3; ++p_idx) {
facet[p_idx] = tr * custom_facets.vertices[custom_facets.indices[facet_idx](p_idx)];
max_z = std::max(max_z, facet[p_idx].z());
min_z = std::min(min_z, facet[p_idx].z());
}
// Sort the vertices by z-axis for simplification of projected_facet on slices
std::sort(facet.begin(), facet.end(), [](const Vec3f &p1, const Vec3f &p2) { return p1.z() < p2.z(); });
// Sort the vertices by z-axis for simplification of projected_facet on slices
std::sort(facet.begin(), facet.end(), [](const Vec3f &p1, const Vec3f &p2) { return p1.z() < p2.z(); });
// Find lowest slice not below the triangle.
auto first_layer = std::upper_bound(print_object.layers().begin(), print_object.layers().end(), float(min_z - EPSILON),
[](float z, const Layer *l1) { return z < l1->slice_z; });
auto last_layer = std::upper_bound(print_object.layers().begin(), print_object.layers().end(), float(max_z + EPSILON),
[](float z, const Layer *l1) { return z < l1->slice_z; });
--last_layer;
// Find lowest slice not below the triangle.
auto first_layer = std::upper_bound(print_object.layers().begin(), print_object.layers().end(), float(min_z - EPSILON),
[](float z, const Layer *l1) { return z < l1->slice_z; });
auto last_layer = std::upper_bound(print_object.layers().begin(), print_object.layers().end(), float(max_z + EPSILON),
[](float z, const Layer *l1) { return z < l1->slice_z; });
--last_layer;
for (auto layer_it = first_layer; layer_it != (last_layer + 1); ++layer_it) {
const Layer *layer = *layer_it;
size_t layer_idx = layer_it - print_object.layers().begin();
if (facet[0].z() > layer->slice_z || layer->slice_z > facet[2].z())
continue;
for (auto layer_it = first_layer; layer_it != (last_layer + 1); ++layer_it) {
const Layer *layer = *layer_it;
size_t layer_idx = layer_it - print_object.layers().begin();
if (input_expolygons[layer_idx].empty() || facet[0].z() > layer->slice_z || layer->slice_z > facet[2].z())
continue;
// https://kandepet.com/3d-printing-slicing-3d-objects/
float t = (float(layer->slice_z) - facet[0].z()) / (facet[2].z() - facet[0].z());
Vec3f line_start_f = facet[0] + t * (facet[2] - facet[0]);
Vec3f line_end_f;
// https://kandepet.com/3d-printing-slicing-3d-objects/
float t = (float(layer->slice_z) - facet[0].z()) / (facet[2].z() - facet[0].z());
Vec3f line_start_f = facet[0] + t * (facet[2] - facet[0]);
Vec3f line_end_f;
if (facet[1].z() > layer->slice_z) {
// [P0, P2] a [P0, P1]
float t1 = (float(layer->slice_z) - facet[0].z()) / (facet[1].z() - facet[0].z());
line_end_f = facet[0] + t1 * (facet[1] - facet[0]);
} else {
// [P0, P2] a [P1, P2]
float t2 = (float(layer->slice_z) - facet[1].z()) / (facet[2].z() - facet[1].z());
line_end_f = facet[1] + t2 * (facet[2] - facet[1]);
if (facet[1].z() > layer->slice_z) {
// [P0, P2] and [P0, P1]
float t1 = (float(layer->slice_z) - facet[0].z()) / (facet[1].z() - facet[0].z());
line_end_f = facet[0] + t1 * (facet[1] - facet[0]);
} else {
// [P0, P2] and [P1, P2]
float t2 = (float(layer->slice_z) - facet[1].z()) / (facet[2].z() - facet[1].z());
line_end_f = facet[1] + t2 * (facet[2] - facet[1]);
}
Point line_start(scale_(line_start_f.x()), scale_(line_start_f.y()));
Point line_end(scale_(line_end_f.x()), scale_(line_end_f.y()));
line_start -= print_object.center_offset();
line_end -= print_object.center_offset();
size_t mutex_idx = layer_idx & 0x3F;
assert(mutex_idx < painted_lines_mutex.size());
PaintedLineVisitor visitor(edge_grids[layer_idx], painted_lines[layer_idx], painted_lines_mutex[mutex_idx], 16);
visitor.line_to_test.a = line_start;
visitor.line_to_test.b = line_end;
visitor.color = int(extruder_idx);
edge_grids[layer_idx].visit_cells_intersecting_line(line_start, line_end, visitor);
}
}
Point line_start(scale_(line_start_f.x()), scale_(line_start_f.y()));
Point line_end(scale_(line_end_f.x()), scale_(line_end_f.y()));
line_start -= print_object.center_offset();
line_end -= print_object.center_offset();
PaintedLineVisitor visitor(edge_grids[layer_idx], painted_lines[layer_idx], 16);
visitor.reset();
visitor.line_to_test.a = line_start;
visitor.line_to_test.b = line_end;
visitor.color = int(extruder_idx);
edge_grids[layer_idx].visit_cells_intersecting_line(line_start, line_end, visitor);
}
});
}
}
});
}
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - projection of painted triangles - end";
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - painted layers count: "
@ -1725,8 +1851,8 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
tbb::parallel_for(tbb::blocked_range<size_t>(0, print_object.layers().size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
throw_on_cancel_callback();
auto comp = [&input_polygons, layer_idx](const PaintedLine &first, const PaintedLine &second) {
Point first_start_p = input_polygons[layer_idx][first.contour_idx][first.line_idx];
auto comp = [&edge_grids, layer_idx](const PaintedLine &first, const PaintedLine &second) {
Point first_start_p = edge_grids[layer_idx].contours()[first.contour_idx].segment_start(first.line_idx);
return first.contour_idx < second.contour_idx ||
(first.contour_idx == second.contour_idx &&
(first.line_idx < second.line_idx ||
@ -1740,13 +1866,28 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
std::vector<PaintedLine> &painted_lines_single = painted_lines[layer_idx];
if (!painted_lines_single.empty()) {
std::vector<std::vector<ColoredLine>> color_poly = colorize_polygons(input_polygons[layer_idx], painted_lines_single);
std::vector<std::vector<ColoredLine>> color_poly = colorize_polygons(edge_grids[layer_idx].contours(), painted_lines_single);
MMU_Graph graph = build_graph(layer_idx, color_poly);
remove_multiple_edges_in_vertices(graph, color_poly);
graph.remove_nodes_with_one_arc();
#ifdef MMU_SEGMENTATION_DEBUG_GRAPH
{
static int iRun = 0;
export_graph_to_svg(debug_out_path("mm-graph-final-%d-%d.svg", layer_idx, iRun++), graph, input_expolygons[layer_idx]);
}
#endif // MMU_SEGMENTATION_DEBUG_GRAPH
std::vector<std::pair<Polygon, size_t>> segmentation = extract_colored_segments(graph);
for (std::pair<Polygon, size_t> &region : segmentation)
segmented_regions[layer_idx].emplace_back(std::move(region));
#ifdef MMU_SEGMENTATION_DEBUG_REGIONS
{
static int iRun = 0;
export_regions_to_svg(debug_out_path("mm-regions-sides-%d-%d.svg", layer_idx, iRun++), segmented_regions[layer_idx], input_expolygons[layer_idx]);
}
#endif // MMU_SEGMENTATION_DEBUG_REGIONS
}
}
}); // end of parallel_for
@ -1765,6 +1906,14 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged = merge_segmented_layers(segmented_regions, std::move(top_and_bottom_layers), throw_on_cancel_callback);
throw_on_cancel_callback();
#ifdef MMU_SEGMENTATION_DEBUG_REGIONS
{
static int iRun = 0;
for (size_t layer_idx = 0; layer_idx < print_object.layers().size(); ++layer_idx)
export_regions_to_svg(debug_out_path("mm-regions-merged-%d-%d.svg", layer_idx, iRun++), segmented_regions_merged[layer_idx], input_expolygons[layer_idx]);
}
#endif // MMU_SEGMENTATION_DEBUG_REGIONS
return segmented_regions_merged;
}

View File

@ -625,17 +625,13 @@ const std::vector<std::string>& Preset::sla_printer_options()
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name) :
m_type(type),
m_edited_preset(type, "", false),
#if ENABLE_PROJECT_DIRTY_STATE
m_saved_preset(type, "", false),
#endif // ENABLE_PROJECT_DIRTY_STATE
m_idx_selected(0)
{
// Insert just the default preset.
this->add_default_preset(keys, defaults, default_name);
m_edited_preset.config.apply(m_presets.front().config);
#if ENABLE_PROJECT_DIRTY_STATE
update_saved_preset_from_current_preset();
#endif // ENABLE_PROJECT_DIRTY_STATE
}
void PresetCollection::reset(bool delete_files)
@ -816,10 +812,8 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
// The source config may contain keys from many possible preset types. Just copy those that relate to this preset.
this->get_edited_preset().config.apply_only(combined_config, keys, true);
this->update_dirty();
#if ENABLE_PROJECT_DIRTY_STATE
update_saved_preset_from_current_preset();
#endif // ENABLE_PROJECT_DIRTY_STATE
assert(this->get_edited_preset().is_dirty);
assert(this->get_edited_preset().is_dirty);
return std::make_pair(&(*it), this->get_edited_preset().is_dirty);
}
if (inherits.empty()) {
@ -1229,9 +1223,7 @@ Preset& PresetCollection::select_preset(size_t idx)
idx = first_visible_idx();
m_idx_selected = idx;
m_edited_preset = m_presets[idx];
#if ENABLE_PROJECT_DIRTY_STATE
update_saved_preset_from_current_preset();
#endif // ENABLE_PROJECT_DIRTY_STATE
bool default_visible = ! m_default_suppressed || m_idx_selected < m_num_default_presets;
for (size_t i = 0; i < m_num_default_presets; ++i)
m_presets[i].is_visible = default_visible;

View File

@ -370,10 +370,8 @@ public:
Preset& get_edited_preset() { return m_edited_preset; }
const Preset& get_edited_preset() const { return m_edited_preset; }
#if ENABLE_PROJECT_DIRTY_STATE
// Return the last saved preset.
const Preset& get_saved_preset() const { return m_saved_preset; }
#endif // ENABLE_PROJECT_DIRTY_STATE
// Return vendor of the first parent profile, for which the vendor is defined, or null if such profile does not exist.
PresetWithVendorProfile get_preset_with_vendor_profile(const Preset &preset) const;
@ -394,15 +392,11 @@ public:
// Return a preset by an index. If the preset is active, a temporary copy is returned.
Preset& preset(size_t idx) { return (idx == m_idx_selected) ? m_edited_preset : m_presets[idx]; }
const Preset& preset(size_t idx) const { return const_cast<PresetCollection*>(this)->preset(idx); }
#if ENABLE_PROJECT_DIRTY_STATE
void discard_current_changes() {
m_presets[m_idx_selected].reset_dirty();
m_edited_preset = m_presets[m_idx_selected];
update_saved_preset_from_current_preset();
}
#else
void discard_current_changes() { m_presets[m_idx_selected].reset_dirty(); m_edited_preset = m_presets[m_idx_selected]; }
#endif // ENABLE_PROJECT_DIRTY_STATE
// Return a preset by its name. If the preset is active, a temporary copy is returned.
// If a preset is not found by its name, null is returned.
@ -477,7 +471,6 @@ public:
std::vector<std::string> current_different_from_parent_options(const bool deep_compare = false) const
{ return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), deep_compare); }
#if ENABLE_PROJECT_DIRTY_STATE
// Compare the content of get_saved_preset() with get_edited_preset() configs, return true if they differ.
bool saved_is_dirty() const { return !this->saved_dirty_options().empty(); }
// Compare the content of get_saved_preset() with get_edited_preset() configs, return the list of keys where they differ.
@ -485,7 +478,6 @@ public:
{ return dirty_options(&this->get_edited_preset(), &this->get_saved_preset(), deep_compare); }
// Copy edited preset into saved preset.
void update_saved_preset_from_current_preset() { m_saved_preset = m_edited_preset; }
#endif // ENABLE_PROJECT_DIRTY_STATE
// Return a sorted list of system preset names.
// Used for validating the "inherits" flag when importing user's config bundles.
@ -574,10 +566,8 @@ private:
std::map<std::string, std::string> m_map_system_profile_renamed;
// Initially this preset contains a copy of the selected preset. Later on, this copy may be modified by the user.
Preset m_edited_preset;
#if ENABLE_PROJECT_DIRTY_STATE
// Contains a copy of the last saved selected preset.
Preset m_saved_preset;
#endif // ENABLE_PROJECT_DIRTY_STATE
// Selected preset.
size_t m_idx_selected;

View File

@ -373,7 +373,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly
// FIXME: Arrangement has different parameters for offsetting (jtMiter, limit 2)
// which causes that the warning will be showed after arrangement with the
// appropriate object distance. Even if I set this to jtMiter the warning still shows up.
#if ENABLE_ALLOW_NEGATIVE_Z
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
offset(print_object->model_object()->convex_hull_2d(
Geometry::assemble_transform({ 0.0, 0.0, model_instance0->get_offset().z() }, model_instance0->get_rotation(), model_instance0->get_scaling_factor(), model_instance0->get_mirror())),
@ -381,15 +380,6 @@ bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Poly
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)),
jtRound, scale_(0.1)).front());
#else
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
offset(print_object->model_object()->convex_hull_2d(
Geometry::assemble_transform(Vec3d::Zero(), model_instance0->get_rotation(), model_instance0->get_scaling_factor(), model_instance0->get_mirror())),
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)),
jtRound, float(scale_(0.1))).front());
#endif // ENABLE_ALLOW_NEGATIVE_Z
}
// Make a copy, so it may be rotated for instances.
Polygon convex_hull0 = it_convex_hull->second;

View File

@ -1279,7 +1279,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back("Teacup");
def->enum_labels.push_back("MakerWare (MakerBot)");
def->enum_labels.push_back("Marlin (legacy)");
def->enum_labels.push_back("Marlin Firmware");
def->enum_labels.push_back("Marlin 2");
def->enum_labels.push_back("Sailfish (MakerBot)");
def->enum_labels.push_back("Mach3/LinuxCNC");
def->enum_labels.push_back("Machinekit");
@ -1457,6 +1457,7 @@ void PrintConfigDef::init_fff_params()
def->tooltip = L("Maximum width of a segmented region. Zero disables this feature.");
def->sidetext = L("mm (zero to disable)");
def->min = 0;
def->category = L("Advanced");
def->mode = comExpert;
def->set_default_value(new ConfigOptionFloat(0.f));

View File

@ -1600,15 +1600,9 @@ PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &defau
void PrintObject::update_slicing_parameters()
{
#if ENABLE_ALLOW_NEGATIVE_Z
if (!m_slicing_params.valid)
m_slicing_params = SlicingParameters::create_from_config(
this->print()->config(), m_config, this->model_object()->bounding_box().max.z(), this->object_extruders());
#else
if (! m_slicing_params.valid)
m_slicing_params = SlicingParameters::create_from_config(
this->print()->config(), m_config, unscale<double>(this->height()), this->object_extruders());
#endif // ENABLE_ALLOW_NEGATIVE_Z
}
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full_config, const ModelObject& model_object, float object_max_z)
@ -1670,7 +1664,6 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
updated = true;
}
#if ENABLE_ALLOW_NEGATIVE_Z
// Verify the layer_height_profile.
if (!layer_height_profile.empty() &&
// Must not be of even length.
@ -1678,15 +1671,6 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
// Last entry must be at the top of the object.
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_max) > 1e-3))
layer_height_profile.clear();
#else
// Verify the layer_height_profile.
if (! layer_height_profile.empty() &&
// Must not be of even length.
((layer_height_profile.size() & 1) != 0 ||
// Last entry must be at the top of the object.
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_height()) > 1e-3))
layer_height_profile.clear();
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (layer_height_profile.empty()) {
//layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_config_ranges, model_object.volumes);

View File

@ -112,7 +112,7 @@ InteriorPtr generate_interior(const TriangleMesh & mesh,
const HollowingConfig &hc,
const JobController & ctl)
{
static const double MIN_OVERSAMPL = 3.;
static const double MIN_OVERSAMPL = 3.5;
static const double MAX_OVERSAMPL = 8.;
// I can't figure out how to increase the grid resolution through openvdb

View File

@ -323,6 +323,7 @@ private:
{
support_tree_ptr = sla::SupportTree::create(*this, ctl);
tree_mesh = TriangleMesh{support_tree_ptr->retrieve_mesh(sla::MeshType::Support)};
tree_mesh.require_shared_vertices();
return support_tree_ptr;
}

View File

@ -10,8 +10,6 @@
#define ENABLE_SELECTION_DEBUG_OUTPUT 0
// Renders a small sphere in the center of the bounding box of the current selection when no gizmo is active
#define ENABLE_RENDER_SELECTION_CENTER 0
// Shows an imgui dialog with render related data
#define ENABLE_RENDER_STATISTICS 0
// Shows an imgui dialog with camera related data
#define ENABLE_CAMERA_STATISTICS 0
// Render the picking pass instead of the main scene (use [T] key to toggle between regular rendering and picking pass only rendering)
@ -26,6 +24,8 @@
#define ENABLE_GCODE_VIEWER_STATISTICS 0
// Enable G-Code viewer comparison between toolpaths height and width detected from gcode and calculated at gcode generation
#define ENABLE_GCODE_VIEWER_DATA_CHECKING 0
// Enable project dirty state manager debug window
#define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW 0
// Enable rendering of objects using environment map
@ -41,33 +41,12 @@
//====================
#define ENABLE_2_4_0_ALPHA0 1
// Enable reload from disk command for 3mf files
#define ENABLE_RELOAD_FROM_DISK_FOR_3MF (1 && ENABLE_2_4_0_ALPHA0)
// Enable showing gcode line numbers in preview horizontal slider
#define ENABLE_GCODE_LINES_ID_IN_H_SLIDER (1 && ENABLE_2_4_0_ALPHA0)
// Enable validation of custom gcode against gcode processor reserved keywords
#define ENABLE_VALIDATE_CUSTOM_GCODE (1 && ENABLE_2_4_0_ALPHA0)
// Enable showing a imgui window containing gcode in preview
#define ENABLE_GCODE_WINDOW (1 && ENABLE_2_4_0_ALPHA0)
// Enable exporting lines M73 for remaining time to next printer stop to gcode
#define ENABLE_EXTENDED_M73_LINES (1 && ENABLE_VALIDATE_CUSTOM_GCODE)
// Enable a modified version of automatic downscale on load of objects too big
#define ENABLE_MODIFIED_DOWNSCALE_ON_LOAD_OBJECTS_TOO_BIG (1 && ENABLE_2_4_0_ALPHA0)
// Enable scrollable legend in preview
#define ENABLE_SCROLLABLE_LEGEND (1 && ENABLE_2_4_0_ALPHA0)
// Enable visualization of start gcode as regular toolpaths
#define ENABLE_START_GCODE_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0)
// Enable visualization of seams in preview
#define ENABLE_SEAMS_VISUALIZATION (1 && ENABLE_2_4_0_ALPHA0)
// Enable project dirty state manager
#define ENABLE_PROJECT_DIRTY_STATE (1 && ENABLE_2_4_0_ALPHA0)
// Enable project dirty state manager debug window
#define ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW (0 && ENABLE_PROJECT_DIRTY_STATE)
// Enable to push object instances under the bed
#define ENABLE_ALLOW_NEGATIVE_Z (1 && ENABLE_2_4_0_ALPHA0)
#define DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA (1 && ENABLE_ALLOW_NEGATIVE_Z)
// Enable delayed rendering of transparent volumes
#define ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING (1 && ENABLE_2_4_0_ALPHA0)
// Enable the fix of importing color print view from gcode files into GCodeViewer
#define ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER (1 && ENABLE_2_4_0_ALPHA0)
// Enable drawing contours, at cut level, for sinking volumes
#define ENABLE_SINKING_CONTOURS (1 && ENABLE_2_4_0_ALPHA0)
#endif // _prusaslicer_technologies_h_

View File

@ -698,27 +698,29 @@ struct EdgeToFace {
bool operator<(const EdgeToFace &other) const { return vertex_low < other.vertex_low || (vertex_low == other.vertex_low && vertex_high < other.vertex_high); }
};
template<typename ThrowOnCancelCallback>
template<typename FaceFilter, typename ThrowOnCancelCallback>
static std::vector<EdgeToFace> create_edge_map(
const indexed_triangle_set &its, ThrowOnCancelCallback throw_on_cancel)
const indexed_triangle_set &its, FaceFilter face_filter, ThrowOnCancelCallback throw_on_cancel)
{
std::vector<EdgeToFace> edges_map;
edges_map.assign(its.indices.size() * 3, EdgeToFace());
edges_map.reserve(its.indices.size() * 3);
for (uint32_t facet_idx = 0; facet_idx < its.indices.size(); ++ facet_idx)
for (int i = 0; i < 3; ++ i) {
EdgeToFace &e2f = edges_map[facet_idx * 3 + i];
e2f.vertex_low = its.indices[facet_idx][i];
e2f.vertex_high = its.indices[facet_idx][(i + 1) % 3];
e2f.face = facet_idx;
// 1 based indexing, to be always strictly positive.
e2f.face_edge = i + 1;
if (e2f.vertex_low > e2f.vertex_high) {
// Sort the vertices
std::swap(e2f.vertex_low, e2f.vertex_high);
// and make the face_edge negative to indicate a flipped edge.
e2f.face_edge = - e2f.face_edge;
if (face_filter(facet_idx))
for (int i = 0; i < 3; ++ i) {
edges_map.push_back({});
EdgeToFace &e2f = edges_map.back();
e2f.vertex_low = its.indices[facet_idx][i];
e2f.vertex_high = its.indices[facet_idx][(i + 1) % 3];
e2f.face = facet_idx;
// 1 based indexing, to be always strictly positive.
e2f.face_edge = i + 1;
if (e2f.vertex_low > e2f.vertex_high) {
// Sort the vertices
std::swap(e2f.vertex_low, e2f.vertex_high);
// and make the face_edge negative to indicate a flipped edge.
e2f.face_edge = - e2f.face_edge;
}
}
}
throw_on_cancel();
std::sort(edges_map.begin(), edges_map.end());
@ -727,12 +729,12 @@ static std::vector<EdgeToFace> create_edge_map(
// Map from a face edge to a unique edge identifier or -1 if no neighbor exists.
// Two neighbor faces share a unique edge identifier even if they are flipped.
template<typename ThrowOnCancelCallback>
static inline std::vector<Vec3i> its_face_edge_ids_impl(const indexed_triangle_set &its, ThrowOnCancelCallback throw_on_cancel)
template<typename FaceFilter, typename ThrowOnCancelCallback>
static inline std::vector<Vec3i> its_face_edge_ids_impl(const indexed_triangle_set &its, FaceFilter face_filter, ThrowOnCancelCallback throw_on_cancel)
{
std::vector<Vec3i> out(its.indices.size(), Vec3i(-1, -1, -1));
std::vector<EdgeToFace> edges_map = create_edge_map(its, throw_on_cancel);
std::vector<EdgeToFace> edges_map = create_edge_map(its, face_filter, throw_on_cancel);
// Assign a unique common edge id to touching triangle edges.
int num_edges = 0;
@ -780,12 +782,17 @@ static inline std::vector<Vec3i> its_face_edge_ids_impl(const indexed_triangle_s
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its)
{
return its_face_edge_ids_impl(its, [](){});
return its_face_edge_ids_impl(its, [](const uint32_t){ return true; }, [](){});
}
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::function<void()> throw_on_cancel_callback)
{
return its_face_edge_ids_impl(its, throw_on_cancel_callback);
return its_face_edge_ids_impl(its, [](const uint32_t){ return true; }, throw_on_cancel_callback);
}
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<bool> &face_mask)
{
return its_face_edge_ids_impl(its, [&face_mask](const uint32_t idx){ return face_mask[idx]; }, [](){});
}
// Having the face neighbors available, assign unique edge IDs to face edges for chaining of polygons over slices.

View File

@ -118,6 +118,7 @@ private:
// Used for chaining slice lines into polygons.
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its);
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::function<void()> throw_on_cancel_callback);
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, const std::vector<bool> &face_mask);
// Having the face neighbors available, assign unique edge IDs to face edges for chaining of polygons over slices.
std::vector<Vec3i> its_face_edge_ids(const indexed_triangle_set &its, std::vector<Vec3i> &face_neighbors, bool assign_unbound_edges = false, int *num_edges = nullptr);

View File

@ -362,6 +362,35 @@ static inline std::vector<IntersectionLines> slice_make_lines(
return lines;
}
template<typename TransformVertex, typename FaceFilter>
static inline IntersectionLines slice_make_lines(
const std::vector<stl_vertex> &mesh_vertices,
const TransformVertex &transform_vertex_fn,
const std::vector<stl_triangle_vertex_indices> &mesh_faces,
const std::vector<Vec3i> &face_edge_ids,
const float plane_z,
FaceFilter face_filter)
{
IntersectionLines lines;
for (int face_idx = 0; face_idx < mesh_faces.size(); ++ face_idx)
if (face_filter(face_idx)) {
const Vec3i &indices = mesh_faces[face_idx];
stl_vertex vertices[3] { transform_vertex_fn(mesh_vertices[indices(0)]), transform_vertex_fn(mesh_vertices[indices(1)]), transform_vertex_fn(mesh_vertices[indices(2)]) };
// find facet extents
const float min_z = fminf(vertices[0].z(), fminf(vertices[1].z(), vertices[2].z()));
const float max_z = fmaxf(vertices[0].z(), fmaxf(vertices[1].z(), vertices[2].z()));
assert(min_z <= plane_z && max_z >= plane_z);
int idx_vertex_lowest = (vertices[1].z() == min_z) ? 1 : ((vertices[2].z() == min_z) ? 2 : 0);
IntersectionLine il;
// Ignore horizontal triangles. Any valid horizontal triangle must have a vertical triangle connected, otherwise the part has zero volume.
if (min_z != max_z && slice_facet(plane_z, vertices, indices, face_edge_ids[face_idx], idx_vertex_lowest, false, il) == FacetSliceType::Slicing) {
assert(il.edge_type != IntersectionLine::FacetEdgeType::Horizontal);
lines.emplace_back(il);
}
}
return lines;
}
// For projecting triangle sets onto slice slabs.
struct SlabLines {
// Intersection lines of a slice with a triangle set, CCW oriented.
@ -1720,6 +1749,69 @@ std::vector<Polygons> slice_mesh(
return layers;
}
// Specialized version for a single slicing plane only, running on a single thread.
Polygons slice_mesh(
const indexed_triangle_set &mesh,
// Unscaled Zs
const float plane_z,
const MeshSlicingParams &params)
{
std::vector<IntersectionLines> lines;
{
bool trafo_identity = is_identity(params.trafo);
Transform3f tf;
std::vector<bool> face_mask(mesh.indices.size(), false);
{
// 1) Mark vertices as below or above the slicing plane.
std::vector<char> vertex_side(mesh.vertices.size(), 0);
if (trafo_identity) {
for (size_t i = 0; i < mesh.vertices.size(); ++ i) {
float z = mesh.vertices[i].z();
char s = z < plane_z ? -1 : z == plane_z ? 0 : 1;
vertex_side[i] = s;
}
} else {
tf = make_trafo_for_slicing(params.trafo);
for (size_t i = 0; i < mesh.vertices.size(); ++ i) {
//FIXME don't need to transform x & y, just Z.
float z = (tf * mesh.vertices[i]).z();
char s = z < plane_z ? -1 : z == plane_z ? 0 : 1;
vertex_side[i] = s;
}
}
// 2) Mark faces crossing the plane.
for (size_t i = 0; i < mesh.indices.size(); ++ i) {
const Vec3i &face = mesh.indices[i];
int sides[3] = { vertex_side[face(0)], vertex_side[face(1)], vertex_side[face(2)] };
face_mask[i] = sides[0] * sides[1] <= 0 || sides[1] * sides[2] <= 0 || sides[0] * sides[2] <= 0;
}
}
// 3) Calculate face neighbors for just the faces in face_mask.
std::vector<Vec3i> face_edge_ids = its_face_edge_ids(mesh, face_mask);
// 4) Slice "face_mask" triangles, collect line segments.
// It likely is not worthwile to copy the vertices. Apply the transformation in place.
if (trafo_identity) {
lines.emplace_back(slice_make_lines(
mesh.vertices, [](const Vec3f &p) { return Vec3f(scaled<float>(p.x()), scaled<float>(p.y()), p.z()); },
mesh.indices, face_edge_ids, plane_z, [&face_mask](int face_idx) { return face_mask[face_idx]; }));
} else {
// Transform the vertices, scale up in XY, not in Z.
lines.emplace_back(slice_make_lines(mesh.vertices, [tf](const Vec3f& p) { return tf * p; }, mesh.indices, face_edge_ids, plane_z,
[&face_mask](int face_idx) { return face_mask[face_idx]; }));
}
}
// 5) Chain the line segments.
std::vector<Polygons> layers = make_loops(lines, params, [](){});
assert(layers.size() == 1);
return layers.front();
}
std::vector<ExPolygons> slice_mesh_ex(
const indexed_triangle_set &mesh,
const std::vector<float> &zs,

View File

@ -52,6 +52,12 @@ std::vector<Polygons> slice_mesh(
const MeshSlicingParams &params,
std::function<void()> throw_on_cancel = []{});
// Specialized version for a single slicing plane only, running on a single thread.
Polygons slice_mesh(
const indexed_triangle_set &mesh,
const float plane_z,
const MeshSlicingParams &params);
std::vector<ExPolygons> slice_mesh_ex(
const indexed_triangle_set &mesh,
const std::vector<float> &zs,

View File

@ -228,7 +228,7 @@ void TriangleSelector::seed_fill_select_triangles(const Vec3f &hit, int facet_st
}
}
void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out) const
void TriangleSelector::precompute_all_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out, std::vector<Vec3i> &neighbors_propagated_out) const
{
assert(facet_idx < int(m_triangles.size()));
@ -236,7 +236,8 @@ void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_
if (!tr->valid())
return;
neighbors_out[facet_idx] = neighbors_propagated;
neighbors_out[facet_idx] = neighbors;
neighbors_propagated_out[facet_idx] = neighbors_propagated;
if (tr->is_split()) {
assert(this->verify_triangle_neighbors(*tr, neighbors));
@ -247,67 +248,51 @@ void TriangleSelector::precompute_all_level_neighbors_recursive(const int facet_
assert(tr->children[i] < int(m_triangles.size()));
// Recursion, deep first search over the children of this triangle.
// All children of this triangle were created by splitting a single source triangle of the original mesh.
this->precompute_all_level_neighbors_recursive(tr->children[i], this->child_neighbors(*tr, neighbors, i), this->child_neighbors_propagated(*tr, neighbors_propagated, i), neighbors_out);
this->precompute_all_neighbors_recursive(tr->children[i], this->child_neighbors(*tr, neighbors, i),
this->child_neighbors_propagated(*tr, neighbors_propagated, i), neighbors_out,
neighbors_propagated_out);
}
}
}
}
std::vector<Vec3i> TriangleSelector::precompute_all_level_neighbors() const
std::pair<std::vector<Vec3i>, std::vector<Vec3i>> TriangleSelector::precompute_all_neighbors() const
{
std::vector<Vec3i> neighbors(m_triangles.size(), Vec3i(-1, -1, -1));
std::vector<Vec3i> neighbors_propagated(m_triangles.size(), Vec3i(-1, -1, -1));
for (int facet_idx = 0; facet_idx < this->m_orig_size_indices; ++facet_idx) {
neighbors[facet_idx] = root_neighbors(*m_mesh, facet_idx);
neighbors[facet_idx] = root_neighbors(*m_mesh, facet_idx);
neighbors_propagated[facet_idx] = neighbors[facet_idx];
assert(this->verify_triangle_neighbors(m_triangles[facet_idx], neighbors[facet_idx]));
if (m_triangles[facet_idx].is_split())
this->precompute_all_level_neighbors_recursive(facet_idx, neighbors[facet_idx], neighbors[facet_idx], neighbors);
this->precompute_all_neighbors_recursive(facet_idx, neighbors[facet_idx], neighbors_propagated[facet_idx], neighbors, neighbors_propagated);
}
return neighbors;
return std::make_pair(std::move(neighbors), std::move(neighbors_propagated));
}
bool TriangleSelector::are_triangles_touching(const int first_facet_idx, const int second_facet_idx) const
// It appends all triangles that are touching the edge (vertexi, vertexj) of the triangle.
// It doesn't append the triangles that are touching the triangle only by part of the edge that means the triangles are from lower depth.
void TriangleSelector::append_touching_subtriangles(int itriangle, int vertexi, int vertexj, std::vector<int> &touching_subtriangles_out) const
{
std::array<Linef3, 3> sides_facet = {Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[0]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[1]].v.cast<double>()),
Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[1]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[2]].v.cast<double>()),
Linef3(m_vertices[m_triangles[first_facet_idx].verts_idxs[2]].v.cast<double>(), m_vertices[m_triangles[first_facet_idx].verts_idxs[0]].v.cast<double>())};
if (itriangle == -1)
return;
const Vec3d p0 = m_vertices[m_triangles[second_facet_idx].verts_idxs[0]].v.cast<double>();
const Vec3d p1 = m_vertices[m_triangles[second_facet_idx].verts_idxs[1]].v.cast<double>();
const Vec3d p2 = m_vertices[m_triangles[second_facet_idx].verts_idxs[2]].v.cast<double>();
auto process_subtriangle = [this, &itriangle, &vertexi, &vertexj, &touching_subtriangles_out](const int subtriangle_idx) -> void {
assert(subtriangle_idx == -1);
if (!m_triangles[subtriangle_idx].is_split())
touching_subtriangles_out.emplace_back(subtriangle_idx);
else if (int midpoint = this->triangle_midpoint(itriangle, vertexi, vertexj); midpoint != -1)
append_touching_subtriangles(subtriangle_idx, vertexi, midpoint, touching_subtriangles_out);
else
append_touching_subtriangles(subtriangle_idx, vertexi, vertexj, touching_subtriangles_out);
};
for (size_t idx = 0; idx < 3; ++idx)
if (line_alg::distance_to_squared(sides_facet[idx], p0) <= EPSILON && (line_alg::distance_to_squared(sides_facet[idx], p1) <= EPSILON || line_alg::distance_to_squared(sides_facet[idx], p2) <= EPSILON))
return true;
else if (line_alg::distance_to_squared(sides_facet[idx], p1) <= EPSILON && line_alg::distance_to_squared(sides_facet[idx], p2) <= EPSILON)
return true;
std::pair<int, int> touching = this->triangle_subtriangles(itriangle, vertexi, vertexj);
if (touching.first != -1)
process_subtriangle(touching.first);
return false;
}
std::vector<int> TriangleSelector::neighboring_triangles(const int first_facet_idx, const int second_facet_idx, EnforcerBlockerType second_facet_state) const
{
assert(first_facet_idx < int(m_triangles.size()));
const Triangle *tr = &m_triangles[first_facet_idx];
if (!tr->valid())
return {};
if (!tr->is_split() && tr->get_state() == second_facet_state && (are_triangles_touching(second_facet_idx, first_facet_idx) || are_triangles_touching(first_facet_idx, second_facet_idx)))
return {first_facet_idx};
std::vector<int> neighbor_facets_out;
int num_of_children = tr->number_of_split_sides() + 1;
if (num_of_children != 1) {
for (int i = 0; i < num_of_children; ++i) {
assert(i < int(tr->children.size()));
assert(tr->children[i] < int(m_triangles.size()));
if (std::vector<int> neighbor_facets = neighboring_triangles(tr->children[i], second_facet_idx, second_facet_state); !neighbor_facets.empty())
Slic3r::append(neighbor_facets_out, std::move(neighbor_facets));
}
}
return neighbor_facets_out;
if (touching.second != -1)
process_subtriangle(touching.second);
}
void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_start, bool propagate)
@ -326,7 +311,23 @@ void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_
return;
}
std::vector<Vec3i> all_level_neighbors = this->precompute_all_level_neighbors();
auto get_all_touching_triangles = [this](int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated) -> std::vector<int> {
assert(facet_idx != -1 && facet_idx < m_triangles.size());
assert(this->verify_triangle_neighbors(m_triangles[facet_idx], neighbors));
std::vector<int> touching_triangles;
Vec3i vertices = {m_triangles[facet_idx].verts_idxs[0], m_triangles[facet_idx].verts_idxs[1], m_triangles[facet_idx].verts_idxs[2]};
append_touching_subtriangles(neighbors(0), vertices(1), vertices(0), touching_triangles);
append_touching_subtriangles(neighbors(1), vertices(2), vertices(1), touching_triangles);
append_touching_subtriangles(neighbors(2), vertices(0), vertices(2), touching_triangles);
for (int neighbor_idx : neighbors_propagated)
if (neighbor_idx != -1 && !m_triangles[neighbor_idx].is_split())
touching_triangles.emplace_back(neighbor_idx);
return touching_triangles;
};
auto [neighbors, neighbors_propagated] = this->precompute_all_neighbors();
std::vector<bool> visited(m_triangles.size(), false);
std::queue<int> facet_queue;
@ -338,17 +339,14 @@ void TriangleSelector::bucket_fill_select_triangles(const Vec3f& hit, int facet_
if (!visited[current_facet]) {
m_triangles[current_facet].select_by_seed_fill();
for (int neighbor_idx : all_level_neighbors[current_facet]) {
if (neighbor_idx < 0 || visited[neighbor_idx])
std::vector<int> touching_triangles = get_all_touching_triangles(current_facet, neighbors[current_facet], neighbors_propagated[current_facet]);
for(const int tr_idx : touching_triangles) {
if (tr_idx < 0 || visited[tr_idx] || m_triangles[tr_idx].get_state() != start_facet_state)
continue;
if (!m_triangles[neighbor_idx].is_split()) {
if (m_triangles[neighbor_idx].get_state() == start_facet_state)
facet_queue.push(neighbor_idx);
} else {
for (int neighbor_facet_idx : neighboring_triangles(neighbor_idx, current_facet, start_facet_state))
facet_queue.push(neighbor_facet_idx);
}
assert(!m_triangles[tr_idx].is_split());
facet_queue.push(tr_idx);
}
}
@ -437,6 +435,40 @@ int TriangleSelector::neighbor_child(int itriangle, int vertexi, int vertexj, Pa
return itriangle == -1 ? -1 : this->neighbor_child(m_triangles[itriangle], vertexi, vertexj, partition);
}
std::pair<int, int> TriangleSelector::triangle_subtriangles(int itriangle, int vertexi, int vertexj) const
{
return itriangle == -1 ? std::make_pair(-1, -1) : this->triangle_subtriangles(m_triangles[itriangle], vertexi, vertexj);
}
std::pair<int, int> TriangleSelector::triangle_subtriangles(const Triangle &tr, int vertexi, int vertexj)
{
if (tr.number_of_split_sides() == 0)
// If this triangle is not split, then there is no subtriangles touching the edge.
return std::make_pair(-1, -1);
// Find the triangle edge.
int edge = tr.verts_idxs[0] == vertexi ? 0 : tr.verts_idxs[1] == vertexi ? 1 : 2;
assert(tr.verts_idxs[edge] == vertexi);
assert(tr.verts_idxs[next_idx_modulo(edge, 3)] == vertexj);
if (tr.number_of_split_sides() == 1) {
return edge == next_idx_modulo(tr.special_side(), 3) ? std::make_pair(tr.children[0], tr.children[1]) :
std::make_pair(tr.children[edge == tr.special_side() ? 0 : 1], -1);
} else if (tr.number_of_split_sides() == 2) {
return edge == next_idx_modulo(tr.special_side(), 3) ? std::make_pair(tr.children[2], -1) :
edge == tr.special_side() ? std::make_pair(tr.children[0], tr.children[1]) :
std::make_pair(tr.children[2], tr.children[0]);
} else {
assert(tr.number_of_split_sides() == 3);
assert(tr.special_side() == 0);
return edge == 0 ? std::make_pair(tr.children[0], tr.children[1]) :
edge == 1 ? std::make_pair(tr.children[1], tr.children[2]) :
std::make_pair(tr.children[2], tr.children[0]);
}
return std::make_pair(-1, -1);
}
// Return existing midpoint of CCW oriented side (vertexi, vertexj).
// If itriangle == -1 or if the side sharing (vertexi, vertexj) is not split, return -1.
int TriangleSelector::triangle_midpoint(const Triangle &tr, int vertexi, int vertexj) const
@ -524,12 +556,8 @@ Vec3i TriangleSelector::child_neighbors(const Triangle &tr, const Vec3i &neighbo
assert(child_idx >= 0 && child_idx <= tr.number_of_split_sides());
int i = tr.special_side();
int j = i + 1;
if (j >= 3)
j = 0;
int k = j + 1;
if (k >= 3)
k = 0;
int j = next_idx_modulo(i, 3);
int k = next_idx_modulo(j, 3);
Vec3i out;
switch (tr.number_of_split_sides()) {
@ -612,23 +640,28 @@ Vec3i TriangleSelector::child_neighbors(const Triangle &tr, const Vec3i &neighbo
Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec3i &neighbors, int child_idx) const
{
int i = tr.special_side();
int j = i + 1;
if (j >= 3) j = 0;
int k = j + 1;
if (k >= 3) k = 0;
int j = next_idx_modulo(i, 3);
int k = next_idx_modulo(j, 3);
Vec3i out;
auto replace_if_not_exists = [&out](int index_to_replace, int neighbor) {
if (out(index_to_replace) == -1)
out(index_to_replace) = neighbor;
};
switch (tr.number_of_split_sides()) {
case 1:
switch (child_idx) {
case 0:
out(0) = neighbors(i);
out(1) = neighbors(j);
out(1) = this->neighbor_child(neighbors(j), tr.verts_idxs[k], tr.verts_idxs[j], Partition::Second);
replace_if_not_exists(1, neighbors(j));
out(2) = tr.children[1];
break;
default:
assert(child_idx == 1);
out(0) = neighbors(j);
out(0) = this->neighbor_child(neighbors(j), tr.verts_idxs[k], tr.verts_idxs[j], Partition::First);
replace_if_not_exists(0, neighbors(j));
out(1) = neighbors(k);
out(2) = tr.children[0];
break;
@ -638,20 +671,24 @@ Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec
case 2:
switch (child_idx) {
case 0:
out(0) = neighbors(i);
out(0) = this->neighbor_child(neighbors(i), tr.verts_idxs[j], tr.verts_idxs[i], Partition::Second);
replace_if_not_exists(0, neighbors(i));
out(1) = tr.children[1];
out(2) = neighbors(k);
out(2) = this->neighbor_child(neighbors(k), tr.verts_idxs[i], tr.verts_idxs[k], Partition::First);
replace_if_not_exists(2, neighbors(k));
break;
case 1:
assert(child_idx == 1);
out(0) = neighbors(i);
out(0) = this->neighbor_child(neighbors(i), tr.verts_idxs[j], tr.verts_idxs[i], Partition::First);
replace_if_not_exists(0, neighbors(i));
out(1) = tr.children[2];
out(2) = tr.children[0];
break;
default:
assert(child_idx == 2);
out(0) = neighbors(j);
out(1) = neighbors(k);
out(1) = this->neighbor_child(neighbors(k), tr.verts_idxs[i], tr.verts_idxs[k], Partition::Second);
replace_if_not_exists(1, neighbors(k));
out(2) = tr.children[1];
break;
}
@ -661,18 +698,24 @@ Vec3i TriangleSelector::child_neighbors_propagated(const Triangle &tr, const Vec
assert(tr.special_side() == 0);
switch (child_idx) {
case 0:
out(0) = neighbors(0);
out(0) = this->neighbor_child(neighbors(0), tr.verts_idxs[1], tr.verts_idxs[0], Partition::Second);
replace_if_not_exists(0, neighbors(0));
out(1) = tr.children[3];
out(2) = neighbors(2);
out(2) = this->neighbor_child(neighbors(2), tr.verts_idxs[0], tr.verts_idxs[2], Partition::First);
replace_if_not_exists(2, neighbors(2));
break;
case 1:
out(0) = neighbors(0);
out(1) = neighbors(1);
out(0) = this->neighbor_child(neighbors(0), tr.verts_idxs[1], tr.verts_idxs[0], Partition::First);
replace_if_not_exists(0, neighbors(0));
out(1) = this->neighbor_child(neighbors(1), tr.verts_idxs[2], tr.verts_idxs[1], Partition::Second);
replace_if_not_exists(1, neighbors(1));
out(2) = tr.children[3];
break;
case 2:
out(0) = neighbors(1);
out(1) = neighbors(2);
out(0) = this->neighbor_child(neighbors(1), tr.verts_idxs[2], tr.verts_idxs[1], Partition::First);
replace_if_not_exists(0, neighbors(1));
out(1) = this->neighbor_child(neighbors(2), tr.verts_idxs[0], tr.verts_idxs[2], Partition::Second);
replace_if_not_exists(1, neighbors(2));
out(2) = tr.children[3];
break;
default:
@ -886,13 +929,13 @@ void TriangleSelector::undivide_triangle(int facet_idx)
Triangle& tr = m_triangles[facet_idx];
if (tr.is_split()) {
for (int i=0; i<=tr.number_of_split_sides(); ++i) {
for (int i = 0; i <= tr.number_of_split_sides(); ++i) {
int child = tr.children[i];
Triangle &child_tr = m_triangles[child];
assert(child_tr.valid());
undivide_triangle(child);
for (int i = 0; i < 3; ++ i) {
int iv = child_tr.verts_idxs[i];
for (int j = 0; j < 3; ++j) {
int iv = child_tr.verts_idxs[j];
Vertex &v = m_vertices[iv];
assert(v.ref_cnt > 0);
if (-- v.ref_cnt == 0) {
@ -1231,7 +1274,7 @@ void TriangleSelector::get_facets_strict_recursive(
this->get_facets_split_by_tjoints({tr.verts_idxs[0], tr.verts_idxs[1], tr.verts_idxs[2]}, neighbors, out_triangles);
}
void TriangleSelector::get_facets_split_by_tjoints(const Vec3i vertices, const Vec3i neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const
void TriangleSelector::get_facets_split_by_tjoints(const Vec3i &vertices, const Vec3i &neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const
{
// Export this triangle, but first collect the T-joint vertices along its edges.
Vec3i midpoints(
@ -1393,9 +1436,10 @@ std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> TriangleSelector:
return out.data;
}
void TriangleSelector::deserialize(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data)
void TriangleSelector::deserialize(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, bool needs_reset)
{
reset(); // dump any current state
if (needs_reset)
reset(); // dump any current state
// Reserve number of triangles as if each triangle was saved with 4 bits.
// With MMU painting this estimate may be somehow low, but better than nothing.

View File

@ -22,8 +22,8 @@ public:
POINTER
};
[[nodiscard]] std::vector<Vec3i> precompute_all_level_neighbors() const;
void precompute_all_level_neighbors_recursive(const int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out) const;
std::pair<std::vector<Vec3i>, std::vector<Vec3i>> precompute_all_neighbors() const;
void precompute_all_neighbors_recursive(int facet_idx, const Vec3i &neighbors, const Vec3i &neighbors_propagated, std::vector<Vec3i> &neighbors_out, std::vector<Vec3i> &neighbors_normal_out) const;
// Set a limit to the edge length, below which the edge will not be split by select_patch().
// Called by select_patch() internally. Made public for debugging purposes, see TriangleSelectorGUI::render_debug().
@ -37,10 +37,6 @@ public:
[[nodiscard]] int select_unsplit_triangle(const Vec3f &hit, int facet_idx) const;
[[nodiscard]] int select_unsplit_triangle(const Vec3f &hit, int facet_idx, const Vec3i &neighbors) const;
[[nodiscard]] bool are_triangles_touching(int first_facet_idx, int second_facet_idx) const;
[[nodiscard]] std::vector<int> neighboring_triangles(int first_facet_idx, int second_facet_idx, EnforcerBlockerType second_facet_state) const;
// Select all triangles fully inside the circle, subdivide where needed.
void select_patch(const Vec3f &hit, // point where to start
int facet_start, // facet of the original mesh (unsplit) that the hit point belongs to
@ -60,7 +56,7 @@ public:
bool propagate); // if bucket fill is propagated to neighbor faces or if it fills the only facet of the modified mesh that the hit point belongs to.
bool has_facets(EnforcerBlockerType state) const;
static bool has_facets(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, const EnforcerBlockerType test_state);
static bool has_facets(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, EnforcerBlockerType test_state);
int num_facets(EnforcerBlockerType state) const;
// Get facets at a given state. Don't triangulate T-joints.
indexed_triangle_set get_facets(EnforcerBlockerType state) const;
@ -81,7 +77,7 @@ public:
std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> serialize() const;
// Load serialized data. Assumes that correct mesh is loaded.
void deserialize(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data);
void deserialize(const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> &data, bool needs_reset = true);
// For all triangles, remove the flag indicating that the triangle was selected by seed fill.
void seed_fill_unselect_all_triangles();
@ -128,11 +124,11 @@ protected:
bool is_selected_by_seed_fill() const { assert(! is_split()); return m_selected_by_seed_fill; }
// Is this triangle valid or marked to be removed?
bool valid() const throw() { return m_valid; }
bool valid() const noexcept { return m_valid; }
// Get info on how it's split.
bool is_split() const throw() { return number_of_split_sides() != 0; }
int number_of_split_sides() const throw() { return number_of_splits; }
int special_side() const throw() { assert(is_split()); return special_side_idx; }
bool is_split() const noexcept { return number_of_split_sides() != 0; }
int number_of_split_sides() const noexcept { return number_of_splits; }
int special_side() const noexcept { assert(is_split()); return special_side_idx; }
private:
friend TriangleSelector;
@ -205,7 +201,7 @@ private:
void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant.
bool is_pointer_in_triangle(int facet_idx) const;
bool is_edge_inside_cursor(int facet_idx) const;
int push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state = EnforcerBlockerType{0});
int push_triangle(int a, int b, int c, int source_triangle, EnforcerBlockerType state = EnforcerBlockerType{0});
void perform_split(int facet_idx, const Vec3i &neighbors, EnforcerBlockerType old_state);
Vec3i child_neighbors(const Triangle &tr, const Vec3i &neighbors, int child_idx) const;
Vec3i child_neighbors_propagated(const Triangle &tr, const Vec3i &neighbors, int child_idx) const;
@ -221,6 +217,11 @@ private:
int triangle_midpoint(int itriangle, int vertexi, int vertexj) const;
int triangle_midpoint_or_allocate(int itriangle, int vertexi, int vertexj);
static std::pair<int, int> triangle_subtriangles(const Triangle &tr, int vertexi, int vertexj);
std::pair<int, int> triangle_subtriangles(int itriangle, int vertexi, int vertexj) const;
void append_touching_subtriangles(int itriangle, int vertexi, int vertexj, std::vector<int> &touching_subtriangles_out) const;
#ifndef NDEBUG
bool verify_triangle_neighbors(const Triangle& tr, const Vec3i& neighbors) const;
bool verify_triangle_midpoints(const Triangle& tr) const;
@ -231,7 +232,7 @@ private:
const Vec3i &neighbors,
EnforcerBlockerType state,
std::vector<stl_triangle_vertex_indices> &out_triangles) const;
void get_facets_split_by_tjoints(const Vec3i vertices, const Vec3i neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const;
void get_facets_split_by_tjoints(const Vec3i &vertices, const Vec3i &neighbors, std::vector<stl_triangle_vertex_indices> &out_triangles) const;
int m_free_triangles_head { -1 };
int m_free_vertices_head { -1 };

View File

@ -10,9 +10,9 @@
using SignalT = decltype (SIGSEGV);
template<class TryFn, class CatchFn, int N>
void try_catch_signal(const SignalT (&/*sigs*/)[N], TryFn &&/*fn*/, CatchFn &&/*cfn*/)
void try_catch_signal(const SignalT (&/*sigs*/)[N], TryFn &&fn, CatchFn &&/*cfn*/)
{
// TODO
fn();
}
#endif

View File

@ -50,6 +50,9 @@ void set_sys_shapes_dir(const std::string &path);
// Return a full path to the system shapes gallery directory.
const std::string& sys_shapes_dir();
// Return a full path to the custom shapes gallery directory.
std::string custom_shapes_dir();
// Set a path with preset files.
void set_data_dir(const std::string &path);
// Return a full path to the GUI resource files.
@ -99,6 +102,7 @@ extern bool is_gcode_file(const std::string &path);
extern bool is_img_file(const std::string& path);
extern bool is_stl_file(const boost::filesystem::directory_entry& path);
extern bool is_stl_file(const std::string& path);
extern bool is_shapes_dir(const std::string& dir);
// File path / name / extension splitting utilities, working with UTF-8,
// to be published to Perl.

View File

@ -202,6 +202,11 @@ const std::string& data_dir()
return g_data_dir;
}
std::string custom_shapes_dir()
{
return (boost::filesystem::path(g_data_dir) / "shapes").string();
}
#ifdef _WIN32
// The following helpers are borrowed from the LLVM project https://github.com/llvm
namespace WindowsSupport
@ -771,6 +776,11 @@ bool is_stl_file(const std::string &path)
return boost::iends_with(path, ".stl");
}
bool is_shapes_dir(const std::string& dir)
{
return dir == sys_shapes_dir() || dir == custom_shapes_dir();
}
} // namespace Slic3r
#ifdef WIN32

View File

@ -203,6 +203,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ProjectDirtyStateManager.cpp
GUI/DesktopIntegrationDialog.cpp
GUI/DesktopIntegrationDialog.hpp
GUI/HintNotification.cpp
GUI/HintNotification.hpp
Utils/Http.cpp
Utils/Http.hpp
Utils/FixModelByWin10.cpp

View File

@ -20,6 +20,8 @@
#include <boost/log/trivial.hpp>
static const float GROUND_Z = -0.02f;
static const std::array<float, 4> DEFAULT_MODEL_COLOR = { 0.235f, 0.235f, 0.235f, 1.0f };
static const std::array<float, 4> PICKING_MODEL_COLOR = { 0.0f, 0.0f, 0.0f, 1.0f };
namespace Slic3r {
namespace GUI {
@ -211,8 +213,18 @@ Point Bed3D::point_projection(const Point& point) const
return m_polygon.point_projection(point);
}
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture) const
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture)
{
render_internal(canvas, bottom, scale_factor, show_axes, show_texture, false);
}
void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor)
{
render_internal(canvas, bottom, scale_factor, false, false, true);
}
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking)
{
float* factor = const_cast<float*>(&m_scale_factor);
*factor = scale_factor;
@ -222,11 +234,13 @@ void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor,
glsafe(::glEnable(GL_DEPTH_TEST));
m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
switch (m_type)
{
case System: { render_system(canvas, bottom, show_texture); break; }
default:
case Custom: { render_custom(canvas, bottom, show_texture); break; }
case Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
}
glsafe(::glDisable(GL_DEPTH_TEST));
@ -237,7 +251,7 @@ void Bed3D::calc_bounding_boxes() const
BoundingBoxf3* bounding_box = const_cast<BoundingBoxf3*>(&m_bounding_box);
*bounding_box = BoundingBoxf3();
for (const Vec2d& p : m_shape) {
bounding_box->merge({ p(0), p(1), 0.0 });
bounding_box->merge({ p.x(), p.y(), 0.0 });
}
BoundingBoxf3* extended_bounding_box = const_cast<BoundingBoxf3*>(&m_extended_bounding_box);
@ -264,16 +278,16 @@ void Bed3D::calc_triangles(const ExPolygon& poly)
void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
{
Polylines axes_lines;
for (coord_t x = bed_bbox.min(0); x <= bed_bbox.max(0); x += scale_(10.0)) {
for (coord_t x = bed_bbox.min.x(); x <= bed_bbox.max.x(); x += scale_(10.0)) {
Polyline line;
line.append(Point(x, bed_bbox.min(1)));
line.append(Point(x, bed_bbox.max(1)));
line.append(Point(x, bed_bbox.min.y()));
line.append(Point(x, bed_bbox.max.y()));
axes_lines.push_back(line);
}
for (coord_t y = bed_bbox.min(1); y <= bed_bbox.max(1); y += scale_(10.0)) {
for (coord_t y = bed_bbox.min.y(); y <= bed_bbox.max.y(); y += scale_(10.0)) {
Polyline line;
line.append(Point(bed_bbox.min(0), y));
line.append(Point(bed_bbox.max(0), y));
line.append(Point(bed_bbox.min.x(), y));
line.append(Point(bed_bbox.max.x(), y));
axes_lines.push_back(line);
}
@ -333,7 +347,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
if (m_texture_filename.empty()) {
texture->reset();
render_default(bottom);
render_default(bottom, false);
return;
}
@ -346,7 +360,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (!temp_texture->load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
render_default(bottom);
render_default(bottom, false);
return;
}
canvas.request_extra_frame();
@ -354,7 +368,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
// starts generating the main texture, compression will run asynchronously
if (!texture->load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
render_default(bottom);
render_default(bottom, false);
return;
}
}
@ -362,7 +376,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
if (temp_texture->get_id() == 0 || temp_texture->get_source() != m_texture_filename) {
if (!temp_texture->load_from_file(m_texture_filename, false, GLTexture::None, false)) {
render_default(bottom);
render_default(bottom, false);
return;
}
canvas.request_extra_frame();
@ -370,12 +384,12 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
// starts generating the main texture, compression will run asynchronously
if (!texture->load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
render_default(bottom);
render_default(bottom, false);
return;
}
}
else {
render_default(bottom);
render_default(bottom, false);
return;
}
}
@ -388,7 +402,6 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas) const
temp_texture->reset();
canvas.request_extra_frame();
}
if (m_triangles.get_vertices_count() > 0) {
@ -470,7 +483,7 @@ void Bed3D::render_model() const
GLModel* model = const_cast<GLModel*>(&m_model);
if (model->get_filename() != m_model_filename && model->init_from_file(m_model_filename)) {
model->set_color(-1, m_model_color);
model->set_color(-1, DEFAULT_MODEL_COLOR);
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
Vec3d shift = m_bounding_box.center();
@ -495,10 +508,10 @@ void Bed3D::render_model() const
}
}
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const
{
if (m_texture_filename.empty() && m_model_filename.empty()) {
render_default(bottom);
render_default(bottom, picking);
return;
}
@ -509,7 +522,7 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) co
render_texture(bottom, canvas);
}
void Bed3D::render_default(bool bottom) const
void Bed3D::render_default(bool bottom, bool picking) const
{
const_cast<GLTexture*>(&m_texture)->reset();
@ -526,21 +539,23 @@ void Bed3D::render_default(bool bottom) const
if (!has_model && !bottom) {
// draw background
glsafe(::glDepthMask(GL_FALSE));
glsafe(::glColor4fv(m_model_color.data()));
glsafe(::glColor4fv(picking ? PICKING_MODEL_COLOR.data() : DEFAULT_MODEL_COLOR.data()));
glsafe(::glNormal3d(0.0f, 0.0f, 1.0f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data()));
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount));
glsafe(::glDepthMask(GL_TRUE));
}
// draw grid
glsafe(::glLineWidth(1.5f * m_scale_factor));
if (has_model && !bottom)
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f));
else
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
if (!picking) {
// draw grid
glsafe(::glLineWidth(1.5f * m_scale_factor));
if (has_model && !bottom)
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 1.0f));
else
glsafe(::glColor4f(0.9f, 0.9f, 0.9f, 0.6f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_gridlines.get_vertices_data()));
glsafe(::glDrawArrays(GL_LINES, 0, (GLsizei)m_gridlines.get_vertices_count()));
}
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));

View File

@ -84,7 +84,6 @@ private:
GLTexture m_temp_texture;
GLModel m_model;
Vec3d m_model_offset{ Vec3d::Zero() };
std::array<float, 4> m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f };
unsigned int m_vbo_id{ 0 };
Axes m_axes;
@ -110,19 +109,23 @@ public:
Point point_projection(const Point& point) const;
void render(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture) const;
bool show_axes, bool show_texture);
void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
private:
void calc_bounding_boxes() const;
void calc_triangles(const ExPolygon& poly);
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
std::tuple<EType, std::string, std::string> detect_type(const Pointfs& shape) const;
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking);
void render_axes() const;
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture) const;
void render_texture(bool bottom, GLCanvas3D& canvas) const;
void render_model() const;
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture) const;
void render_default(bool bottom) const;
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking) const;
void render_default(bool bottom, bool picking) const;
void reset();
};

View File

@ -9,9 +9,9 @@
#include "3DScene.hpp"
#include "GLShader.hpp"
#include "GUI_App.hpp"
#if ENABLE_ENVIRONMENT_MAP
#if ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS
#include "Plater.hpp"
#endif // ENABLE_ENVIRONMENT_MAP
#endif // ENABLE_ENVIRONMENT_MAP || ENABLE_SINKING_CONTOURS
#include "libslic3r/ExtrusionEntity.hpp"
#include "libslic3r/ExtrusionEntityCollection.hpp"
@ -23,9 +23,11 @@
#include "libslic3r/Format/STL.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/AppConfig.hpp"
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
#include "libslic3r/PresetBundle.hpp"
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
#include "libslic3r/ClipperUtils.hpp"
#if ENABLE_SINKING_CONTOURS
#include "libslic3r/Tesselate.hpp"
#endif // ENABLE_SINKING_CONTOURS
#include <stdio.h>
#include <stdlib.h>
@ -286,6 +288,74 @@ void GLIndexedVertexArray::render(
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
#if ENABLE_SINKING_CONTOURS
const float GLVolume::SinkingContours::HalfWidth = 0.25f;
void GLVolume::SinkingContours::render()
{
update();
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z()));
m_model.render();
glsafe(::glPopMatrix());
}
void GLVolume::SinkingContours::update()
{
if (m_parent.is_sinking() && !m_parent.is_below_printbed()) {
const BoundingBoxf3& box = m_parent.transformed_convex_hull_bounding_box();
if (!m_old_box.size().isApprox(box.size()) || m_old_box.min.z() != box.min.z()) {
m_old_box = box;
m_shift = Vec3d::Zero();
const TriangleMesh& mesh = GUI::wxGetApp().plater()->model().objects[m_parent.object_idx()]->volumes[m_parent.volume_idx()]->mesh();
assert(mesh.has_shared_vertices());
m_model.reset();
GUI::GLModel::InitializationData init_data;
MeshSlicingParams slicing_params;
slicing_params.trafo = m_parent.world_matrix();
Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
for (Polygon& polygon : polygons) {
if (polygon.is_clockwise())
polygon.reverse();
Polygons outer_polys = offset(polygon, float(scale_(HalfWidth)));
assert(outer_polys.size() == 1);
if (outer_polys.empty())
// no outer contour, skip
continue;
ExPolygon expoly(std::move(outer_polys.front()));
expoly.holes = offset(polygon, -float(scale_(HalfWidth)));
polygons_reverse(expoly.holes);
GUI::GLModel::InitializationData::Entity entity;
entity.type = GUI::GLModel::PrimitiveType::Triangles;
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(expoly);
for (const Vec3d& v : triangulation) {
entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.015f)); // add a small positive z to avoid z-fighting
entity.normals.emplace_back(Vec3f::UnitZ());
const size_t positions_count = entity.positions.size();
if (positions_count % 3 == 0) {
entity.indices.emplace_back(positions_count - 3);
entity.indices.emplace_back(positions_count - 2);
entity.indices.emplace_back(positions_count - 1);
}
}
init_data.entities.emplace_back(entity);
}
m_model.init_from(init_data);
}
else
m_shift = box.center() - m_old_box.center();
}
else
m_model.reset();
}
#endif // ENABLE_SINKING_CONTOURS
const std::array<float, 4> GLVolume::SELECTED_COLOR = { 0.0f, 1.0f, 0.0f, 1.0f };
const std::array<float, 4> GLVolume::HOVER_SELECT_COLOR = { 0.4f, 0.9f, 0.1f, 1.0f };
const std::array<float, 4> GLVolume::HOVER_DESELECT_COLOR = { 1.0f, 0.75f, 0.75f, 1.0f };
@ -306,6 +376,9 @@ GLVolume::GLVolume(float r, float g, float b, float a)
: m_transformed_bounding_box_dirty(true)
, m_sla_shift_z(0.0)
, m_transformed_convex_hull_bounding_box_dirty(true)
#if ENABLE_SINKING_CONTOURS
, m_sinking_contours(*this)
#endif // ENABLE_SINKING_CONTOURS
// geometry_id == 0 -> invalid
, geometry_id(std::pair<size_t, size_t>(0, 0))
, extruder_id(0)
@ -323,6 +396,9 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, force_transparent(false)
, force_native_color(false)
, force_neutral_color(false)
#if ENABLE_SINKING_CONTOURS
, force_sinking_contours(false)
#endif // ENABLE_SINKING_CONTOURS
, tverts_range(0, size_t(-1))
, qverts_range(0, size_t(-1))
{
@ -342,16 +418,10 @@ void GLVolume::set_render_color(const std::array<float, 4>& rgba)
void GLVolume::set_render_color()
{
#if ENABLE_ALLOW_NEGATIVE_Z
bool outside = is_outside || is_below_printbed();
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (force_native_color || force_neutral_color) {
#if ENABLE_ALLOW_NEGATIVE_Z
if (outside && shader_outside_printer_detection_enabled)
#else
if (is_outside && shader_outside_printer_detection_enabled)
#endif // ENABLE_ALLOW_NEGATIVE_Z
set_render_color(OUTSIDE_COLOR);
else {
if (force_native_color)
@ -366,18 +436,10 @@ void GLVolume::set_render_color()
else if (hover == HS_Deselect)
set_render_color(HOVER_DESELECT_COLOR);
else if (selected)
#if ENABLE_ALLOW_NEGATIVE_Z
set_render_color(outside ? SELECTED_OUTSIDE_COLOR : SELECTED_COLOR);
#else
set_render_color(is_outside ? SELECTED_OUTSIDE_COLOR : SELECTED_COLOR);
#endif // ENABLE_ALLOW_NEGATIVE_Z
else if (disabled)
set_render_color(DISABLED_COLOR);
#if ENABLE_ALLOW_NEGATIVE_Z
else if (outside && shader_outside_printer_detection_enabled)
#else
else if (is_outside && shader_outside_printer_detection_enabled)
#endif // ENABLE_ALLOW_NEGATIVE_Z
set_render_color(OUTSIDE_COLOR);
else
set_render_color(color);
@ -520,14 +582,9 @@ void GLVolume::render() const
bool GLVolume::is_sla_support() const { return this->composite_id.volume_id == -int(slaposSupportTree); }
bool GLVolume::is_sla_pad() const { return this->composite_id.volume_id == -int(slaposPad); }
#if ENABLE_ALLOW_NEGATIVE_Z
bool GLVolume::is_sinking() const
{
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
if (is_modifier || GUI::wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA)
#else
if (is_modifier)
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
return false;
const BoundingBoxf3& box = transformed_convex_hull_bounding_box();
return box.min.z() < SINKING_Z_THRESHOLD && box.max.z() >= SINKING_Z_THRESHOLD;
@ -537,7 +594,13 @@ bool GLVolume::is_below_printbed() const
{
return transformed_convex_hull_bounding_box().max(2) < 0.0;
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
#if ENABLE_SINKING_CONTOURS
void GLVolume::render_sinking_contours()
{
m_sinking_contours.render();
}
#endif // ENABLE_SINKING_CONTOURS
std::vector<int> GLVolumeCollection::load_object(
const ModelObject *model_object,
@ -774,6 +837,68 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
if (disable_cullface)
glsafe(::glDisable(GL_CULL_FACE));
#if ENABLE_SINKING_CONTOURS
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
for (GLVolumeWithIdAndZ& volume : to_render) {
volume.first->set_render_color();
// render sinking contours of non-hovered volumes
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
shader->stop_using();
volume.first->render_sinking_contours();
shader->start_using();
}
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
shader->set_uniform("uniform_color", volume.first->render_color);
shader->set_uniform("z_range", m_z_range, 2);
shader->set_uniform("clipping_plane", m_clipping_plane, 4);
shader->set_uniform("print_box.min", m_print_box_min, 3);
shader->set_uniform("print_box.max", m_print_box_max, 3);
shader->set_uniform("print_box.actived", volume.first->shader_outside_printer_detection_enabled);
shader->set_uniform("print_box.volume_world_matrix", volume.first->world_matrix());
shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower);
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
shader->set_uniform("slope.normal_z", m_slope.normal_z);
#if ENABLE_ENVIRONMENT_MAP
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
shader->set_uniform("use_environment_tex", use_environment_texture);
if (use_environment_texture)
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
#endif // ENABLE_ENVIRONMENT_MAP
glcheck();
volume.first->render();
#if ENABLE_ENVIRONMENT_MAP
if (use_environment_texture)
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
#endif // ENABLE_ENVIRONMENT_MAP
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
}
for (GLVolumeWithIdAndZ& volume : to_render) {
// render sinking contours of hovered/displaced volumes
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
shader->stop_using();
glsafe(::glDepthFunc(GL_ALWAYS));
volume.first->render_sinking_contours();
glsafe(::glDepthFunc(GL_LESS));
shader->start_using();
}
}
#else
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
@ -813,6 +938,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
#endif // ENABLE_SINKING_CONTOURS
if (disable_cullface)
glsafe(::glEnable(GL_CULL_FACE));
@ -879,8 +1005,8 @@ bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, b
if (opt == nullptr)
return false;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Vec3d(unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config->opt_float("max_print_height")));
const BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
BoundingBoxf3 print_volume(Vec3d(unscale<double>(bed_box_2D.min.x()), unscale<double>(bed_box_2D.min.y()), 0.0), Vec3d(unscale<double>(bed_box_2D.max.x()), unscale<double>(bed_box_2D.max.y()), config->opt_float("max_print_height")));
// Allow the objects to protrude below the print bed
print_volume.min(2) = -1e10;
print_volume.min(0) -= BedEpsilon;

View File

@ -8,6 +8,10 @@
#include "libslic3r/Utils.hpp"
#include "libslic3r/Geometry.hpp"
#if ENABLE_SINKING_CONTOURS
#include "GLModel.hpp"
#endif // ENABLE_SINKING_CONTOURS
#include <functional>
#define HAS_GLSAFE
@ -250,6 +254,9 @@ public:
enum EHoverState : unsigned char
{
HS_None,
#if ENABLE_SINKING_CONTOURS
HS_Hover,
#endif // ENABLE_SINKING_CONTOURS
HS_Select,
HS_Deselect
};
@ -262,7 +269,7 @@ private:
Geometry::Transformation m_volume_transformation;
// Shift in z required by sla supports+pad
double m_sla_shift_z;
double m_sla_shift_z;
// Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 m_transformed_bounding_box;
// Whether or not is needed to recalculate the transformed bounding box.
@ -274,6 +281,26 @@ private:
// Whether or not is needed to recalculate the transformed convex hull bounding box.
bool m_transformed_convex_hull_bounding_box_dirty;
#if ENABLE_SINKING_CONTOURS
class SinkingContours
{
static const float HalfWidth;
GLVolume& m_parent;
GUI::GLModel m_model;
BoundingBoxf3 m_old_box;
Vec3d m_shift{ Vec3d::Zero() };
public:
SinkingContours(GLVolume& volume) : m_parent(volume) {}
void render();
private:
void update();
};
SinkingContours m_sinking_contours;
#endif // ENABLE_SINKING_CONTOURS
public:
// Color of the triangles / quads held by this volume.
std::array<float, 4> color;
@ -334,7 +361,11 @@ public:
bool force_native_color : 1;
// Whether or not render this volume in neutral
bool force_neutral_color : 1;
};
#if ENABLE_SINKING_CONTOURS
// Whether or not to force rendering of sinking contours
bool force_sinking_contours : 1;
#endif // ENABLE_SINKING_CONTOURS
};
// Is mouse or rectangle selection over this object to select/deselect it ?
EHoverState hover;
@ -459,10 +490,11 @@ public:
bool is_sla_support() const;
bool is_sla_pad() const;
#if ENABLE_ALLOW_NEGATIVE_Z
bool is_sinking() const;
bool is_below_printbed() const;
#endif // ENABLE_ALLOW_NEGATIVE_Z
#if ENABLE_SINKING_CONTOURS
void render_sinking_contours();
#endif // ENABLE_SINKING_CONTOURS
// Return an estimate of the memory consumed by this class.
size_t cpu_memory_used() const {

View File

@ -155,19 +155,15 @@ void BackgroundSlicingProcess::process_fff()
if (! m_export_path.empty()) {
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id));
#if ENABLE_GCODE_WINDOW
// let the gcode window to unmap the temporary .gcode file (m_temp_output_path)
// because the scripts may want to modify it
GUI::wxGetApp().plater()->stop_mapping_gcode_window();
#endif // ENABLE_GCODE_WINDOW
m_print->set_status(95, _utf8(L("Running post-processing scripts")));
run_post_process_scripts(m_temp_output_path, m_fff_print->full_print_config());
#if ENABLE_GCODE_WINDOW
// let the gcode window to reload and remap the temporary .gcode file (m_temp_output_path)
GUI::wxGetApp().plater()->start_mapping_gcode_window();
#endif // ENABLE_GCODE_WINDOW
//FIXME localize the messages
// Perform the final post-processing of the export path by applying the print statistics over the file name.

View File

@ -40,6 +40,7 @@
#include "slic3r/Utils/PresetUpdater.hpp"
#include "format.hpp"
#include "MsgDialog.hpp"
#include "libslic3r/libslic3r.h"
#if defined(__linux__) && defined(__WXGTK3__)
#define wxLinux_gtk3 true
@ -65,6 +66,7 @@ bool Bundle::load(fs::path source_path, bool ais_in_resources, bool ais_prusa_bu
std::string path_string = source_path.string();
auto [config_substitutions, presets_loaded] = preset_bundle->load_configbundle(path_string, PresetBundle::LoadConfigBundleAttribute::LoadSystem);
UNUSED(config_substitutions);
// No substitutions shall be reported when loading a system config bundle, no substitutions are allowed.
assert(config_substitutions.empty());
auto first_vendor = preset_bundle->vendors.begin();
@ -1604,25 +1606,17 @@ ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent)
, item_hover(NO_ITEM)
, last_page((size_t)-1)
{
#ifndef __WXOSX__
SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX
#endif //__WXOSX__
SetMinSize(bg.bmp().GetSize());
const wxSize size = GetTextExtent("m");
em_w = size.x;
em_h = size.y;
// Add logo bitmap.
// This could be done in on_paint() along with the index labels, but I've found it tricky
// to get the bitmap rendered well on all platforms with transparent background.
// In some cases it didn't work at all. And so wxStaticBitmap is used here instead,
// because it has all the platform quirks figured out.
auto *sizer = new wxBoxSizer(wxVERTICAL);
logo = new wxStaticBitmap(this, wxID_ANY, bg.bmp());
sizer->AddStretchSpacer();
sizer->Add(logo);
SetSizer(sizer);
logo_height = logo->GetBitmap().GetHeight();
Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
Bind(wxEVT_SIZE, [this](wxEvent& e) { e.Skip(); Refresh(); });
Bind(wxEVT_MOTION, &ConfigWizardIndex::on_mouse_move, this);
Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &evt) {
@ -1767,6 +1761,12 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
y += yinc;
index_width = std::max(index_width, (int)x + text_size.x);
}
//draw logo
if (int y = size.y - bg.GetBmpHeight(); y>=0) {
dc.DrawBitmap(bg.bmp(), 0, y, false);
index_width = std::max(index_width, bg.GetBmpWidth() + em_w / 2);
}
if (GetMinSize().x < index_width) {
CallAfter([this, index_width]() {
@ -1774,11 +1774,6 @@ void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
Refresh();
});
}
if ((int)y + logo_height > size.GetHeight())
logo->Hide();
else
logo->Show();
}
void ConfigWizardIndex::on_mouse_move(wxMouseEvent &evt)
@ -1804,7 +1799,6 @@ void ConfigWizardIndex::msw_rescale()
bg.msw_rescale();
SetMinSize(bg.bmp().GetSize());
logo->SetBitmap(bg.bmp());
bullet_black.msw_rescale();
bullet_blue.msw_rescale();

View File

@ -512,15 +512,12 @@ private:
ScalableBitmap bullet_black;
ScalableBitmap bullet_blue;
ScalableBitmap bullet_white;
wxStaticBitmap* logo;
std::vector<Item> items;
size_t item_active;
ssize_t item_hover;
size_t last_page;
int logo_height;
int item_height() const { return std::max(bullet_black.bmp().GetSize().GetHeight(), em_w) + em_w; }
void on_paint(wxPaintEvent &evt);

View File

@ -739,16 +739,8 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer
return size_t(it - m_layers_values.begin());
};
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (m_draw_mode == dmSequentialGCodeView) {
return (Slic3r::GUI::get_app_config()->get("seq_top_gcode_indices") == "1") ?
wxString::Format("%lu", static_cast<unsigned long>(m_alternate_values[value])) :
wxString::Format("%lu", static_cast<unsigned long>(m_values[value]));
}
#else
if (m_draw_mode == dmSequentialGCodeView)
return wxString::Format("%lu", static_cast<unsigned long>(m_values[value]));
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
return wxString::Format("%lu", static_cast<unsigned long>(m_alternate_values[value]));
else {
if (label_type == ltEstimatedTime) {
if (m_is_wipe_tower) {
@ -1556,6 +1548,9 @@ void Control::OnMotion(wxMouseEvent& event)
event.Skip();
// Set tooltips with information for each icon
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
if (GUI::wxGetApp().is_editor())
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
this->SetToolTip(get_tooltip(tick));
if (action) {
@ -2062,6 +2057,10 @@ void Control::auto_color_change()
break;
if (prev_area - cur_area > delta_area) {
// Check percent of the area decrease.
// Ignore it, if this value is less than 10%
if (cur_area / prev_area > 0.9)
continue;
int tick = get_tick_from_value(layer->print_z);
if (tick >= 0 && !m_ticks.has_tick(tick)) {
if (m_mode == SingleExtruder) {
@ -2180,7 +2179,6 @@ static std::string get_custom_code(const std::string& code_in, double height)
wxTextEntryDialogStyle | wxTE_MULTILINE);
upgrade_text_entry_dialog(&dlg);
#if ENABLE_VALIDATE_CUSTOM_GCODE
bool valid = true;
std::string value;
do {
@ -2191,12 +2189,6 @@ static std::string get_custom_code(const std::string& code_in, double height)
valid = GUI::Tab::validate_custom_gcode("Custom G-code", value);
} while (!valid);
return value;
#else
if (dlg.ShowModal() != wxID_OK)
return "";
return into_u8(dlg.GetValue());
#endif // ENABLE_VALIDATE_CUSTOM_GCODE
}
static std::string get_pause_print_msg(const std::string& msg_in, double height)

View File

@ -223,9 +223,7 @@ public:
void SetKoefForLabels(const double koef) { m_label_koef = koef; }
void SetSliderValues(const std::vector<double>& values);
void ChangeOneLayerLock();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
void SetSliderAlternateValues(const std::vector<double>& values) { m_alternate_values = values; }
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
Info GetTicksValues() const;
void SetTicksValues(const Info &custom_gcode_per_print_z);
@ -409,9 +407,7 @@ private:
std::vector<std::string> m_extruder_colors;
std::string m_print_obj_idxs;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
std::vector<double> m_alternate_values;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// control's view variables
wxCoord SLIDER_MARGIN; // margin around slider

View File

@ -23,9 +23,7 @@
#include <GL/glew.h>
#include <boost/log/trivial.hpp>
#if ENABLE_GCODE_WINDOW
#include <boost/algorithm/string/split.hpp>
#endif // ENABLE_GCODE_WINDOW
#include <boost/nowide/cstdio.hpp>
#include <boost/nowide/fstream.hpp>
#include <wx/progdlg.h>
@ -123,9 +121,7 @@ bool GCodeViewer::Path::matches(const GCodeProcessor::MoveVertex& move) const
case EMoveType::Custom_GCode:
case EMoveType::Retract:
case EMoveType::Unretract:
#if ENABLE_SEAMS_VISUALIZATION
case EMoveType::Seam:
#endif // ENABLE_SEAMS_VISUALIZATION
case EMoveType::Extrude: {
// use rounding to reduce the number of generated paths
return type == move.type && extruder_id == move.extruder_id && cp_color_id == move.cp_color_id && role == move.extrusion_role &&
@ -269,7 +265,6 @@ void GCodeViewer::SequentialView::Marker::render() const
ImGui::PopStyleVar();
}
#if ENABLE_GCODE_WINDOW
void GCodeViewer::SequentialView::GCodeWindow::load_gcode()
{
if (m_filename.empty())
@ -487,7 +482,6 @@ void GCodeViewer::SequentialView::render(float legend_height) const
bottom -= wxGetApp().plater()->get_view_toolbar().get_height();
gcode_window.render(legend_height, bottom, static_cast<uint64_t>(gcode_ids[current.last]));
}
#endif // ENABLE_GCODE_WINDOW
const std::vector<GCodeViewer::Color> GCodeViewer::Extrusion_Role_Colors {{
{ 0.75f, 0.75f, 0.75f }, // erNone
@ -511,9 +505,7 @@ const std::vector<GCodeViewer::Color> GCodeViewer::Extrusion_Role_Colors {{
const std::vector<GCodeViewer::Color> GCodeViewer::Options_Colors {{
{ 0.803f, 0.135f, 0.839f }, // Retractions
{ 0.287f, 0.679f, 0.810f }, // Unretractions
#if ENABLE_SEAMS_VISUALIZATION
{ 0.900f, 0.900f, 0.900f }, // Seams
#endif // ENABLE_SEAMS_VISUALIZATION
{ 0.758f, 0.744f, 0.389f }, // ToolChanges
{ 0.856f, 0.582f, 0.546f }, // ColorChanges
{ 0.322f, 0.942f, 0.512f }, // PausePrints
@ -556,20 +548,12 @@ GCodeViewer::GCodeViewer()
case EMoveType::Pause_Print:
case EMoveType::Custom_GCode:
case EMoveType::Retract:
#if ENABLE_SEAMS_VISUALIZATION
case EMoveType::Unretract:
case EMoveType::Seam: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
buffer.vertices.format = VBuffer::EFormat::Position;
break;
}
#else
case EMoveType::Unretract: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Point;
buffer.vertices.format = VBuffer::EFormat::Position;
break;
}
#endif // ENABLE_SEAMS_VISUALIZATION
case EMoveType::Wipe:
case EMoveType::Extrude: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
@ -599,10 +583,13 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
// release gpu memory, if used
reset();
#if ENABLE_GCODE_WINDOW
m_sequential_view.gcode_window.set_filename(gcode_result.filename);
m_sequential_view.gcode_window.load_gcode();
#endif // ENABLE_GCODE_WINDOW
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
if (wxGetApp().is_gcode_viewer())
m_custom_gcode_per_print_z = gcode_result.custom_gcode_per_print_z;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
load_toolpaths(gcode_result);
@ -761,9 +748,10 @@ void GCodeViewer::reset()
m_layers_z_range = { 0, 0 };
m_roles = std::vector<ExtrusionRole>();
m_print_statistics.reset();
#if ENABLE_GCODE_WINDOW
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
m_custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
m_sequential_view.gcode_window.reset();
#endif // ENABLE_GCODE_WINDOW
#if ENABLE_GCODE_VIEWER_STATISTICS
m_statistics.reset_all();
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -783,18 +771,11 @@ void GCodeViewer::render() const
case EMoveType::Pause_Print:
case EMoveType::Custom_GCode:
case EMoveType::Retract:
#if ENABLE_SEAMS_VISUALIZATION
case EMoveType::Unretract:
case EMoveType::Seam: {
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
break;
}
#else
case EMoveType::Unretract: {
buffer.shader = wxGetApp().is_glsl_version_greater_or_equal_to(1, 20) ? "options_120" : "options_110";
break;
}
#endif // ENABLE_SEAMS_VISUALIZATION
case EMoveType::Wipe:
case EMoveType::Extrude: {
buffer.shader = "gouraud_light";
@ -832,20 +813,12 @@ void GCodeViewer::render() const
glsafe(::glEnable(GL_DEPTH_TEST));
render_toolpaths();
render_shells();
#if ENABLE_GCODE_WINDOW
float legend_height = 0.0f;
render_legend(legend_height);
#else
render_legend();
#endif // ENABLE_GCODE_WINDOW
SequentialView* sequential_view = const_cast<SequentialView*>(&m_sequential_view);
if (sequential_view->current.last != sequential_view->endpoints.last) {
sequential_view->marker.set_world_position(sequential_view->current_position);
#if ENABLE_GCODE_WINDOW
sequential_view->render(legend_height);
#else
sequential_view->marker.render();
#endif // ENABLE_GCODE_WINDOW
}
#if ENABLE_GCODE_VIEWER_STATISTICS
render_statistics();
@ -927,9 +900,7 @@ unsigned int GCodeViewer::get_options_visibility_flags() const
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Wipe), is_toolpath_move_type_visible(EMoveType::Wipe));
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Retractions), is_toolpath_move_type_visible(EMoveType::Retract));
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Unretractions), is_toolpath_move_type_visible(EMoveType::Unretract));
#if ENABLE_SEAMS_VISUALIZATION
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::Seams), is_toolpath_move_type_visible(EMoveType::Seam));
#endif // ENABLE_SEAMS_VISUALIZATION
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ToolChanges), is_toolpath_move_type_visible(EMoveType::Tool_change));
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::ColorChanges), is_toolpath_move_type_visible(EMoveType::Color_change));
flags = set_flag(flags, static_cast<unsigned int>(Preview::OptionType::PausePrints), is_toolpath_move_type_visible(EMoveType::Pause_Print));
@ -950,9 +921,7 @@ void GCodeViewer::set_options_visibility_from_flags(unsigned int flags)
set_toolpath_move_type_visible(EMoveType::Wipe, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Wipe)));
set_toolpath_move_type_visible(EMoveType::Retract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Retractions)));
set_toolpath_move_type_visible(EMoveType::Unretract, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Unretractions)));
#if ENABLE_SEAMS_VISUALIZATION
set_toolpath_move_type_visible(EMoveType::Seam, is_flag_set(static_cast<unsigned int>(Preview::OptionType::Seams)));
#endif // ENABLE_SEAMS_VISUALIZATION
set_toolpath_move_type_visible(EMoveType::Tool_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ToolChanges)));
set_toolpath_move_type_visible(EMoveType::Color_change, is_flag_set(static_cast<unsigned int>(Preview::OptionType::ColorChanges)));
set_toolpath_move_type_visible(EMoveType::Pause_Print, is_flag_set(static_cast<unsigned int>(Preview::OptionType::PausePrints)));
@ -1122,7 +1091,6 @@ void GCodeViewer::export_toolpaths_to_obj(const char* filename) const
fclose(fp);
}
#if ENABLE_GCODE_WINDOW
void GCodeViewer::start_mapping_gcode_window()
{
m_sequential_view.gcode_window.load_gcode();
@ -1132,7 +1100,6 @@ void GCodeViewer::stop_mapping_gcode_window()
{
m_sequential_view.gcode_window.stop_mapping_file();
}
#endif // ENABLE_GCODE_WINDOW
void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
{
@ -1430,11 +1397,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
// for the gcode viewer we need to take in account all moves to correctly size the printbed
m_paths_bounding_box.merge(move.position.cast<double>());
else {
#if ENABLE_START_GCODE_VISUALIZATION
if (move.type == EMoveType::Extrude && move.extrusion_role != erCustom && move.width != 0.0f && move.height != 0.0f)
#else
if (move.type == EMoveType::Extrude && move.width != 0.0f && move.height != 0.0f)
#endif // ENABLE_START_GCODE_VISUALIZATION
m_paths_bounding_box.merge(move.position.cast<double>());
}
}
@ -1443,12 +1406,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
m_max_bounding_box = m_paths_bounding_box;
m_max_bounding_box.merge(m_paths_bounding_box.max + m_sequential_view.marker.get_bounding_box().size()[2] * Vec3d::UnitZ());
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
m_sequential_view.gcode_ids.clear();
for (const GCodeProcessor::MoveVertex& move : gcode_result.moves) {
m_sequential_view.gcode_ids.push_back(move.gcode_id);
}
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
std::vector<MultiVertexBuffer> vertices(m_buffers.size());
std::vector<MultiIndexBuffer> indices(m_buffers.size());
@ -2188,9 +2149,7 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
case EMoveType::Custom_GCode: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::CustomGCodes)]; break; }
case EMoveType::Retract: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Retractions)]; break; }
case EMoveType::Unretract: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Unretractions)]; break; }
#if ENABLE_SEAMS_VISUALIZATION
case EMoveType::Seam: { color = Options_Colors[static_cast<unsigned int>(EOptionsColors::Seams)]; break; }
#endif // ENABLE_SEAMS_VISUALIZATION
case EMoveType::Extrude: {
if (!top_layer_only ||
m_sequential_view.current.last == global_endpoints.last ||
@ -2594,34 +2553,22 @@ void GCodeViewer::render_shells() const
// glsafe(::glDepthMask(GL_TRUE));
}
#if ENABLE_GCODE_WINDOW
void GCodeViewer::render_legend(float& legend_height) const
#else
void GCodeViewer::render_legend() const
#endif // ENABLE_GCODE_WINDOW
{
if (!m_legend_enabled)
return;
#if ENABLE_SCROLLABLE_LEGEND
const Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
#endif // ENABLE_SCROLLABLE_LEGEND
ImGuiWrapper& imgui = *wxGetApp().imgui();
imgui.set_next_window_pos(0.0f, 0.0f, ImGuiCond_Always);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::SetNextWindowBgAlpha(0.6f);
#if ENABLE_SCROLLABLE_LEGEND
const float max_height = 0.75f * static_cast<float>(cnv_size.get_height());
const float child_height = 0.3333f * max_height;
ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, max_height });
imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove);
#else
imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
#endif // ENABLE_SCROLLABLE_LEGEND
enum class EItemType : unsigned char
{
@ -2632,30 +2579,22 @@ void GCodeViewer::render_legend() const
};
const PrintEstimatedStatistics::Mode& time_mode = m_print_statistics.modes[static_cast<size_t>(m_time_estimate_mode)];
#if ENABLE_SCROLLABLE_LEGEND
bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType ||
(m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()));
#endif // ENABLE_SCROLLABLE_LEGEND
const float icon_size = ImGui::GetTextLineHeight();
const float percent_bar_size = 2.0f * ImGui::GetTextLineHeight();
bool imperial_units = wxGetApp().app_config->get("use_inches") == "1";
#if ENABLE_SCROLLABLE_LEGEND
auto append_item = [this, icon_size, percent_bar_size, &imgui, imperial_units](EItemType type, const Color& color, const std::string& label,
#else
auto append_item = [this, draw_list, icon_size, percent_bar_size, &imgui, imperial_units](EItemType type, const Color& color, const std::string& label,
#endif // ENABLE_SCROLLABLE_LEGEND
bool visible = true, const std::string& time = "", float percent = 0.0f, float max_percent = 0.0f, const std::array<float, 4>& offsets = { 0.0f, 0.0f, 0.0f, 0.0f },
double used_filament_m = 0.0, double used_filament_g = 0.0,
std::function<void()> callback = nullptr) {
if (!visible)
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f);
#if ENABLE_SCROLLABLE_LEGEND
ImDrawList* draw_list = ImGui::GetWindowDrawList();
#endif // ENABLE_SCROLLABLE_LEGEND
ImVec2 pos = ImGui::GetCursorScreenPos();
switch (type) {
default:
@ -3008,8 +2947,11 @@ void GCodeViewer::render_legend() const
}
case EViewType::ColorPrint:
{
#if ENABLE_SCROLLABLE_LEGEND
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
#else
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
size_t total_items = 1;
for (unsigned char i : m_extruder_ids) {
total_items += color_print_ranges(i, custom_gcode_per_print_z).size();
@ -3020,9 +2962,6 @@ void GCodeViewer::render_legend() const
// add scrollable region, if needed
if (need_scrollable)
ImGui::BeginChild("color_prints", { -1.0f, child_height }, false);
#else
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
#endif // ENABLE_SCROLLABLE_LEGEND
if (m_extruders_count == 1) { // single extruder use case
const std::vector<std::pair<Color, std::pair<double, double>>> cp_values = color_print_ranges(0, custom_gcode_per_print_z);
const int items_cnt = static_cast<int>(cp_values.size());
@ -3073,10 +3012,8 @@ void GCodeViewer::render_legend() const
}
}
}
#if ENABLE_SCROLLABLE_LEGEND
if (need_scrollable)
ImGui::EndChild();
#endif // ENABLE_SCROLLABLE_LEGEND
break;
}
@ -3109,7 +3046,11 @@ void GCodeViewer::render_legend() const
auto generate_partial_times = [this, get_used_filament_from_volume](const TimesList& times, const std::vector<double>& used_filaments) {
PartialTimes items;
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
#else
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
int extruders_count = wxGetApp().extruders_edited_cnt();
std::vector<Color> last_color(extruders_count);
for (int i = 0; i < extruders_count; ++i) {
@ -3227,12 +3168,10 @@ void GCodeViewer::render_legend() const
ImGui::Spacing();
append_headers({ _u8L("Event"), _u8L("Remaining time"), _u8L("Duration"), _u8L("Used filament") }, offsets);
#if ENABLE_SCROLLABLE_LEGEND
const bool need_scrollable = static_cast<float>(partial_times.size()) * (icon_size + ImGui::GetStyle().ItemSpacing.y) > child_height;
if (need_scrollable)
// add scrollable region
ImGui::BeginChild("events", { -1.0f, child_height }, false);
#endif // ENABLE_SCROLLABLE_LEGEND
for (const PartialTime& item : partial_times) {
switch (item.type)
@ -3254,10 +3193,8 @@ void GCodeViewer::render_legend() const
}
}
#if ENABLE_SCROLLABLE_LEGEND
if (need_scrollable)
ImGui::EndChild();
#endif // ENABLE_SCROLLABLE_LEGEND
}
}
@ -3316,12 +3253,8 @@ void GCodeViewer::render_legend() const
available(EMoveType::Pause_Print) ||
available(EMoveType::Retract) ||
available(EMoveType::Tool_change) ||
#if ENABLE_SEAMS_VISUALIZATION
available(EMoveType::Unretract) ||
available(EMoveType::Seam);
#else
available(EMoveType::Unretract);
#endif // ENABLE_SEAMS_VISUALIZATION
};
auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
@ -3339,9 +3272,7 @@ void GCodeViewer::render_legend() const
// items
add_option(EMoveType::Retract, EOptionsColors::Retractions, _u8L("Retractions"));
add_option(EMoveType::Unretract, EOptionsColors::Unretractions, _u8L("Deretractions"));
#if ENABLE_SEAMS_VISUALIZATION
add_option(EMoveType::Seam, EOptionsColors::Seams, _u8L("Seams"));
#endif // ENABLE_SEAMS_VISUALIZATION
add_option(EMoveType::Tool_change, EOptionsColors::ToolChanges, _u8L("Tool changes"));
add_option(EMoveType::Color_change, EOptionsColors::ColorChanges, _u8L("Color changes"));
add_option(EMoveType::Pause_Print, EOptionsColors::PausePrints, _u8L("Print pauses"));
@ -3407,48 +3338,56 @@ void GCodeViewer::render_legend() const
}
// total estimated printing time section
#if ENABLE_SCROLLABLE_LEGEND
if (show_estimated_time) {
#else
if (time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType ||
(m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()))) {
ImGui::Spacing();
#endif // ENABLE_SCROLLABLE_LEGEND
ImGui::Spacing();
std::string time_title = _u8L("Estimated printing times");
switch (m_time_estimate_mode)
{
case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]:"; break; }
case PrintEstimatedStatistics::ETimeMode::Stealth: { time_title += " [" + _u8L("Stealth mode") + "]:"; break; }
default: { assert(false); break; }
auto can_show_mode_button = [this](PrintEstimatedStatistics::ETimeMode mode) {
bool show = false;
if (m_print_statistics.modes.size() > 1 && m_print_statistics.modes[static_cast<size_t>(mode)].roles_times.size() > 0) {
for (size_t i = 0; i < m_print_statistics.modes.size(); ++i) {
if (i != static_cast<size_t>(mode) &&
m_print_statistics.modes[i].time > 0.0f &&
short_time(get_time_dhms(m_print_statistics.modes[static_cast<size_t>(mode)].time)) != short_time(get_time_dhms(m_print_statistics.modes[i].time))) {
show = true;
break;
}
}
}
return show;
};
if (can_show_mode_button(m_time_estimate_mode)) {
switch (m_time_estimate_mode)
{
case PrintEstimatedStatistics::ETimeMode::Normal: { time_title += " [" + _u8L("Normal mode") + "]"; break; }
case PrintEstimatedStatistics::ETimeMode::Stealth: { time_title += " [" + _u8L("Stealth mode") + "]"; break; }
default: { assert(false); break; }
}
}
imgui.title(time_title);
imgui.title(time_title + ":");
std::string first_str = _u8L("First layer");
std::string total_str = _u8L("Total");
float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x + std::max(ImGui::CalcTextSize(first_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x);
float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x;
if (time_mode.layers_times.empty())
max_len += ImGui::CalcTextSize(total_str.c_str()).x;
else
max_len += std::max(ImGui::CalcTextSize(first_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x);
imgui.text(first_str + ":");
ImGui::SameLine(max_len);
imgui.text(short_time(get_time_dhms(time_mode.layers_times.front())));
if (!time_mode.layers_times.empty()) {
imgui.text(first_str + ":");
ImGui::SameLine(max_len);
imgui.text(short_time(get_time_dhms(time_mode.layers_times.front())));
}
imgui.text(total_str + ":");
ImGui::SameLine(max_len);
imgui.text(short_time(get_time_dhms(time_mode.time)));
auto show_mode_button = [this, &imgui](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) {
bool show = false;
for (size_t i = 0; i < m_print_statistics.modes.size(); ++i) {
if (i != static_cast<size_t>(mode) &&
short_time(get_time_dhms(m_print_statistics.modes[static_cast<size_t>(mode)].time)) != short_time(get_time_dhms(m_print_statistics.modes[i].time))) {
show = true;
break;
}
}
if (show && m_print_statistics.modes[static_cast<size_t>(mode)].roles_times.size() > 0) {
auto show_mode_button = [this, &imgui, can_show_mode_button](const wxString& label, PrintEstimatedStatistics::ETimeMode mode) {
if (can_show_mode_button(mode)) {
if (imgui.button(label)) {
*const_cast<PrintEstimatedStatistics::ETimeMode*>(&m_time_estimate_mode) = mode;
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
@ -3470,9 +3409,7 @@ void GCodeViewer::render_legend() const
}
}
#if ENABLE_GCODE_WINDOW
legend_height = ImGui::GetCurrentWindow()->Size.y;
#endif // ENABLE_GCODE_WINDOW
imgui.end();
ImGui::PopStyleVar();

View File

@ -5,9 +5,7 @@
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "GLModel.hpp"
#if ENABLE_GCODE_WINDOW
#include <boost/iostreams/device/mapped_file.hpp>
#endif // ENABLE_GCODE_WINDOW
#include <cstdint>
#include <float.h>
@ -40,9 +38,7 @@ class GCodeViewer
{
Retractions,
Unretractions,
#if ENABLE_SEAMS_VISUALIZATION
Seams,
#endif // ENABLE_SEAMS_VISUALIZATION
ToolChanges,
ColorChanges,
PausePrints,
@ -520,7 +516,6 @@ public:
void render() const;
};
#if ENABLE_GCODE_WINDOW
class GCodeWindow
{
struct Line
@ -557,7 +552,6 @@ public:
void stop_mapping_file();
};
#endif // ENABLE_GCODE_WINDOW
struct Endpoints
{
@ -571,16 +565,10 @@ public:
Endpoints last_current;
Vec3f current_position{ Vec3f::Zero() };
Marker marker;
#if ENABLE_GCODE_WINDOW
GCodeWindow gcode_window;
#endif // ENABLE_GCODE_WINDOW
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
std::vector<unsigned int> gcode_ids;
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
#if ENABLE_GCODE_WINDOW
void render(float legend_height) const;
#endif // ENABLE_GCODE_WINDOW
};
enum class EViewType : unsigned char
@ -628,6 +616,10 @@ private:
GCodeProcessor::Result::SettingsIds m_settings_ids;
std::array<SequentialRangeCap, 2> m_sequential_range_caps;
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<CustomGCode::Item> m_custom_gcode_per_print_z;
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
public:
GCodeViewer();
~GCodeViewer() { reset(); }
@ -673,11 +665,14 @@ public:
void export_toolpaths_to_obj(const char* filename) const;
#if ENABLE_GCODE_WINDOW
void start_mapping_gcode_window();
void stop_mapping_gcode_window();
void toggle_gcode_window_visibility() { m_sequential_view.gcode_window.toggle_visibility(); }
#endif // ENABLE_GCODE_WINDOW
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_custom_gcode_per_print_z; }
size_t get_extruders_count() { return m_extruders_count; }
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
private:
void load_toolpaths(const GCodeProcessor::Result& gcode_result);
@ -685,11 +680,7 @@ private:
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
void render_toolpaths() const;
void render_shells() const;
#if ENABLE_GCODE_WINDOW
void render_legend(float& legend_height) const;
#else
void render_legend() const;
#endif // ENABLE_GCODE_WINDOW
#if ENABLE_GCODE_VIEWER_STATISTICS
void render_statistics() const;
#endif // ENABLE_GCODE_VIEWER_STATISTICS

View File

@ -169,17 +169,10 @@ void GLCanvas3D::LayersEditing::set_config(const DynamicPrintConfig* config)
void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
{
const ModelObject *model_object_new = (object_id >= 0) ? model.objects[object_id] : nullptr;
#if ENABLE_ALLOW_NEGATIVE_Z
// Maximum height of an object changes when the object gets rotated or scaled.
// Changing maximum height of an object will invalidate the layer heigth editing profile.
// m_model_object->bounding_box() is cached, therefore it is cheap even if this method is called frequently.
const float new_max_z = (model_object_new == nullptr) ? 0.0f : static_cast<float>(model_object_new->bounding_box().max.z());
#else
// Maximum height of an object changes when the object gets rotated or scaled.
// Changing maximum height of an object will invalidate the layer heigth editing profile.
// m_model_object->raw_bounding_box() is cached, therefore it is cheap even if this method is called frequently.
float new_max_z = (model_object_new == nullptr) ? 0.f : model_object_new->raw_bounding_box().size().z();
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z ||
(model_object_new != nullptr && m_model_object->id() != model_object_new->id())) {
m_layer_height_profile.clear();
@ -261,7 +254,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
float widget_align = ImGui::GetCursorPosX();
ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f);
m_adaptive_quality = std::clamp(m_adaptive_quality, 0.0f, 1.f);
ImGui::SliderFloat("", &m_adaptive_quality, 0.0f, 1.f, "%.2f");
imgui.slider_float("", &m_adaptive_quality, 0.0f, 1.f, "%.2f");
ImGui::Separator();
if (imgui.button(_L("Smooth")))
@ -799,7 +792,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
for (const Polygon& poly : polygons) {
triangles_count += poly.points.size() - 2;
}
size_t vertices_count = 3 * triangles_count;
const size_t vertices_count = 3 * triangles_count;
if (m_render_fill) {
GLModel::InitializationData fill_data;
@ -810,13 +803,13 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
entity.normals.reserve(vertices_count);
entity.indices.reserve(vertices_count);
ExPolygons polygons_union = union_ex(polygons);
const ExPolygons polygons_union = union_ex(polygons);
for (const ExPolygon& poly : polygons_union) {
std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly, false);
const std::vector<Vec3d> triangulation = triangulate_expolygon_3d(poly);
for (const Vec3d& v : triangulation) {
entity.positions.emplace_back(v.cast<float>() + Vec3f(0.0f, 0.0f, 0.0125f)); // add a small positive z to avoid z-fighting
entity.normals.emplace_back(Vec3f::UnitZ());
size_t positions_count = entity.positions.size();
const size_t positions_count = entity.positions.size();
if (positions_count % 3 == 0) {
entity.indices.emplace_back(positions_count - 3);
entity.indices.emplace_back(positions_count - 2);
@ -907,6 +900,8 @@ wxDEFINE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
wxDEFINE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_RELOAD_FROM_DISK, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_RENDER_TIMER, wxTimerEvent/*RenderTimerEvent*/);
wxDEFINE_EVENT(EVT_GLCANVAS_TOOLBAR_HIGHLIGHTER_TIMER, wxTimerEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, wxTimerEvent);
const double GLCanvas3D::DefaultCameraZoomToBoxMarginFactor = 1.25;
@ -1119,7 +1114,6 @@ int GLCanvas3D::check_volumes_outside_state() const
return (int)state;
}
#if ENABLE_GCODE_WINDOW
void GLCanvas3D::start_mapping_gcode_window()
{
m_gcode_viewer.start_mapping_gcode_window();
@ -1129,7 +1123,6 @@ void GLCanvas3D::stop_mapping_gcode_window()
{
m_gcode_viewer.stop_mapping_gcode_window();
}
#endif // ENABLE_GCODE_WINDOW
void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx)
{
@ -1416,10 +1409,6 @@ void GLCanvas3D::render()
if (!is_initialized() && !init())
return;
#if ENABLE_RENDER_STATISTICS
auto start_time = std::chrono::high_resolution_clock::now();
#endif // ENABLE_RENDER_STATISTICS
if (wxGetApp().plater()->get_bed().get_shape().empty()) {
// this happens at startup when no data is still saved under <>\AppData\Roaming\Slic3rPE
post_event(SimpleEvent(EVT_GLCANVAS_UPDATE_BED_SHAPE));
@ -1514,19 +1503,12 @@ void GLCanvas3D::render()
// draw overlays
_render_overlays();
#if ENABLE_RENDER_STATISTICS
if (wxGetApp().plater()->is_render_statistic_dialog_visible()) {
ImGuiWrapper& imgui = *wxGetApp().imgui();
imgui.begin(std::string("Render statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
imgui.text("Last frame:");
imgui.text("FPS (SwapBuffers() calls per second):");
ImGui::SameLine();
int64_t average = m_render_stats.get_average();
imgui.text(std::to_string(average));
ImGui::SameLine();
imgui.text("ms");
imgui.text("FPS:");
ImGui::SameLine();
imgui.text(std::to_string((average == 0) ? 0 : static_cast<int>(1000.0f / static_cast<float>(average))));
imgui.text(std::to_string(m_render_stats.get_fps_and_reset_if_needed()));
ImGui::Separator();
imgui.text("Compressed textures:");
ImGui::SameLine();
@ -1536,7 +1518,6 @@ void GLCanvas3D::render()
imgui.text(std::to_string(OpenGLManager::get_gl_info().get_max_tex_size()));
imgui.end();
}
#endif // ENABLE_RENDER_STATISTICS
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
if (wxGetApp().is_editor() && wxGetApp().plater()->is_view3D_shown())
@ -1583,11 +1564,7 @@ void GLCanvas3D::render()
wxGetApp().imgui()->render();
m_canvas->SwapBuffers();
#if ENABLE_RENDER_STATISTICS
auto end_time = std::chrono::high_resolution_clock::now();
m_render_stats.add_frame(std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count());
#endif // ENABLE_RENDER_STATISTICS
m_render_stats.increment_fps_counter();
}
void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params, Camera::EType camera_type)
@ -1625,14 +1602,17 @@ void GLCanvas3D::delete_selected()
m_selection.erase();
}
void GLCanvas3D::ensure_on_bed(unsigned int object_idx)
void GLCanvas3D::ensure_on_bed(unsigned int object_idx, bool allow_negative_z)
{
if (allow_negative_z)
return;
typedef std::map<std::pair<int, int>, double> InstancesToZMap;
InstancesToZMap instances_min_z;
for (GLVolume* volume : m_volumes.volumes) {
if (volume->object_idx() == (int)object_idx && !volume->is_modifier) {
double min_z = volume->transformed_convex_hull_bounding_box().min(2);
double min_z = volume->transformed_convex_hull_bounding_box().min.z();
std::pair<int, int> instance = std::make_pair(volume->object_idx(), volume->instance_idx());
InstancesToZMap::iterator it = instances_min_z.find(instance);
if (it == instances_min_z.end())
@ -2189,6 +2169,10 @@ void GLCanvas3D::bind_event_handlers()
m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this);
m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this);
m_canvas->Bind(EVT_GLCANVAS_RENDER_TIMER, &GLCanvas3D::on_render_timer, this);
m_toolbar_highlighter.set_timer_owner(m_canvas, 0);
m_canvas->Bind(EVT_GLCANVAS_TOOLBAR_HIGHLIGHTER_TIMER, [this](wxTimerEvent&) { m_toolbar_highlighter.blink(); });
m_gizmo_highlighter.set_timer_owner(m_canvas, 0);
m_canvas->Bind(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, [this](wxTimerEvent&) { m_gizmo_highlighter.blink(); });
m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this);
m_canvas->Bind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this);
m_canvas->Bind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this);
@ -2419,10 +2403,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; }
case 'B':
case 'b': { zoom_to_bed(); break; }
#if ENABLE_GCODE_WINDOW
case 'C':
case 'c': { m_gcode_viewer.toggle_gcode_window_visibility(); m_dirty = true; request_extra_frame(); break; }
#endif // ENABLE_GCODE_WINDOW
case 'E':
case 'e': { m_labels.show(!m_labels.is_shown()); m_dirty = true; break; }
case 'G':
@ -2449,8 +2431,8 @@ void GLCanvas3D::on_char(wxKeyEvent& evt)
case 'O':
case 'o': { _update_camera_zoom(-1.0); break; }
#if ENABLE_RENDER_PICKING_PASS
case 'P':
case 'p': {
case 'T':
case 't': {
m_show_picking_texture = !m_show_picking_texture;
m_dirty = true;
break;
@ -2603,15 +2585,11 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
{
if (!m_gizmos.on_key(evt)) {
if (evt.GetEventType() == wxEVT_KEY_UP) {
#if ENABLE_RENDER_STATISTICS
if (evt.ShiftDown() && evt.ControlDown() && keyCode == WXK_SPACE) {
wxGetApp().plater()->toggle_render_statistic_dialog();
m_dirty = true;
}
if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) {
#else
if (m_tab_down && keyCode == WXK_TAB && !evt.HasAnyModifiers()) {
#endif // ENABLE_RENDER_STATISTICS
// Enable switching between 3D and Preview with Tab
// m_canvas->HandleAsNavigationKey(evt); // XXX: Doesn't work in some cases / on Linux
post_event(SimpleEvent(EVT_GLCANVAS_TAB));
@ -2969,6 +2947,20 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
return;
}
#if ENABLE_SINKING_CONTOURS
for (GLVolume* volume : m_volumes.volumes) {
volume->force_sinking_contours = false;
}
auto show_sinking_contours = [this]() {
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
for (unsigned int idx : idxs) {
m_volumes.volumes[idx]->force_sinking_contours = true;
}
m_dirty = true;
};
#endif // ENABLE_SINKING_CONTOURS
if (m_gizmos.on_mouse(evt)) {
if (wxWindow::FindFocus() != m_canvas)
// Grab keyboard focus for input in gizmo dialogs.
@ -2993,6 +2985,21 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
default: { break; }
}
}
#if ENABLE_SINKING_CONTOURS
else if (evt.Dragging()) {
switch (m_gizmos.get_current_type())
{
case GLGizmosManager::EType::Move:
case GLGizmosManager::EType::Scale:
case GLGizmosManager::EType::Rotate:
{
show_sinking_contours();
break;
}
default: { break; }
}
}
#endif // ENABLE_SINKING_CONTOURS
return;
}
@ -3302,6 +3309,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
else
evt.Skip();
#if ENABLE_SINKING_CONTOURS
if (m_moving)
show_sinking_contours();
#endif // ENABLE_SINKING_CONTOURS
#ifdef __WXMSW__
if (on_enter_workaround)
m_mouse.position = Vec2d(-1., -1.);
@ -3405,37 +3417,22 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
wipe_tower_origin = v->get_volume_offset();
}
#if ENABLE_ALLOW_NEGATIVE_Z
// Fixes flying instances
#else
// Fixes sinking/flying instances
#endif // ENABLE_ALLOW_NEGATIVE_Z
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
const double shift_z = m->get_instance_min_z(i.second);
#if DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
if (current_printer_technology() == ptSLA || shift_z > SINKING_Z_THRESHOLD) {
#else
if (shift_z > 0.0) {
#endif // DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA
const Vec3d shift(0.0, 0.0, -shift_z);
#else
const Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
#endif // ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
}
#if ENABLE_ALLOW_NEGATIVE_Z
// if the selection is not valid to allow for layer editing after the move, we need to turn off the tool if it is running
// similar to void Plater::priv::selection_changed()
if (!wxGetApp().plater()->can_layers_editing() && is_layers_editing_enabled())
post_event(SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING));
#endif // ENABLE_ALLOW_NEGATIVE_Z
if (object_moved)
post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_MOVED));
@ -3456,7 +3453,6 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
#if ENABLE_ALLOW_NEGATIVE_Z
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
@ -3467,7 +3463,6 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
}
}
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
std::set<std::pair<int, int>> done; // keeps track of modified instances
@ -3505,19 +3500,15 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
double shift_z = m->get_instance_min_z(i.second);
const double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) {
Vec3d shift(0.0, 0.0, -shift_z);
#else
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
#endif // ENABLE_ALLOW_NEGATIVE_Z
const Vec3d shift(0.0, 0.0, -shift_z);
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
}
if (!done.empty())
@ -3534,7 +3525,6 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
#if ENABLE_ALLOW_NEGATIVE_Z
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
@ -3545,7 +3535,6 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
}
}
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
std::set<std::pair<int, int>> done; // keeps track of modified instances
@ -3580,19 +3569,14 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
#if ENABLE_ALLOW_NEGATIVE_Z
double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) {
Vec3d shift(0.0, 0.0, -shift_z);
#else
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
#endif // ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
#if ENABLE_ALLOW_NEGATIVE_Z
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
#endif // ENABLE_ALLOW_NEGATIVE_Z
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
}
if (!done.empty())
@ -3618,14 +3602,24 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
for (int i = 0; i < static_cast<int>(m_model->objects.size()); ++i) {
const ModelObject* obj = m_model->objects[i];
for (int j = 0; j < static_cast<int>(obj->instances.size()); ++j) {
min_zs[{ i, j }] = obj->instance_bounding_box(j).min.z();
}
}
}
std::set<std::pair<int, int>> done; // keeps track of modified instances
Selection::EMode selection_mode = m_selection.get_mode();
for (const GLVolume* v : m_volumes.volumes)
{
for (const GLVolume* v : m_volumes.volumes) {
int object_idx = v->object_idx();
if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx))
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
int instance_idx = v->instance_idx();
@ -3635,8 +3629,7 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
// Mirror instances/volumes
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr)
{
if (model_object != nullptr) {
if (selection_mode == Selection::Instance)
model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror());
else if (selection_mode == Selection::Volume)
@ -3647,12 +3640,16 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
}
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done)
{
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second));
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) {
Vec3d shift(0.0, 0.0, -shift_z);
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
}
post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
@ -3881,6 +3878,15 @@ void GLCanvas3D::update_sequential_clearance()
set_sequential_print_clearance_polygons(polygons);
}
bool GLCanvas3D::is_object_sinking(int object_idx) const
{
for (const GLVolume* v : m_volumes.volumes) {
if (v->object_idx() == object_idx && v->is_sinking())
return true;
}
return false;
}
bool GLCanvas3D::_is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@ -4425,6 +4431,29 @@ bool GLCanvas3D::_init_main_toolbar()
m_main_toolbar.set_enabled(false);
return true;
}
// init arrow
BackgroundTexture::Metadata arrow_data;
arrow_data.filename = "toolbar_arrow.png";
// arrow_data.filename = "toolbar_arrow.svg";
//arrow_data.left = 16;
//arrow_data.top = 16;
//arrow_data.right = 16;
//arrow_data.bottom = 16;
arrow_data.left = 0;
arrow_data.top = 0;
arrow_data.right = 0;
arrow_data.bottom = 0;
if (!m_main_toolbar.init_arrow(arrow_data))
{
BOOST_LOG_TRIVIAL(error) << "Main toolbar failed to load arrow texture.";
}
if (!m_gizmos.init_arrow(arrow_data))
{
BOOST_LOG_TRIVIAL(error) << "Gizmos manager failed to load arrow texture.";
}
// m_main_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
m_main_toolbar.set_layout_type(GLToolbar::Layout::Horizontal);
@ -4744,13 +4773,11 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
if (m_canvas == nullptr && m_context == nullptr)
return;
#if ENABLE_SCROLLABLE_LEGEND
const std::array<unsigned int, 2> new_size = { w, h };
if (m_old_size == new_size)
return;
m_old_size = new_size;
#endif // ENABLE_SCROLLABLE_LEGEND
auto *imgui = wxGetApp().imgui();
imgui->set_display_size(static_cast<float>(w), static_cast<float>(h));
@ -4761,9 +4788,7 @@ void GLCanvas3D::_resize(unsigned int w, unsigned int h)
imgui->set_scaling(font_size, m_canvas->GetContentScaleFactor(), 1.0f);
#endif
#if ENABLE_SCROLLABLE_LEGEND
this->request_extra_frame();
#endif // ENABLE_SCROLLABLE_LEGEND
// ensures that this canvas is current
_set_current();
@ -4842,21 +4867,30 @@ void GLCanvas3D::_picking_pass()
if (m_camera_clipping_plane.is_active())
::glDisable(GL_CLIP_PLANE0);
_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
m_gizmos.render_current_gizmo_for_picking_pass();
if (m_multisample_allowed)
glsafe(::glEnable(GL_MULTISAMPLE));
int volume_id = -1;
int gizmo_id = -1;
GLubyte color[4] = { 0, 0, 0, 0 };
const Size& cnv_size = get_canvas_size();
bool inside = 0 <= m_mouse.position(0) && m_mouse.position(0) < cnv_size.get_width() && 0 <= m_mouse.position(1) && m_mouse.position(1) < cnv_size.get_height();
if (inside) {
glsafe(::glReadPixels(m_mouse.position(0), cnv_size.get_height() - m_mouse.position(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color));
if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3])
// Only non-interpolated colors are valid, those have their lowest three bits zeroed.
volume_id = color[0] + (color[1] << 8) + (color[2] << 16);
if (picking_checksum_alpha_channel(color[0], color[1], color[2]) == color[3]) {
// Only non-interpolated colors are valid, those have their lowest three bits zeroed.
// we reserve color = (0,0,0) for occluders (as the printbed)
// volumes' id are shifted by 1
// see: _render_volumes_for_picking()
volume_id = color[0] + (color[1] << 8) + (color[2] << 16) - 1;
// gizmos' id are instead properly encoded by the color
gizmo_id = color[0] + (color[1] << 8) + (color[2] << 16);
}
}
if (0 <= volume_id && volume_id < (int)m_volumes.volumes.size()) {
// do not add the volume id if any gizmo is active and CTRL is pressed
@ -4865,7 +4899,7 @@ void GLCanvas3D::_picking_pass()
m_gizmos.set_hover_id(-1);
}
else
m_gizmos.set_hover_id(inside && (unsigned int)volume_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - volume_id) : -1);
m_gizmos.set_hover_id(inside && (unsigned int)gizmo_id <= GLGizmoBase::BASE_ID ? ((int)GLGizmoBase::BASE_ID - gizmo_id) : -1);
_update_volumes_hover_state();
}
@ -4888,6 +4922,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_volumes_for_picking();
_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
if (m_multisample_allowed)
glsafe(::glEnable(GL_MULTISAMPLE));
@ -4906,7 +4941,10 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
std::array<GLubyte, 4> data;
// Only non-interpolated colors are valid, those have their lowest three bits zeroed.
bool valid() const { return picking_checksum_alpha_channel(data[0], data[1], data[2]) == data[3]; }
int id() const { return data[0] + (data[1] << 8) + (data[2] << 16); }
// we reserve color = (0,0,0) for occluders (as the printbed)
// volumes' id are shifted by 1
// see: _render_volumes_for_picking()
int id() const { return data[0] + (data[1] << 8) + (data[2] << 16) - 1; }
};
std::vector<Pixel> frame(px_count);
@ -5028,6 +5066,17 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
wxGetApp().plater()->get_bed().render(*this, bottom, scale_factor, show_axes, show_texture);
}
void GLCanvas3D::_render_bed_for_picking(bool bottom)
{
float scale_factor = 1.0;
#if ENABLE_RETINA_GL
scale_factor = m_retina_helper->get_scale_factor();
#endif // ENABLE_RETINA_GL
wxGetApp().plater()->get_bed().render_for_picking(*this, bottom, scale_factor);
}
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
#else
@ -5270,50 +5319,30 @@ void GLCanvas3D::_render_volumes_for_picking() const
{
static const GLfloat INV_255 = 1.0f / 255.0f;
#if ENABLE_ALLOW_NEGATIVE_Z
auto* shader = wxGetApp().get_shader("picking");
if (!shader)
return;
#endif // ENABLE_ALLOW_NEGATIVE_Z
// do not cull backfaces to show broken geometry, if any
glsafe(::glDisable(GL_CULL_FACE));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
#if ENABLE_ALLOW_NEGATIVE_Z
shader->start_using();
shader->set_uniform("viewed_from_top", wxGetApp().plater()->get_camera().is_looking_downward());
#endif // ENABLE_ALLOW_NEGATIVE_Z
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
for (size_t type = 0; type < 2; ++ type) {
GLVolumeWithIdAndZList to_render = volumes_to_render(m_volumes.volumes, (type == 0) ? GLVolumeCollection::ERenderType::Opaque : GLVolumeCollection::ERenderType::Transparent, view_matrix);
for (const GLVolumeWithIdAndZ& volume : to_render)
if (!volume.first->disabled && (volume.first->composite_id.volume_id >= 0 || m_render_sla_auxiliaries)) {
// Object picking mode. Render the object with a color encoding the object index.
unsigned int id = volume.second.first;
unsigned int r = (id & (0x000000FF << 0)) << 0;
// we reserve color = (0,0,0) for occluders (as the printbed)
// so we shift volumes' id by 1 to get the proper color
unsigned int id = 1 + volume.second.first;
unsigned int r = (id & (0x000000FF << 0)) << 0;
unsigned int g = (id & (0x000000FF << 8)) >> 8;
unsigned int b = (id & (0x000000FF << 16)) >> 16;
unsigned int a = picking_checksum_alpha_channel(r, g, b);
#if ENABLE_ALLOW_NEGATIVE_Z
std::array<float, 4> color = { (float)r * INV_255, (float)g * INV_255, (float)b * INV_255, (float)a * INV_255 };
shader->set_uniform("uniform_color", color);
shader->set_uniform("world_matrix", volume.first->world_matrix());
#else
glsafe(::glColor4f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255, (GLfloat)a * INV_255));
#endif // ENABLE_ALLOW_NEGATIVE_Z
volume.first->render();
}
}
#if ENABLE_ALLOW_NEGATIVE_Z
shader->stop_using();
#endif // ENABLE_ALLOW_NEGATIVE_Z
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
@ -5339,6 +5368,11 @@ void GLCanvas3D::_render_gizmos_overlay()
#endif /* __WXMSW__ */
m_gizmos.render_overlay();
if (m_gizmo_highlighter.m_render_arrow)
{
m_gizmos.render_arrow(*this, m_gizmo_highlighter.m_gizmo_type);
}
}
void GLCanvas3D::_render_main_toolbar()
@ -5356,6 +5390,10 @@ void GLCanvas3D::_render_main_toolbar()
m_main_toolbar.set_position(top, left);
m_main_toolbar.render(*this);
if (m_toolbar_highlighter.m_render_arrow)
{
m_main_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item);
}
}
void GLCanvas3D::_render_undoredo_toolbar()
@ -5639,6 +5677,11 @@ void GLCanvas3D::_update_volumes_hover_state()
}
}
}
#if ENABLE_SINKING_CONTOURS
else if (volume.selected)
volume.hover = GLVolume::HS_Hover;
#endif // ENABLE_SINKING_CONTOURS
}
}
@ -6518,6 +6561,24 @@ bool GLCanvas3D::_deactivate_collapse_toolbar_items()
return false;
}
void GLCanvas3D::highlight_toolbar_item(const std::string& item_name)
{
GLToolbarItem* item = m_main_toolbar.get_item(item_name);
if (!item)
item = m_undoredo_toolbar.get_item(item_name);
if (!item || !item->is_visible())
return;
m_toolbar_highlighter.init(item, this);
}
void GLCanvas3D::highlight_gizmo(const std::string& gizmo_name)
{
GLGizmosManager::EType gizmo = m_gizmos.get_gizmo_from_name(gizmo_name);
if(gizmo == GLGizmosManager::EType::Undefined)
return;
m_gizmo_highlighter.init(&m_gizmos, gizmo, this);
}
const Print* GLCanvas3D::fff_print() const
{
return (m_process == nullptr) ? nullptr : m_process->fff_print();
@ -6537,10 +6598,119 @@ void GLCanvas3D::WipeTowerInfo::apply_wipe_tower() const
wxGetApp().get_tab(Preset::TYPE_PRINT)->load_config(cfg);
}
void GLCanvas3D::RenderTimer::Notify()
void GLCanvas3D::RenderTimer::Notify()
{
wxPostEvent((wxEvtHandler*)GetOwner(), RenderTimerEvent( EVT_GLCANVAS_RENDER_TIMER, *this));
}
void GLCanvas3D::ToolbarHighlighterTimer::Notify()
{
wxPostEvent((wxEvtHandler*)GetOwner(), ToolbarHighlighterTimerEvent(EVT_GLCANVAS_TOOLBAR_HIGHLIGHTER_TIMER, *this));
}
void GLCanvas3D::GizmoHighlighterTimer::Notify()
{
wxPostEvent((wxEvtHandler*)GetOwner(), GizmoHighlighterTimerEvent(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, *this));
}
void GLCanvas3D::ToolbarHighlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
{
m_timer.SetOwner(owner, timerid);
}
void GLCanvas3D::ToolbarHighlighter::init(GLToolbarItem* toolbar_item, GLCanvas3D* canvas)
{
if (m_timer.IsRunning())
invalidate();
if (!toolbar_item || !canvas)
return;
m_timer.Start(300, false);
m_toolbar_item = toolbar_item;
m_canvas = canvas;
}
void GLCanvas3D::ToolbarHighlighter::invalidate()
{
m_timer.Stop();
if (m_toolbar_item) {
m_toolbar_item->set_highlight(GLToolbarItem::EHighlightState::NotHighlighted);
}
m_toolbar_item = nullptr;
m_blink_counter = 0;
m_render_arrow = false;
}
void GLCanvas3D::ToolbarHighlighter::blink()
{
if (m_toolbar_item) {
char state = m_toolbar_item->get_highlight();
if (state != (char)GLToolbarItem::EHighlightState::HighlightedShown)
m_toolbar_item->set_highlight(GLToolbarItem::EHighlightState::HighlightedShown);
else
m_toolbar_item->set_highlight(GLToolbarItem::EHighlightState::HighlightedHidden);
m_render_arrow = !m_render_arrow;
m_canvas->set_as_dirty();
}
else
invalidate();
if ((++m_blink_counter) >= 11)
invalidate();
}
void GLCanvas3D::GizmoHighlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
{
m_timer.SetOwner(owner, timerid);
}
void GLCanvas3D::GizmoHighlighter::init(GLGizmosManager* manager, GLGizmosManager::EType gizmo, GLCanvas3D* canvas)
{
if (m_timer.IsRunning())
invalidate();
if (!gizmo || !canvas)
return;
m_timer.Start(300, false);
m_gizmo_manager = manager;
m_gizmo_type = gizmo;
m_canvas = canvas;
}
void GLCanvas3D::GizmoHighlighter::invalidate()
{
m_timer.Stop();
if (m_gizmo_manager) {
m_gizmo_manager->set_highlight(GLGizmosManager::EType::Undefined, false);
}
m_gizmo_manager = nullptr;
m_gizmo_type = GLGizmosManager::EType::Undefined;
m_blink_counter = 0;
m_render_arrow = false;
}
void GLCanvas3D::GizmoHighlighter::blink()
{
if (m_gizmo_manager) {
if (m_blink_counter % 2 == 0)
m_gizmo_manager->set_highlight(m_gizmo_type, true);
else
m_gizmo_manager->set_highlight(m_gizmo_type, false);
m_render_arrow = !m_render_arrow;
m_canvas->set_as_dirty();
}
else
invalidate();
if ((++m_blink_counter) >= 11)
invalidate();
}
} // namespace GUI
} // namespace Slic3r

View File

@ -93,6 +93,43 @@ private:
wxTimer* m_timer;
};
class ToolbarHighlighterTimerEvent : public wxEvent
{
public:
ToolbarHighlighterTimerEvent(wxEventType type, wxTimer& timer)
: wxEvent(timer.GetId(), type),
m_timer(&timer)
{
SetEventObject(timer.GetOwner());
}
int GetInterval() const { return m_timer->GetInterval(); }
wxTimer& GetTimer() const { return *m_timer; }
virtual wxEvent* Clone() const { return new ToolbarHighlighterTimerEvent(*this); }
virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_TIMER; }
private:
wxTimer* m_timer;
};
class GizmoHighlighterTimerEvent : public wxEvent
{
public:
GizmoHighlighterTimerEvent(wxEventType type, wxTimer& timer)
: wxEvent(timer.GetId(), type),
m_timer(&timer)
{
SetEventObject(timer.GetOwner());
}
int GetInterval() const { return m_timer->GetInterval(); }
wxTimer& GetTimer() const { return *m_timer; }
virtual wxEvent* Clone() const { return new GizmoHighlighterTimerEvent(*this); }
virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_TIMER; }
private:
wxTimer* m_timer;
};
wxDECLARE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
@ -137,6 +174,8 @@ wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RELOAD_FROM_DISK, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RENDER_TIMER, wxTimerEvent/*RenderTimerEvent*/);
wxDECLARE_EVENT(EVT_GLCANVAS_TOOLBAR_HIGHLIGHTER_TIMER, wxTimerEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, wxTimerEvent);
class GLCanvas3D
{
@ -305,25 +344,27 @@ class GLCanvas3D
ObjectClashed
};
#if ENABLE_RENDER_STATISTICS
class RenderStats
{
std::queue<std::pair<int64_t, int64_t>> m_frames;
int64_t m_curr_total{ 0 };
private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_measuring_start;
int m_fps_out = -1;
int m_fps_running = 0;
public:
void add_frame(int64_t frame) {
int64_t now = GLCanvas3D::timestamp_now();
if (!m_frames.empty() && now - m_frames.front().first > 1000) {
m_curr_total -= m_frames.front().second;
m_frames.pop();
void increment_fps_counter() { ++m_fps_running; }
int get_fps() { return m_fps_out; }
int get_fps_and_reset_if_needed() {
auto cur_time = std::chrono::high_resolution_clock::now();
int elapsed_ms = std::chrono::duration_cast<std::chrono::milliseconds>(cur_time-m_measuring_start).count();
if (elapsed_ms > 1000 || m_fps_out == -1) {
m_measuring_start = cur_time;
m_fps_out = int (1000. * m_fps_running / elapsed_ms);
m_fps_running = 0;
}
m_curr_total += frame;
m_frames.push({ now, frame });
return m_fps_out;
}
int64_t get_average() const { return m_frames.empty() ? 0 : m_curr_total / m_frames.size(); }
};
#endif // ENABLE_RENDER_STATISTICS
class Labels
{
@ -376,6 +417,16 @@ class GLCanvas3D
virtual void Notify() override;
};
class ToolbarHighlighterTimer : public wxTimer {
private:
virtual void Notify() override;
};
class GizmoHighlighterTimer : public wxTimer {
private:
virtual void Notify() override;
};
public:
enum ECursorType : unsigned char
{
@ -427,9 +478,7 @@ private:
Model* m_model;
BackgroundSlicingProcess *m_process;
#if ENABLE_SCROLLABLE_LEGEND
std::array<unsigned int, 2> m_old_size{ 0, 0 };
#endif // ENABLE_SCROLLABLE_LEGEND
// Screen is only refreshed from the OnIdle handler if it is dirty.
bool m_dirty;
@ -457,9 +506,7 @@ private:
bool m_show_picking_texture;
#endif // ENABLE_RENDER_PICKING_PASS
#if ENABLE_RENDER_STATISTICS
RenderStats m_render_stats;
#endif // ENABLE_RENDER_STATISTICS
int m_imgui_undo_redo_hovered_pos{ -1 };
int m_mouse_wheel{ 0 };
@ -519,6 +566,38 @@ private:
SequentialPrintClearance m_sequential_print_clearance;
bool m_sequential_print_clearance_first_displacement{ true };
struct ToolbarHighlighter
{
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
void init(GLToolbarItem* toolbar_item, GLCanvas3D* canvas);
void blink();
void invalidate();
bool m_render_arrow{ false };
GLToolbarItem* m_toolbar_item{ nullptr };
private:
GLCanvas3D* m_canvas{ nullptr };
int m_blink_counter{ 0 };
ToolbarHighlighterTimer m_timer;
}
m_toolbar_highlighter;
struct GizmoHighlighter
{
void set_timer_owner(wxEvtHandler* owner, int timerid = wxID_ANY);
void init(GLGizmosManager* manager, GLGizmosManager::EType gizmo, GLCanvas3D* canvas);
void blink();
void invalidate();
bool m_render_arrow{ false };
GLGizmosManager::EType m_gizmo_type;
private:
GLGizmosManager* m_gizmo_manager{ nullptr };
GLCanvas3D* m_canvas{ nullptr };
int m_blink_counter{ 0 };
GizmoHighlighterTimer m_timer;
}
m_gizmo_highlighter;
public:
explicit GLCanvas3D(wxGLCanvas* canvas);
~GLCanvas3D();
@ -544,10 +623,8 @@ public:
const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); }
void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); }
#if ENABLE_GCODE_WINDOW
void start_mapping_gcode_window();
void stop_mapping_gcode_window();
#endif // ENABLE_GCODE_WINDOW
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
@ -625,7 +702,7 @@ public:
void select_all();
void deselect_all();
void delete_selected();
void ensure_on_bed(unsigned int object_idx);
void ensure_on_bed(unsigned int object_idx, bool allow_negative_z);
bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); }
GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); }
@ -638,6 +715,10 @@ public:
void set_toolpath_view_type(GCodeViewer::EViewType type);
void set_volumes_z_range(const std::array<double, 2>& range);
void set_toolpaths_z_range(const std::array<unsigned int, 2>& range);
#if ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<CustomGCode::Item>& get_custom_gcode_per_print_z() { return m_gcode_viewer.get_custom_gcode_per_print_z(); }
size_t get_gcode_extruders_count() { return m_gcode_viewer.get_extruders_count(); }
#endif // ENABLE_FIX_IMPORTING_COLOR_PRINT_VIEW_INTO_GCODEVIEWER
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
std::vector<int> load_object(const Model& model, int obj_idx);
@ -744,6 +825,9 @@ public:
void use_slope(bool use) { m_slope.use(use); }
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
void highlight_toolbar_item(const std::string& item_name);
void highlight_gizmo(const std::string& gizmo_name);
ArrangeSettings get_arrange_settings() const {
const ArrangeSettings &settings = get_arrange_settings(this);
ArrangeSettings ret = settings;
@ -789,9 +873,9 @@ public:
const Print* fff_print() const;
const SLAPrint* sla_print() const;
#if ENABLE_SCROLLABLE_LEGEND
void reset_old_size() { m_old_size = { 0, 0 }; }
#endif // ENABLE_SCROLLABLE_LEGEND
bool is_object_sinking(int object_idx) const;
private:
bool _is_shown_on_screen() const;
@ -816,6 +900,7 @@ private:
void _rectangular_selection_picking_pass();
void _render_background() const;
void _render_bed(bool bottom, bool show_axes);
void _render_bed_for_picking(bool bottom);
#if ENABLE_DELAYED_TRANSPARENT_VOLUMES_RENDERING
void _render_objects(GLVolumeCollection::ERenderType type);
#else

View File

@ -7,6 +7,9 @@
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
#if ENABLE_SINKING_CONTOURS
#include "libslic3r/Polygon.hpp"
#endif // ENABLE_SINKING_CONTOURS
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string/predicate.hpp>
@ -87,6 +90,35 @@ void GLModel::init_from(const TriangleMesh& mesh)
m_render_data.emplace_back(data);
}
#if ENABLE_SINKING_CONTOURS
void GLModel::init_from(const Polygons& polygons, float z)
{
auto append_polygon = [](const Polygon& polygon, float z, GUI::GLModel::InitializationData& data) {
if (!polygon.empty()) {
GUI::GLModel::InitializationData::Entity entity;
entity.type = GUI::GLModel::PrimitiveType::LineLoop;
// contour
entity.positions.reserve(polygon.size() + 1);
entity.indices.reserve(polygon.size() + 1);
unsigned int id = 0;
for (const Point& p : polygon) {
Vec3f position = unscale(p.x(), p.y(), 0.0).cast<float>();
position.z() = z;
entity.positions.emplace_back(position);
entity.indices.emplace_back(id++);
}
data.entities.emplace_back(entity);
}
};
InitializationData init_data;
for (const Polygon& polygon : polygons) {
append_polygon(polygon, z, init_data);
}
init_from(init_data);
}
#endif // ENABLE_SINKING_CONTOURS
bool GLModel::init_from_file(const std::string& filename)
{
if (!boost::filesystem::exists(filename))

Some files were not shown because too many files have changed in this diff Show More