diff --git a/build_linux.sh b/build_linux.sh index eb3c1bc920..2af0f63599 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -30,7 +30,7 @@ function check_available_memory_and_disk() { } function usage() { - echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-h][-i][-j N][-p][-r][-s][-u]" + echo "Usage: ./${SCRIPT_NAME} [-1][-b][-c][-d][-h][-i][-j N][-p][-r][-s][-u][-l]" echo " -1: limit builds to one core (where possible)" echo " -j N: limit builds to N cores (where possible)" echo " -b: build in debug mode" @@ -43,6 +43,7 @@ function usage() { echo " -r: skip RAM and disk checks (low RAM compiling)" echo " -s: build the Orca Slicer (optional)" echo " -u: install system dependencies (asks for sudo password; build prerequisite)" + echo " -l: use Clang instead of GCC (default: GCC)" echo "For a first use, you want to './${SCRIPT_NAME} -u'" echo " and then './${SCRIPT_NAME} -dsi'" } @@ -50,7 +51,7 @@ function usage() { SLIC3R_PRECOMPILED_HEADERS="ON" unset name -while getopts ":1j:bcCdhiprsu" opt ; do +while getopts ":1j:bcCdhiprsul" opt ; do case ${opt} in 1 ) export CMAKE_BUILD_PARALLEL_LEVEL=1 @@ -88,6 +89,9 @@ while getopts ":1j:bcCdhiprsu" opt ; do u ) UPDATE_LIB="1" ;; + l ) + USE_CLANG="1" + ;; esac done @@ -139,6 +143,11 @@ if ! [[ -n "${SKIP_RAM_CHECK}" ]] ; then check_available_memory_and_disk fi +export CMAKE_C_CXX_COMPILER_CLANG="" +if [[ -n "${USE_CLANG}" ]] ; then + export CMAKE_C_CXX_COMPILER_CLANG="-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++" +fi + if [[ -n "${BUILD_DEPS}" ]] ; then echo "Configuring dependencies..." BUILD_ARGS="${DEPS_EXTRA_BUILD_ARGS} -DDEP_WX_GTK3=ON" @@ -155,13 +164,13 @@ if [[ -n "${BUILD_DEPS}" ]] ; then if [ ! -d "deps/build/release" ] ; then mkdir deps/build/release fi - cmake -S deps -B deps/build/release -DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} -G Ninja -DDESTDIR="${SCRIPT_PATH}/deps/build/destdir" -DDEP_DOWNLOAD_DIR="${SCRIPT_PATH}/deps/DL_CACHE" ${COLORED_OUTPUT} ${BUILD_ARGS} + cmake ${CMAKE_C_CXX_COMPILER_CLANG} -S deps -B deps/build/release -DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} -G Ninja -DDESTDIR="${SCRIPT_PATH}/deps/build/destdir" -DDEP_DOWNLOAD_DIR="${SCRIPT_PATH}/deps/DL_CACHE" ${COLORED_OUTPUT} ${BUILD_ARGS} cmake --build deps/build/release BUILD_ARGS="${BUILD_ARGS} -DCMAKE_BUILD_TYPE=Debug" fi - echo "cmake -S deps -B deps/build -G Ninja ${BUILD_ARGS}" - cmake -S deps -B deps/build -G Ninja ${COLORED_OUTPUT} ${BUILD_ARGS} + echo "cmake -S deps -B deps/build ${CMAKE_C_CXX_COMPILER_CLANG} -G Ninja ${BUILD_ARGS}" + cmake -S deps -B deps/build ${CMAKE_C_CXX_COMPILER_CLANG} -G Ninja ${COLORED_OUTPUT} ${BUILD_ARGS} cmake --build deps/build fi @@ -180,7 +189,7 @@ if [[ -n "${BUILD_ORCA}" ]] ; then BUILD_ARGS="${BUILD_ARGS} -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0" fi - CMAKE_CMD="cmake -S . -B build -G Ninja \ + CMAKE_CMD="cmake -S . -B build ${CMAKE_C_CXX_COMPILER_CLANG} -G Ninja \ -DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} \ -DCMAKE_PREFIX_PATH="${SCRIPT_PATH}/deps/build/destdir/usr/local" \ -DSLIC3R_STATIC=1 \ diff --git a/doc/Home.md b/doc/Home.md index 9d775f3cb6..f6ea7bc1ac 100644 --- a/doc/Home.md +++ b/doc/Home.md @@ -2,32 +2,56 @@ Orca slicer is a powerful open source slicer for FFF (FDM) 3D Printers. This wiki page aims to provide an detailed explanation of the slicer settings, how to get the most out of them as well as how to calibrate and setup your printer. -- [Prepare](#prepare) -- [Print Settings, Tips and Tricks](#print-settings-tips-and-tricks) - - [Quality Settings](#quality-settings) - - [Speed Settings](#speed-settings) - - [Strength Settings](#strength-settings) +- [Printer Settings](#printer-settings) - [Material Settings](#material-settings) - - [Printer Settings](#printer-settings) -- [Printer Calibration](#printer-calibration) +- [Prepare](#prepare) +- [Process Settings](#process-settings) + - [Quality Settings](#quality-settings) + - [Strength Settings](#strength-settings) + - [Speed Settings](#speed-settings) + - [Support Settings](#support-settings) + - [Multimaterial Settings](#multimaterial-settings) + - [Others Settings](#others-settings) +- [Calibrations](#calibrations) - [Developer Section](#developer-section) > [!NOTE] > The Wiki is **Work In Progress** so bear with us while we get it up and running! > Please consider contributing to the wiki following the [How to contribute to the wiki](How-to-wiki) guide. +## Printer Settings + +![printer-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/printer-preset.png) + +- [Air filtration/Exhaust fan handling](air-filtration) +- [Auxiliary fan handling](Auxiliary-fan) +- [Chamber temperature control](chamber-temperature) +- [Adaptive Bed Mesh](adaptive-bed-mesh) +- [Using different bed types in Orca](bed-types) + +## Material Settings + +![filament-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/filament-preset.png) + +- [Single Extruder Multimaterial](semm) +- [Pellet Printers (pellet flow coefficient)](pellet-flow-coefficient) + ## Prepare First steps to prepare your model/s for printing. - [STL Transformation](stl-transformation) -## Print Settings, Tips and Tricks +## Process Settings + +![process-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process-preset.png) The below sections provide a detailed settings explanation as well as tips and tricks in setting these for optimal print results. ### Quality Settings +![process-quality](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-quality.png?raw=true) + - [Layer Height Settings](quality_settings_layer_height) - [Line Width Settings](quality_settings_line_width) - [Seam Settings](quality_settings_seam) @@ -44,28 +68,38 @@ The below sections provide a detailed settings explanation as well as tips and t - [Polyholes](quality_settings_precision#polyholes) - [Wall generator](quality_settings_wall_generator) -### Speed Settings - -- [Extrusion rate smoothing](speed_extrusion_rate_smoothing) - ### Strength Settings +![process-strength](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-strength.png?raw=true) + +- [Top and Bottom Shells](strength_settings_top_bottom_shells) - [Infill](strength_settings_infill) -## Material Settings +### Speed Settings -- [Single Extruder Multimaterial](semm) -- [Pellet Printers (pellet flow coefficient)](pellet-flow-coefficient) +![process-speed](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-speed.png?raw=true) -### Printer Settings +- [Extrusion rate smoothing](speed_settings_extrusion_rate_smoothing) -- [Air filtration/Exhaust fan handling](air-filtration) -- [Auxiliary fan handling](Auxiliary-fan) -- [Chamber temperature control](chamber-temperature) -- [Adaptive Bed Mesh](adaptive-bed-mesh) -- [Using different bed types in Orca](bed-types) +### Support Settings -## Printer Calibration +![process-support](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-support.png?raw=true) + +WIP... + +### Multimaterial Settings + +![process-multimaterial](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-multimaterial.png?raw=true) + +WIP... + +### Others Settings + +![process-others](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process/process-others.png?raw=true) + +WIP... + +## Calibrations The [Calibration Guide](Calibration) outlines Orca’s key calibration tests and their suggested order of execution. diff --git a/doc/calibration/Calibration.md b/doc/calibration/Calibration.md index 5c4e6820cd..c8d8718dae 100644 --- a/doc/calibration/Calibration.md +++ b/doc/calibration/Calibration.md @@ -25,7 +25,7 @@ The recommended order for calibration is as follows: - **[Adaptative Pressure Advance](adaptive-pressure-advance-calib):** This is an advanced calibration technique that can be used to further optimize the pressure advance settings for different print speeds and geometries. - pa-tower + pa-tower 2. **[Retraction](retraction-calib):** Calibrate the retraction settings to minimize stringing and improve print quality. Doing this after Flow and @@ -47,10 +47,9 @@ The recommended order for calibration is as follows: Input_Shaping -### VFA +7. **[VFA](vfa-calib):** A VFA speed test is available to find resonance speeds. -Vertical Fine Artifacts (VFA) are small artifacts that can occur on the surface of a 3D print, particularly in areas where there are sharp corners or changes in direction. These artifacts can be caused by a variety of factors, including mechanical vibrations, resonance, and other factors that can affect the quality of the print. -Because of the nature of these artifacts the methods to reduce them can be mechanical such as changing motors, belts and pulleys or with advanced calibrations such as Jerk/[Junction Deviation](junction-deviation) corrections or [Input Shaping](input-shaping). + vfa_test_print --- @@ -62,4 +61,3 @@ _Credits:_ - _The temp tower model is remixed from [Smart compact temperature calibration tower](https://www.thingiverse.com/thing:2729076)._ - _The max flowrate test was inspired by Stefan (CNC Kitchen), and the model used in the test is a remix of his [Extrusion Test Structure](https://www.printables.com/model/342075-extrusion-test-structure)._ - _ZV Input Shaping is inspired by [Marlin Input Shaping](https://marlinfw.org/docs/features/input_shaping.html) and [Ringing Tower 3D STL](https://marlinfw.org/assets/stl/ringing_tower.stl)._ -- _ChatGPT_ ;) diff --git a/doc/calibration/cornering-calib.md b/doc/calibration/cornering-calib.md index e8d78f5742..f5634eb875 100644 --- a/doc/calibration/cornering-calib.md +++ b/doc/calibration/cornering-calib.md @@ -4,7 +4,7 @@ Cornering is a critical aspect of 3D printing that affects the quality and accur ## Jerk -WIP... TODO: Jerk calibration not implemented yet. +TODO: Jerk calibration not implemented yet. ## Junction Deviation diff --git a/doc/calibration/input-shaping-calib.md b/doc/calibration/input-shaping-calib.md index c2b6f8324c..2624aedf17 100644 --- a/doc/calibration/input-shaping-calib.md +++ b/doc/calibration/input-shaping-calib.md @@ -3,7 +3,10 @@ During high-speed movements, vibrations can cause a phenomenon called "ringing," where periodic ripples appear on the print surface. Input Shaping provides an effective solution by counteracting these vibrations, improving print quality and reducing wear on components without needing to significantly lower print speeds. - [Klipper](#klipper) + - [Resonance Compensation](#resonance-compensation) - [Marlin](#marlin) + - [ZV Input Shaping](#zv-input-shaping) + - [Fixed-Time Motion](#fixed-time-motion) ## Klipper @@ -125,5 +128,4 @@ ZV Input Shaping introduces an anti-vibration signal into the stepper motion for ### Fixed-Time Motion -WIP... -This calibration test is currently under development. See the [Marlin documentation](https://marlinfw.org/docs/gcode/M493.html) for more information. +TODO: This calibration test is currently under development. See the [Marlin documentation](https://marlinfw.org/docs/gcode/M493.html) for more information. diff --git a/doc/calibration/vfa-calib.md b/doc/calibration/vfa-calib.md new file mode 100644 index 0000000000..f449e6baea --- /dev/null +++ b/doc/calibration/vfa-calib.md @@ -0,0 +1,13 @@ +# VFA + +Vertical Fine Artifacts (VFA) are small artifacts that can occur on the surface of a 3D print, particularly in areas where there are sharp corners or changes in direction. These artifacts can be caused by a variety of factors, including mechanical vibrations, resonance, and other factors that can affect the quality of the print. + +Because of the nature of these artifacts the methods to reduce them can be mechanical such as changing motors, belts and pulleys or with advanced calibrations such as [Jerk/Junction Deviation](cornering-calib) corrections or [Input Shaping](input-shaping-calib). + +## VFA Test + +OrcaSlicer's VFA test is used to identify the print speed that minimizes ringing artifacts. It prints a tower with walls at key angles while gradually increasing the print speed. The goal is to find the speed at which VFA artifacts are least visible, revealing the optimal range for clean surfaces. + +![vfa_test_menu](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/vfa/vfa_test_menu.png?raw=true) + +![vfa_test_print](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/vfa/vfa_test_print.jpg?raw=true) \ No newline at end of file diff --git a/doc/calibration/volumetric-speed-calib.md b/doc/calibration/volumetric-speed-calib.md index e904e3e50c..6eb40f5203 100644 --- a/doc/calibration/volumetric-speed-calib.md +++ b/doc/calibration/volumetric-speed-calib.md @@ -1,4 +1,4 @@ -# Max Volumetric speed +# Max Volumetric Speed (FlowRate) Calibration This is a test designed to calibrate the maximum volumetric speed of the specific filament. The generic or 3rd party filament types may not have the correct volumetric flow rate set in the filament. This test will help you to find the maximum volumetric speed of the filament. @@ -6,15 +6,15 @@ You will be promted to enter the settings for the test: start volumetric speed, Once printed, take note of where the layers begin to fail and where the quality begins to suffer. Pay attention to changes from matte to shiny as well. -![vmf_measurement_point](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images//vmf_measurement_point.jpg?raw=true) +![mvf_measurement_point](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/mvf/mvf_measurement_point.jpg?raw=true) Using calipers or a ruler, measure the height of the print at that point. Use the following calculation to determine the correct max flow value: `start + (height-measured * step)` . For example in the photo below, and using the default setting values, the print quality began to suffer at 19mm measured, so the calculation would be: `5 + (19 * 0.5)` , or `13mm³/s` using the default values. Enter your number into the "Max volumetric speed" value in the filament settings. -![caliper_sample_mvf](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images//caliper_sample_mvf.jpg?raw=true) +![mvf_caliper_sample_mvf](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/mvf/mvf_caliper_sample_mvf.jpg?raw=true) -You can also return to OrcaSlicer in the "Preview" tab, make sure the color scheme "flow" is selected. Scroll down to the layer height that you measured, and click on the toolhead slider. This will indicate the max flow level for your filmanet. +You can also return to OrcaSlicer in the "Preview" tab, make sure the color scheme "flow" is selected. Scroll down to the layer height that you measured, and click on the toolhead slider. This will indicate the max flow level for your filament. -![image](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/max_volumetric_flow.jpg?raw=true) +![mvf_gui_flow](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/mvf/mvf_gui_flow.jpg?raw=true) > [!NOTE] > You may also choose to conservatively reduce the flow by 5-10% to ensure print quality. diff --git a/doc/developer-reference/How-to-build.md b/doc/developer-reference/How-to-build.md index a480a2f94a..ee2a772330 100644 --- a/doc/developer-reference/How-to-build.md +++ b/doc/developer-reference/How-to-build.md @@ -1,10 +1,33 @@ # How to Build +This wiki page provides detailed instructions for building OrcaSlicer from source on different operating systems, including Windows, macOS, and Linux. +It includes tool requirements, setup commands, and build steps for each platform. + +Whether you're a contributor or just want a custom build, this guide will help you compile OrcaSlicer successfully. + +- [Windows 64-bit](#windows-64-bit) + - [Windows Tools Required](#windows-tools-required) + - [Windows Instructions](#windows-instructions) +- [MacOS 64-bit](#macos-64-bit) + - [MacOS Tools Required](#macos-tools-required) + - [MacOS Instructions](#macos-instructions) + - [Debugging in Xcode](#debugging-in-xcode) +- [Linux](#linux) + - [Using Docker (Recommended)](#using-docker-recommended) + - [Docker Dependencies](#docker-dependencies) + - [Docker Instructions](#docker-instructions) + - [Troubleshooting](#troubleshooting) +- [Ubuntu](#ubuntu) + - [Ubuntu Dependencies](#ubuntu-dependencies) + - [Ubuntu Instructions](#ubuntu-instructions) +- [Portable User Configuration](#portable-user-configuration) + - [Example folder structure](#example-folder-structure) + ## Windows 64-bit -This guide is for building your Visual Studio 2022 solution for OrcaSlicer on Windows 64-bit. +How to building with Visual Studio 2022 on Windows 64-bit. -### Tools Required +### Windows Tools Required - [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) or Visual Studio 2019 ```shell @@ -33,7 +56,7 @@ This guide is for building your Visual Studio 2022 solution for OrcaSlicer on Wi > winget install --id=GitHub.GitHubDesktop -e > ``` -### Instructions +### Windows Instructions 1. Clone the repository: - If using GitHub Desktop clone the repository from the GUI. @@ -74,9 +97,11 @@ This guide is for building your Visual Studio 2022 solution for OrcaSlicer on Wi > [!NOTE] > If the build fails, try deleting the `build/` and `deps/build/` directories to clear any cached build data. Rebuilding after a clean-up is usually sufficient to resolve most issues. -## macOS 64-bit +## MacOS 64-bit -### Tools Required +How to building with Xcode on MacOS 64-bit. + +### MacOS Tools Required - Xcode - CMake (version 3.31.x is mandatory) @@ -114,7 +139,7 @@ cmake --version > [!IMPORTANT] > If you've recently upgraded Xcode, be sure to open Xcode at least once and install the required macOS build support. -### Instructions +### MacOS Instructions 1. Clone the repository: ```shell @@ -147,14 +172,18 @@ To build and debug directly in Xcode: ## Linux +Linux instructions are available in two formats: using Docker (recommended) or building directly on your system. + ### Using Docker (Recommended) -#### Dependencies +How to build and run OrcaSlicer using Docker. + +#### Docker Dependencies - Docker - Git -#### Instructions +#### Docker Instructions ```shell git clone https://github.com/SoftFever/OrcaSlicer && cd OrcaSlicer && ./DockerBuild.sh && ./DockerRun.sh @@ -179,7 +208,9 @@ By uncommenting and using these options as needed, you can often resolve issues ## Ubuntu -### Dependencies +How to build OrcaSlicer on Ubuntu. + +### Ubuntu Dependencies All required dependencies will be installed automatically by the provided shell script, including: @@ -199,9 +230,27 @@ All required dependencies will be installed automatically by the provided shell - git - texinfo -### Instructions +### Ubuntu Instructions ```shell `./build_linux.sh -u` # install dependencies `./build_linux.sh -disr` # build OrcaSlicer ``` + +## Portable User Configuration + +If you want OrcaSlicer to use a custom user configuration folder (e.g., for a portable installation), you can simply place a folder named `data_dir` next to the OrcaSlicer executable. OrcaSlicer will automatically use this folder as its configuration directory. + +This allows for multiple self-contained installations with separate user data. + +> [!TIP] +> This feature is especially useful if you want to run OrcaSlicer from a USB stick or keep different profiles isolated. + +### Example folder structure + +```shell +OrcaSlicer.exe +data_dir/ +``` + +You don’t need to recompile or modify any settings — this works out of the box as long as `data_dir` exists in the same folder as the executable. diff --git a/doc/developer-reference/How-to-wiki.md b/doc/developer-reference/How-to-wiki.md index 86f3779257..bb650dcac1 100644 --- a/doc/developer-reference/How-to-wiki.md +++ b/doc/developer-reference/How-to-wiki.md @@ -150,10 +150,13 @@ Always use raw GitHub URLs for image links to ensure correct display: Format = `![[filename]](` + Base URL + filename.extension + Raw tag + `)` - Base URL: + ```markdown https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/ ``` + - Raw tag: + ```markdown ?raw=true ``` @@ -167,6 +170,7 @@ Format = `![[filename]](` + Base URL + filename.extension + Raw tag + `)` ``` - For an image in a subdirectory like `doc/images/calibration/pa-example.svg`: + ```markdown ![pa-example](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/calibration/pa-example.svg?raw=true) ``` @@ -194,6 +198,7 @@ If resizing is necessary (e.g., for thumbnails), use the following syntax: HTML Format = `` + filename + ` ``` diff --git a/doc/developer-reference/Preset-and-bundle.md b/doc/developer-reference/Preset-and-bundle.md index ca2d680f0d..55ad3632f1 100644 --- a/doc/developer-reference/Preset-and-bundle.md +++ b/doc/developer-reference/Preset-and-bundle.md @@ -9,15 +9,15 @@ As the name might suggest this class deals with presets for various things. It d - `TYPE_PRINT`: Refers to a process preset. It's called 'Print' probably due to some legacy code. -![process-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/process-preset.png?raw=true) +![process-preset-full](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/process-preset-full.png?raw=true) - `TYPE_FILAMENT`: As the name suggests this preset is for filaments -![filament-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/filament-preset.png?raw=true) +![filament-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/filament-preset.png?raw=true) - `TYPE_PRINTER`: Preset for printers. -![printer-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/printer-preset.png?raw=true) +![printer-preset](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/printer-preset.png?raw=true) There are other preset types but some of them are for SLA. Which is legacy code, since SLA printers are no longer supported. Above 3 are the important types. diff --git a/doc/developer-reference/plater-sidebar-tab-combobox.md b/doc/developer-reference/plater-sidebar-tab-combobox.md index e7a4c51895..45d5c460de 100644 --- a/doc/developer-reference/plater-sidebar-tab-combobox.md +++ b/doc/developer-reference/plater-sidebar-tab-combobox.md @@ -5,24 +5,24 @@ WIP... > [!WARNING] > !! incomplete, possibly inaccurate, being updated with new info !! -## [`Plater`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/GUI/Plater.hpp) +## [`Plater`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/gui/Plater.hpp) Refers to the entire application. The whole view, file loading, project saving and loading is all managed by this class. This class contains members for the model viewer, the sidebar, gcode viewer and everything else. -## [`Sidebar`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/GUI/Plater.hpp) +## [`Sidebar`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/gui/Plater.hpp) This is relating the the sidebar in the application window -![full-sidebar](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/full-sidebar.png?raw=true) +![full-sidebar](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/full-sidebar.png?raw=true) -## [`ComboBox`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/GUI/Widgets/ComboBox.hpp) +## [`ComboBox`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/gui/Widgets/ComboBox.hpp) The drop down menus where you can see and select presets -![combobox](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/combobox.png?raw=true) +![combobox](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/combobox.png?raw=true) -## [`Tab`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/GUI/Tab.hpp) +## [`Tab`](https://github.com/SoftFever/OrcaSlicer/blob/main/src/slic3r/gui/Tab.hpp) Refers to the various windows with settings. e.g. the Popup to edit printer or filament preset. Also the section to edit process preset and the object list. These 4 are managed by `TabPrinter`, `TabFilament`, `TabPrint` and `TabPrintModel` respectively. -![tab-popup](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/tab-popup.png?raw=true) \ No newline at end of file +![tab-popup](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/gui/tab-popup.png?raw=true) diff --git a/doc/images/combobox.png b/doc/images/GUI/combobox.png similarity index 100% rename from doc/images/combobox.png rename to doc/images/GUI/combobox.png diff --git a/doc/images/filament-preset.png b/doc/images/GUI/filament-preset.png similarity index 100% rename from doc/images/filament-preset.png rename to doc/images/GUI/filament-preset.png diff --git a/doc/images/full-sidebar.png b/doc/images/GUI/full-sidebar.png similarity index 100% rename from doc/images/full-sidebar.png rename to doc/images/GUI/full-sidebar.png diff --git a/doc/images/printer-preset.png b/doc/images/GUI/printer-preset.png similarity index 100% rename from doc/images/printer-preset.png rename to doc/images/GUI/printer-preset.png diff --git a/doc/images/GUI/process-preset.png b/doc/images/GUI/process-preset.png new file mode 100644 index 0000000000..85f329314d Binary files /dev/null and b/doc/images/GUI/process-preset.png differ diff --git a/doc/images/GUI/process/process-multimaterial.png b/doc/images/GUI/process/process-multimaterial.png new file mode 100644 index 0000000000..83bd9115f8 Binary files /dev/null and b/doc/images/GUI/process/process-multimaterial.png differ diff --git a/doc/images/GUI/process/process-others.png b/doc/images/GUI/process/process-others.png new file mode 100644 index 0000000000..002c85ccb6 Binary files /dev/null and b/doc/images/GUI/process/process-others.png differ diff --git a/doc/images/GUI/process/process-quality.png b/doc/images/GUI/process/process-quality.png new file mode 100644 index 0000000000..b84f855870 Binary files /dev/null and b/doc/images/GUI/process/process-quality.png differ diff --git a/doc/images/GUI/process/process-speed.png b/doc/images/GUI/process/process-speed.png new file mode 100644 index 0000000000..75145adad7 Binary files /dev/null and b/doc/images/GUI/process/process-speed.png differ diff --git a/doc/images/GUI/process/process-strength.png b/doc/images/GUI/process/process-strength.png new file mode 100644 index 0000000000..8f92633e50 Binary files /dev/null and b/doc/images/GUI/process/process-strength.png differ diff --git a/doc/images/GUI/process/process-support.png b/doc/images/GUI/process/process-support.png new file mode 100644 index 0000000000..1d44decf2b Binary files /dev/null and b/doc/images/GUI/process/process-support.png differ diff --git a/doc/images/tab-popup.png b/doc/images/GUI/tab-popup.png similarity index 100% rename from doc/images/tab-popup.png rename to doc/images/GUI/tab-popup.png diff --git a/doc/images/caliper_sample_mvf.jpg b/doc/images/MVF/mvf_caliper_sample_mvf.jpg similarity index 100% rename from doc/images/caliper_sample_mvf.jpg rename to doc/images/MVF/mvf_caliper_sample_mvf.jpg diff --git a/doc/images/max_volumetric_flow.jpg b/doc/images/MVF/mvf_gui_flow.jpg similarity index 100% rename from doc/images/max_volumetric_flow.jpg rename to doc/images/MVF/mvf_gui_flow.jpg diff --git a/doc/images/vmf_measurement_point.jpg b/doc/images/MVF/mvf_measurement_point.jpg similarity index 100% rename from doc/images/vmf_measurement_point.jpg rename to doc/images/MVF/mvf_measurement_point.jpg diff --git a/doc/images/Precision/PreciseWallOff.svg b/doc/images/Precision/PreciseWallOff.svg index f920f06f41..99fe13f6f7 100644 --- a/doc/images/Precision/PreciseWallOff.svg +++ b/doc/images/Precision/PreciseWallOff.svg @@ -1,3 +1,3 @@ -
Inner wall
Inner wall
Inner wall
Inner wall
Outer wall
Outer wall
\ No newline at end of file +
Inner wall
Inner wall
Inner wall
Inner wall
Outer wall
Outer wall
\ No newline at end of file diff --git a/doc/images/Precision/PreciseWallOn.svg b/doc/images/Precision/PreciseWallOn.svg index 5d27354d1e..48d1fcac7f 100644 --- a/doc/images/Precision/PreciseWallOn.svg +++ b/doc/images/Precision/PreciseWallOn.svg @@ -1,3 +1,3 @@ -
Inner wall
Inner wall
Inner wall
Inner wall
Outer wall
Outer wall
\ No newline at end of file +
Inner wall
Inner wall
Inner wall
Inner wall
Outer wall
Outer wall
\ No newline at end of file diff --git a/doc/images/STL-Transformation/stl-transformation.png b/doc/images/STL-Transformation/stl-transformation.png index 4390b85403..6527e14826 100644 Binary files a/doc/images/STL-Transformation/stl-transformation.png and b/doc/images/STL-Transformation/stl-transformation.png differ diff --git a/doc/images/fill/InfillAnchorOff.png b/doc/images/fill/InfillAnchorOff.png new file mode 100644 index 0000000000..291f41bb34 Binary files /dev/null and b/doc/images/fill/InfillAnchorOff.png differ diff --git a/doc/images/fill/InfillAnchorOn.png b/doc/images/fill/InfillAnchorOn.png new file mode 100644 index 0000000000..5757a4f9be Binary files /dev/null and b/doc/images/fill/InfillAnchorOn.png differ diff --git a/doc/images/fill/InfillWallOverlapOff.svg b/doc/images/fill/InfillWallOverlapOff.svg new file mode 100644 index 0000000000..a524a6bf73 --- /dev/null +++ b/doc/images/fill/InfillWallOverlapOff.svg @@ -0,0 +1,3 @@ + + +
Inner wall
Inner wall
Outer wall
Outer wall
Inner wall
Inner wall
Sparse infill
Sparse infill
\ No newline at end of file diff --git a/doc/images/fill/InfillWallOverlapOn.svg b/doc/images/fill/InfillWallOverlapOn.svg new file mode 100644 index 0000000000..cc348c099b --- /dev/null +++ b/doc/images/fill/InfillWallOverlapOn.svg @@ -0,0 +1,3 @@ + + +
Inner wall
Inner wall
Outer wall
Outer wall
Inner wall
Inner wall
Sparse infill
Sparse infill
\ No newline at end of file diff --git a/doc/images/fill/infill-top-2d-honeycomb.png b/doc/images/fill/infill-top-2d-honeycomb.png new file mode 100644 index 0000000000..e557f81002 Binary files /dev/null and b/doc/images/fill/infill-top-2d-honeycomb.png differ diff --git a/doc/images/fill/infill-top-2d-lattice.png b/doc/images/fill/infill-top-2d-lattice.png index a67d27a4f4..01900ad1f1 100644 Binary files a/doc/images/fill/infill-top-2d-lattice.png and b/doc/images/fill/infill-top-2d-lattice.png differ diff --git a/doc/images/fill/infill-top-3d-honeycomb.png b/doc/images/fill/infill-top-3d-honeycomb.png index 749df03131..30134a3f83 100644 Binary files a/doc/images/fill/infill-top-3d-honeycomb.png and b/doc/images/fill/infill-top-3d-honeycomb.png differ diff --git a/doc/images/fill/infill-top-adaptive-cubic.png b/doc/images/fill/infill-top-adaptive-cubic.png index 8fdb765017..31cb7220be 100644 Binary files a/doc/images/fill/infill-top-adaptive-cubic.png and b/doc/images/fill/infill-top-adaptive-cubic.png differ diff --git a/doc/images/fill/infill-top-aligned-rectilinear.png b/doc/images/fill/infill-top-aligned-rectilinear.png index 0df2b714d9..b31ad33c3f 100644 Binary files a/doc/images/fill/infill-top-aligned-rectilinear.png and b/doc/images/fill/infill-top-aligned-rectilinear.png differ diff --git a/doc/images/fill/infill-top-archimedean-chords.png b/doc/images/fill/infill-top-archimedean-chords.png index 3e2f78d47a..f70f98cde5 100644 Binary files a/doc/images/fill/infill-top-archimedean-chords.png and b/doc/images/fill/infill-top-archimedean-chords.png differ diff --git a/doc/images/fill/infill-top-concentric.png b/doc/images/fill/infill-top-concentric.png index fe981fe792..605f182e65 100644 Binary files a/doc/images/fill/infill-top-concentric.png and b/doc/images/fill/infill-top-concentric.png differ diff --git a/doc/images/fill/infill-top-coss-zag.png b/doc/images/fill/infill-top-coss-zag.png new file mode 100644 index 0000000000..1c037b69e4 Binary files /dev/null and b/doc/images/fill/infill-top-coss-zag.png differ diff --git a/doc/images/fill/infill-top-cross-hatch.png b/doc/images/fill/infill-top-cross-hatch.png index 15e6b67a9a..1bcc7b217a 100644 Binary files a/doc/images/fill/infill-top-cross-hatch.png and b/doc/images/fill/infill-top-cross-hatch.png differ diff --git a/doc/images/fill/infill-top-cubic.png b/doc/images/fill/infill-top-cubic.png index 0f3a1af305..2c240e8ec0 100644 Binary files a/doc/images/fill/infill-top-cubic.png and b/doc/images/fill/infill-top-cubic.png differ diff --git a/doc/images/fill/infill-top-grid.png b/doc/images/fill/infill-top-grid.png index 6a853404a6..0582468d68 100644 Binary files a/doc/images/fill/infill-top-grid.png and b/doc/images/fill/infill-top-grid.png differ diff --git a/doc/images/fill/infill-top-gyroid.png b/doc/images/fill/infill-top-gyroid.png index dee06c34cd..930f4e7de9 100644 Binary files a/doc/images/fill/infill-top-gyroid.png and b/doc/images/fill/infill-top-gyroid.png differ diff --git a/doc/images/fill/infill-top-hilbert-curve.png b/doc/images/fill/infill-top-hilbert-curve.png index 60399e2e9f..4c74acbe7e 100644 Binary files a/doc/images/fill/infill-top-hilbert-curve.png and b/doc/images/fill/infill-top-hilbert-curve.png differ diff --git a/doc/images/fill/infill-top-honeycomb.png b/doc/images/fill/infill-top-honeycomb.png index bf6ec72ef2..16face86f1 100644 Binary files a/doc/images/fill/infill-top-honeycomb.png and b/doc/images/fill/infill-top-honeycomb.png differ diff --git a/doc/images/fill/infill-top-infill-top-2d-honeycomb.png b/doc/images/fill/infill-top-infill-top-2d-honeycomb.png deleted file mode 100644 index 257dd83c7c..0000000000 Binary files a/doc/images/fill/infill-top-infill-top-2d-honeycomb.png and /dev/null differ diff --git a/doc/images/fill/infill-top-lightning.png b/doc/images/fill/infill-top-lightning.png index cd9903e34c..9892bbb5c7 100644 Binary files a/doc/images/fill/infill-top-lightning.png and b/doc/images/fill/infill-top-lightning.png differ diff --git a/doc/images/fill/infill-top-line.png b/doc/images/fill/infill-top-line.png index 67b1ff61fa..d028a2e442 100644 Binary files a/doc/images/fill/infill-top-line.png and b/doc/images/fill/infill-top-line.png differ diff --git a/doc/images/fill/infill-top-locked-zag.png b/doc/images/fill/infill-top-locked-zag.png new file mode 100644 index 0000000000..b9592186c5 Binary files /dev/null and b/doc/images/fill/infill-top-locked-zag.png differ diff --git a/doc/images/fill/infill-top-octagram-spiral.png b/doc/images/fill/infill-top-octagram-spiral.png index 94afbd3eab..51c76c400e 100644 Binary files a/doc/images/fill/infill-top-octagram-spiral.png and b/doc/images/fill/infill-top-octagram-spiral.png differ diff --git a/doc/images/fill/infill-top-quarter-cubic.png b/doc/images/fill/infill-top-quarter-cubic.png index 1041e01f29..aae74aa1f3 100644 Binary files a/doc/images/fill/infill-top-quarter-cubic.png and b/doc/images/fill/infill-top-quarter-cubic.png differ diff --git a/doc/images/fill/infill-top-rectilinear.png b/doc/images/fill/infill-top-rectilinear.png index c4b5639b4f..2f0b84e36c 100644 Binary files a/doc/images/fill/infill-top-rectilinear.png and b/doc/images/fill/infill-top-rectilinear.png differ diff --git a/doc/images/fill/infill-top-support-cubic.png b/doc/images/fill/infill-top-support-cubic.png index 309910eab4..248276a56f 100644 Binary files a/doc/images/fill/infill-top-support-cubic.png and b/doc/images/fill/infill-top-support-cubic.png differ diff --git a/doc/images/fill/infill-top-tpms-d.png b/doc/images/fill/infill-top-tpms-d.png index 21159fe3ab..f86cae3058 100644 Binary files a/doc/images/fill/infill-top-tpms-d.png and b/doc/images/fill/infill-top-tpms-d.png differ diff --git a/doc/images/fill/infill-top-tri-hexagon.png b/doc/images/fill/infill-top-tri-hexagon.png index e2229ae195..2adfc583fc 100644 Binary files a/doc/images/fill/infill-top-tri-hexagon.png and b/doc/images/fill/infill-top-tri-hexagon.png differ diff --git a/doc/images/fill/infill-top-triangles.png b/doc/images/fill/infill-top-triangles.png index e8bbed4e8d..921b6db9eb 100644 Binary files a/doc/images/fill/infill-top-triangles.png and b/doc/images/fill/infill-top-triangles.png differ diff --git a/doc/images/fill/infill-top-zig-zag.png b/doc/images/fill/infill-top-zig-zag.png new file mode 100644 index 0000000000..3a9adb7ca7 Binary files /dev/null and b/doc/images/fill/infill-top-zig-zag.png differ diff --git a/doc/images/process-preset.png b/doc/images/gui/process-preset-full.png similarity index 100% rename from doc/images/process-preset.png rename to doc/images/gui/process-preset-full.png diff --git a/doc/images/vfa/vfa_test_menu.png b/doc/images/vfa/vfa_test_menu.png new file mode 100644 index 0000000000..40580284ab Binary files /dev/null and b/doc/images/vfa/vfa_test_menu.png differ diff --git a/doc/images/vfa/vfa_test_print.jpg b/doc/images/vfa/vfa_test_print.jpg new file mode 100644 index 0000000000..0423a2d1b8 Binary files /dev/null and b/doc/images/vfa/vfa_test_print.jpg differ diff --git a/doc/material_settings/semm.md b/doc/material_settings/semm.md index a5e22f3584..b0c84dacc0 100644 --- a/doc/material_settings/semm.md +++ b/doc/material_settings/semm.md @@ -16,4 +16,3 @@ Ramming is a technique used to push the filament through the nozzle to ensure th ## Manual filament change Manual filament change is a feature that allows the user to change the filament during the print. This can be useful for multi-material prints or when changing colors. The user can specify the position and timing of the filament change, as well as the speed and distance of the ramming process. -WIP... diff --git a/doc/print_settings/quality/quality_settings_wall_generator.md b/doc/print_settings/quality/quality_settings_wall_generator.md index f7279aa253..fe39915e17 100644 --- a/doc/print_settings/quality/quality_settings_wall_generator.md +++ b/doc/print_settings/quality/quality_settings_wall_generator.md @@ -1,23 +1,58 @@ # Wall Generator -WIP... +The Wall Generator defines how the outer and inner walls (perimeters) of the model are printed. ## Classic -WIP... +The Classic wall generator is a simple and reliable method used in many slicers. It creates as many walls as possible (limited by [Wall Loops](strength_settings_walls#wall-loops)) by extruding along the model’s perimeter using the defined [Line Width](quality_settings_line_width). +This method does not vary extrusion width and is ideal for fast, predictable slicing. ![wallgenerator-classic](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/WallGenerator/wallgenerator-classic.png?raw=true) ## Arachne -WIP... +The Arachne wall generator dynamically adjusts extrusion width to follow the shape of the model more closely. This allows better handling of thin features and smooth transitions between wall counts. ![wallgenerator-arachne](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/WallGenerator/wallgenerator-arachne.png?raw=true) -- Wall transitioning threshhold angle -- Wall transitioning filter -- Wall transitioning length -- Wall distribution count -- First layer minimum wall width -- Minimum feature size -- Minimum wall length +### Wall transitioning threshhold angle + +Defines the minimum angle (in degrees) required for the algorithm to create a transition between an even and odd number of walls. If a wedge shape exceeds this angle, no extra center wall will be added. Lowering this value reduces center walls but may cause under- or over-extrusion in sharp corners. + +### Wall transitioning filter margin + +Prevents rapid switching between more or fewer walls by defining a tolerance range around the minimum wall width. The extrusion width will stay within the range: + +```math +\left[ \text{Minimum Wall Width} - \text{Margin},\ 2 \times \text{Minimum Wall Width} + \text{Margin} \right] +``` + +Higher values reduce transitions, travel moves, and extrusion starts/stops, but may increase extrusion variability and introduce print quality issues. Expressed as a percentage of nozzle diameter. + +### Wall transitioning length + +Controls how far into the model the transition between wall counts extends. A lower value shortens or removes center walls, improving print time but potentially reducing coverage in tight areas. + +### Wall distribution count + +Sets how many walls (counted inward from the outer wall) are allowed to vary in width. Lower values constrain variation to inner walls, keeping outer walls consistent for best surface quality. + +### Minimum wall width + +Defines the narrowest wall that can be printed to represent thin features. If the feature is thinner than this value, the wall will match its width. Expressed as a percentage of nozzle diameter. + +#### First layer minimum wall width + +Specifies the minimum wall width for the first layer. It is recommended to match the nozzle diameter to improve adhesion and ensure stable base walls. + +### Minimum feature size + +Minimum width required for a model feature to be printed. Features below this value are skipped; features above it are widened to match the **Minimum Wall Width**. Expressed as a percentage of nozzle diameter. + +### Minimum wall length + +Avoids very short or isolated wall segments that add unnecessary time. Increasing this value removes short unconnected walls, improving efficiency. + +> [!NOTE] +> Top and bottom surfaces are not affected by this setting to avoid visual artifacts. +> Use the One Wall Threshold (in Advanced settings) to adjust how aggressively OrcaSlicer considers a region a top surface. This option only appears when this setting exceeds 0.5, or if single-wall top surfaces are enabled. diff --git a/doc/print_settings/speed/speed_extrusion_rate_smoothing.md b/doc/print_settings/speed/speed_settings_extrusion_rate_smoothing.md similarity index 100% rename from doc/print_settings/speed/speed_extrusion_rate_smoothing.md rename to doc/print_settings/speed/speed_settings_extrusion_rate_smoothing.md diff --git a/doc/print_settings/strength/infill_desc_calculator.xlsx b/doc/print_settings/strength/infill_desc_calculator.xlsx index d2eb743142..3cefcb777e 100644 Binary files a/doc/print_settings/strength/infill_desc_calculator.xlsx and b/doc/print_settings/strength/infill_desc_calculator.xlsx differ diff --git a/doc/print_settings/strength/strength_settings_infill.md b/doc/print_settings/strength/strength_settings_infill.md index 394ab8720e..6730bf4b5d 100644 --- a/doc/print_settings/strength/strength_settings_infill.md +++ b/doc/print_settings/strength/strength_settings_infill.md @@ -2,6 +2,41 @@ Infill is the internal structure of a 3D print, providing strength and support. It can be adjusted to balance material usage, print time, and part strength. +- [Sparse infill density](#sparse-infill-density) +- [Direction and Rotation](#direction-and-rotation) + - [Direction](#direction) + - [Rotation](#rotation) +- [Infill Wall Overlap](#infill-wall-overlap) +- [Apply gap fill](#apply-gap-fill) +- [Anchor](#anchor) +- [Internal Solid Infill](#internal-solid-infill) +- [Sparse Infill Pattern](#sparse-infill-pattern) + - [Concentric](#concentric) + - [Rectilinear](#rectilinear) + - [Grid](#grid) + - [2D Lattice](#2d-lattice) + - [Line](#line) + - [Cubic](#cubic) + - [Triangles](#triangles) + - [Tri-hexagon](#tri-hexagon) + - [Gyroid](#gyroid) + - [TPMS-D](#tpms-d) + - [Honeycomb](#honeycomb) + - [Adaptive Cubic](#adaptive-cubic) + - [Aligned Rectilinear](#aligned-rectilinear) + - [2D Honeycomb](#2d-honeycomb) + - [3D Honeycomb](#3d-honeycomb) + - [Hilbert Curve](#hilbert-curve) + - [Archimedean Chords](#archimedean-chords) + - [Octagram Spiral](#octagram-spiral) + - [Support Cubic](#support-cubic) + - [Lightning](#lightning) + - [Cross Hatch](#cross-hatch) + - [Quarter Cubic](#quarter-cubic) + - [Zig Zag](#zig-zag) + - [Coss Zag](#coss-zag) + - [Locked Zag](#locked-zag) + ## Sparse infill density Density usually should be calculated as a % of the total infill volume, not the total print volume. @@ -9,6 +44,82 @@ Higher density increases strength but also material usage and print time. Lower Nevertheless, **not all patterns interpret density the same way**, so the actual material usage may vary. You can see each pattern's material usage in the [Sparse Infill Pattern](#sparse-infill-pattern) section. +## Direction and Rotation + +### Direction + +Controls the direction of the infill lines to optimize or strengthen the print. + +### Rotation + +This parameter adds a rotation to the sparse infill direction for each layer according to the specified template. The template is a comma-separated list of angles in degrees. + +For example: + +```c++ +0,90 +``` + +The first layer uses 0°, the second uses 90°, and the pattern repeats for subsequent layers. + +Other examples: + +```c++ +0,45,90 +``` + +```c++ +0,60,120,180 +``` + +If there are more layers than angles, the sequence repeats. +> [!NOTE] +> Not all sparse infill patterns support rotation. + +## Infill Wall Overlap + +Infill area is enlarged slightly to overlap with wall for better bonding. The percentage value is relative to line width of sparse infill. Set this value to ~10-15% to minimize potential over extrusion and accumulation of material resulting in rough surfaces. + +- **Infill Wall Overlap Off** + +![InfillWallOverlapOff](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/InfillWallOverlapOff.svg?raw=true) + +- **Infill Wall Overlap On** + +![InfillWallOverlapOn](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/InfillWallOverlapOn.svg?raw=true) + +## Apply gap fill + +Enables gap fill for the selected solid surfaces. The minimum gap length that will be filled can be controlled from the filter out tiny gaps option. + +1. **Everywhere:** Applies gap fill to top, bottom and internal solid surfaces for maximum strength. +2. **Top and Bottom surfaces:** Applies gap fill to top and bottom surfaces only, balancing print speed, reducing potential over extrusion in the solid infill and making sure the top and bottom surfaces have no pinhole gaps. +3. **Nowhere:** Disables gap fill for all solid infill areas. + +Note that if using the [classic perimeter generator](quality_settings_wall_generator#classic), gap fill may also be generated between perimeters, if a full width line cannot fit between them. +That perimeter gap fill is not controlled by this setting. + +If you would like all gap fill, including the classic perimeter generated one, removed, set the filter out tiny gaps value to a large number, like 999999. + +However this is not advised, as gap fill between perimeters is contributing to the model's strength. For models where excessive gap fill is generated between perimeters, a better option would be to switch to the [arachne wall generator](quality_settings_wall_generator#arachne) and use this option to control whether the cosmetic top and bottom surface gap fill is generated. + +## Anchor + +Connect an infill line to an internal perimeter with a short segment of an additional perimeter. If expressed as percentage (example: 15%) it is calculated over infill extrusion width. +OrcaSlicer tries to connect two close infill lines to a short perimeter segment. If no such perimeter segment shorter than this parameter is found, the infill line is connected to a perimeter segment at just one side and the length of the perimeter segment taken is limited to infill_anchor, but no longer than this parameter. If set to 0, the old algorithm for infill connection will be used, it should create the same result as with 1000 & 0. + +- **Anchor Off** + +![InfillAnchorOff](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/InfillAnchorOff.png?raw=true) + +- **Anchor On** + +![InfillAnchorOn](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/InfillAnchorOn.png?raw=true) + +## Internal Solid Infill + +Line pattern of internal solid infill. If the [detect narrow internal solid infill](strength_settings_advanced#detect-narrow-internal-solid-infill) be enabled, the concentric pattern will be used for the small area. + ## Sparse Infill Pattern Infill patterns determine how material is distributed within a print. Different patterns can affect strength, flexibility, and print speed using the same density setting. @@ -18,30 +129,33 @@ There is no one-size-fits-all solution, as the best pattern depends on the speci Many patterns may look similar and have similar overall specifications, but they can behave very differently in practice. As most settings in 3D printing, experience is the best way to determine which pattern works best for your specific needs. -| Infill | X-Y Strength | Z Strength | Material Usage | Print Time | -|---------------------------------------------|--------------|-------------|----------------|-------------| -| [Concentric](#concentric) | Low | Normal | Normal | Normal | -| [Rectilinear](#rectilinear) | Normal-Low | Low | Normal | Normal | -| [Grid](#grid) | High | High | Normal | Normal | -| [2D Lattice](#2d-lattice) | Normal-Low | Low | Normal | Normal | -| [Line](#line) | Low | Low | Normal | Normal-Low | -| [Cubic](#cubic) | High | High | Normal | Normal-Low | -| [Triangles](#triangles) | High | Normal | Normal | Normal-Low | -| [Tri-hexagon](#tri-hexagon) | High | Normal-High | Normal | Normal-Low | -| [Gyroid](#gyroid) | High | High | Normal | Normal-High | -| [TPMS-D](#tpms-d) | High | High | Normal | High | -| [Honeycomb](#honeycomb) | High | High | High | Ultra-High | -| [Adaptive Cubic](#adaptive-cubic) | Normal-High | Normal-High | Low | Low | -| [Aligned Rectilinear](#aligned-rectilinear) | Normal-Low | Normal | Normal | Normal | -| [2D Honeycomb](#2d-honeycomb) | Normal-Low | Normal-Low | Normal | Normal-Low | -| [3D Honeycomb](#3d-honeycomb) | Normal-High | Normal-High | Normal-Low | High | -| [Hilbert Curve](#hilbert-curve) | Low | Normal | Normal | High | -| [Archimedean Chords](#archimedean-chords) | Low | Normal | Normal | Normal-Low | -| [Octagram Spiral](#octagram-spiral) | Low | Normal | Normal | Normal-High | -| [Support Cubic](#support-cubic) | Low | Low | Extra-Low | Extra-Low | -| [Lightning](#lightning) | Low | Low | Ultra-Low | Ultra-Low | -| [Cross Hatch](#cross-hatch) | Normal-High | Normal-High | Normal | Normal-High | -| [Quarter Cubic](#quarter-cubic) | High | High | Normal | Normal-Low | +| Pattern | X-Y Strength | Z Strength | Material Usage | Print Time | +|-----------------------------------------------|--------------|-------------|----------------|-------------| +| [Concentric](#concentric) | Low | Normal | Normal | Normal | +| [Rectilinear](#rectilinear) | Normal-Low | Low | Normal | Normal-Low | +| [Grid](#grid) | High | High | Normal | Normal-Low | +| [2D Lattice](#2d-lattice) | Normal-Low | Low | Normal | Normal-Low | +| [Line](#line) | Low | Low | Normal | Normal-Low | +| [Cubic](#cubic) | High | High | Normal | Normal-Low | +| [Triangles](#triangles) | High | Normal | Normal | Normal-Low | +| [Tri-hexagon](#tri-hexagon) | High | Normal-High | Normal | Normal-Low | +| [Gyroid](#gyroid) | High | High | Normal | Normal-High | +| [TPMS-D](#tpms-d) | High | High | Normal | High | +| [Honeycomb](#honeycomb) | High | High | High | Ultra-High | +| [Adaptive Cubic](#adaptive-cubic) | Normal-High | Normal-High | Low | Low | +| [Aligned Rectilinear](#aligned-rectilinear) | Normal-Low | Normal | Normal | Normal-Low | +| [2D Honeycomb](#2d-honeycomb) | Normal-Low | Normal-Low | Normal | Normal-Low | +| [3D Honeycomb](#3d-honeycomb) | Normal-High | Normal-High | Normal-Low | High | +| [Hilbert Curve](#hilbert-curve) | Low | Normal | Normal | High | +| [Archimedean Chords](#archimedean-chords) | Low | Normal | Normal | Normal-Low | +| [Octagram Spiral](#octagram-spiral) | Low | Normal | Normal | Normal | +| [Support Cubic](#support-cubic) | Low | Low | Extra-Low | Extra-Low | +| [Lightning](#lightning) | Low | Low | Ultra-Low | Ultra-Low | +| [Cross Hatch](#cross-hatch) | Normal-High | Normal-High | Normal | Normal-High | +| [Quarter Cubic](#quarter-cubic) | High | High | Normal | Normal-Low | +| [Zig Zag](#zig-zag) | Normal-Low | Low | Normal | Normal | +| [Coss Zag](#coss-zag) | Normal | Low | Normal | Normal | +| [Locked Zag](#locked-zag) | Normal-Low | Normal-Low | Normal-High | Extra-High | > [!NOTE] > You can download [infill_desc_calculator.xlsx](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/print_settings/strength/infill_desc_calculator.xlsx?raw=true) used to calculate the values above. @@ -61,14 +175,14 @@ Fills the area with progressively smaller versions of the outer contour, creatin ### Rectilinear -Parallel lines spaced according to infill density. Each layer is printed perpendicular to the previous, resulting in low vertical bonding. +Parallel lines spaced according to infill density. Each layer is printed perpendicular to the previous, resulting in low vertical bonding. Considere using new [Zig Zag](#zig-zag) infill instead. - **Horizontal Strength (X-Y):** Normal-Low - **Vertical Strength (Z):** Low - **Density Calculation:** % of total infill volume - **Material Usage:** Normal -- **Print Time:** Normal -- **Material/Time (Higher better):** Normal-High +- **Print Time:** Normal-Low +- **Material/Time (Higher better):** Normal ![infill-top-rectilinear](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-rectilinear.png?raw=true) @@ -80,7 +194,7 @@ Two-layer pattern of perpendicular lines, forming a grid. Overlapping points may - **Vertical Strength (Z):** High - **Density Calculation:** % of total infill volume - **Material Usage:** Normal -- **Print Time:** Normal +- **Print Time:** Normal-Low - **Material/Time (Higher better):** Normal ![infill-top-grid](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-grid.png?raw=true) @@ -93,7 +207,7 @@ Low-strength pattern with good flexibility. Angle 1 and angle 2 TBD. - **Vertical Strength (Z):** Low - **Density Calculation:** % of total infill volume - **Material Usage:** Normal -- **Print Time:** Normal +- **Print Time:** Normal-Low - **Material/Time (Higher better):** Normal ![infill-top-2d-lattice](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-2d-lattice.png?raw=true) @@ -159,7 +273,7 @@ Mathematical, isotropic surface providing equal strength in all directions. Exce - **Density Calculation:** % of total infill volume - **Material Usage:** Normal - **Print Time:** Normal-High -- **Material/Time (Higher better):** Low +- **Material/Time (Higher better):** Normal-Low ![infill-top-gyroid](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-gyroid.png?raw=true) @@ -172,7 +286,7 @@ Triply Periodic Minimal Surface - D. Hybrid between [Cross Hatch](#cross-hatch) - **Density Calculation:** % of total infill volume - **Material Usage:** Normal - **Print Time:** High -- **Material/Time (Higher better):** Low +- **Material/Time (Higher better):** Normal-Low ![infill-top-tpms-d](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-tpms-d.png?raw=true) @@ -185,7 +299,7 @@ Hexagonal pattern balancing strength and material use. Double walls in each hexa - **Density Calculation:** % of total infill volume - **Material Usage:** High - **Print Time:** Ultra-High -- **Material/Time (Higher better):** Extra Low +- **Material/Time (Higher better):** Low ![infill-top-honeycomb](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-honeycomb.png?raw=true) @@ -211,7 +325,7 @@ Recommended with layer anchoring to improve not perpendicular strength. - **Vertical Strength (Z):** Normal - **Density Calculation:** % of total infill volume - **Material Usage:** Normal -- **Print Time:** Normal +- **Print Time:** Normal-Low - **Material/Time (Higher better):** Normal ![infill-top-aligned-rectilinear](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-aligned-rectilinear.png?raw=true) @@ -238,7 +352,7 @@ This infill tries to generate a printable honeycomb structure by printing square - **Density Calculation:** Unknown - **Material Usage:** Normal-Low - **Print Time:** High -- **Material/Time (Higher better):** Extra Low +- **Material/Time (Higher better):** Low ![infill-top-3d-honeycomb](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-3d-honeycomb.png?raw=true) @@ -252,7 +366,7 @@ Print speed is very low due to the complexity of the path, which can lead to lon - **Density Calculation:** % of total infill volume - **Material Usage:** Normal - **Print Time:** High -- **Material/Time (Higher better):** Extra Low +- **Material/Time (Higher better):** Low ![infill-top-hilbert-curve](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-hilbert-curve.png?raw=true) @@ -277,8 +391,8 @@ Esthetic pattern with low strength and high print time. - **Vertical Strength (Z):** Normal - **Density Calculation:** % of total infill volume - **Material Usage:** Normal -- **Print Time:** Normal-High -- **Material/Time (Higher better):** Normal +- **Print Time:** Normal +- **Material/Time (Higher better):** Normal-Low ![infill-top-octagram-spiral](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-octagram-spiral.png?raw=true) @@ -304,7 +418,7 @@ Ultra-fast, ultra-low material infill. Designed for speed and efficiency, ideal - **Density Calculation:** % of layer before top shell layers - **Material Usage:** Ultra-Low - **Print Time:** Ultra-Low -- **Material/Time (Higher better):** Extra Low +- **Material/Time (Higher better):** Low ![infill-top-lightning](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-lightning.png?raw=true) @@ -317,7 +431,7 @@ Similar to [Gyroid](#gyroid) but with linear patterns, creating weak points at i - **Density Calculation:** % of total infill volume - **Material Usage:** Normal - **Print Time:** Normal-High -- **Material/Time (Higher better):** Low +- **Material/Time (Higher better):** Normal-Low ![infill-top-cross-hatch](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-cross-hatch.png?raw=true) @@ -333,3 +447,42 @@ Similar to [Gyroid](#gyroid) but with linear patterns, creating weak points at i - **Material/Time (Higher better):** Normal ![infill-top-quarter-cubic](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-quarter-cubic.png?raw=true) + +### Zig Zag + +Similar to [rectilinear](#rectilinear) with consistent pattern between layers. Allows you to add a Symmetric infil Y axis for models with two symmetric parts. + +- **Horizontal Strength (X-Y):** Normal-Low +- **Vertical Strength (Z):** Low +- **Density Calculation:** % of total infill volume +- **Material Usage:** Normal +- **Print Time:** Normal +- **Material/Time (Higher better):** Normal + +![infill-top-zig-zag](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-zig-zag.png?raw=true) + +### Coss Zag + +Similar to [Zig Zag](#zig-zag) but displacing each lager with Infill shift step parammeter. + +- **Horizontal Strength (X-Y):** Normal +- **Vertical Strength (Z):** Low +- **Density Calculation:** % of total infill volume +- **Material Usage:** Normal +- **Print Time:** Normal +- **Material/Time (Higher better):** Normal + +![infill-top-coss-zag](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-coss-zag.png?raw=true) + +### Locked Zag + +Adaptative version of [Zig Zag](#zig-zag) adding an external skin texture to interlock layers and a low material skeleton. + +- **Horizontal Strength (X-Y):** Normal-Low +- **Vertical Strength (Z):** Normal-Low +- **Density Calculation:** Same as [Zig Zag](#zig-zag) but increasing near walls +- **Material Usage:** Normal-High +- **Print Time:** Extra-High +- **Material/Time (Higher better):** Low + +![infill-top-locked-zag](https://github.com/SoftFever/OrcaSlicer/blob/main/doc/images/fill/infill-top-locked-zag.png?raw=true) diff --git a/doc/print_settings/strength/strength_settings_top_bottom_shells.md b/doc/print_settings/strength/strength_settings_top_bottom_shells.md new file mode 100644 index 0000000000..aa960ac6c8 --- /dev/null +++ b/doc/print_settings/strength/strength_settings_top_bottom_shells.md @@ -0,0 +1,19 @@ +# Top and Bottom Shells + +Controls how the top and bottom solid layers (shells) are generated in the print. + +- **Shells:** This is the number of solid layers of shell, including the surface layer. When the thickness calculated by this value is thinner than shell thickness, the shell layers will be increased. +- **Shell Thickness:** The number of solid layers is increased when slicing if the thickness calculated by shell layers is thinner than this value. This can avoid having too thin shell when layer height is small. 0 means that this setting is disabled and thickness of shell is absolutely determined by shell layers. +- **Infill/Wall Overlap:** Top solid infill area is enlarged slightly to overlap with wall for better bonding and to minimize the appearance of pinholes where the infill meets the walls. A value of 25-30% is a good starting point, minimizing the appearance of pinholes. The percentage value is relative to line width of sparse infill. +- **Surface Pattern:** This setting controls the pattern of the surface. The options are: + - **Concentric:** Fills the surface with inward-tracing loops that follow the outer contour. + - **Rectilinear:** Fills the surface with straight lines alternating direction per layer. + - **Monotonic:** Prints lines in a uniform direction for a smoother visual surface. + - **Monotonic Lines:** Similar to Monotonic but avoids overlapping with the perimeter, reducing excess material at joints. May introduce visible seams. + - **Aligned Rectilinear:** The surface is printed with rectilinear lines that are aligned with the infill pattern. + - **Hilbert Curve:** Applies a space-filling curve for even material distribution and a unique appearance. Slow to print but useful in esthetic applications. + - **Archimedean Chords:** Generates concentric arc-like lines, promoting uniform material spread. + - **Octagram Spiral:** Creates an octagonal spiral for decorative, esthetic surfaces. + +> [!NOTE] +> Some patterns may have further information in its [Sparse Infill Pattern Wiki](strength_settings_infill#sparse-infill-pattern) diff --git a/resources/images/param_tpmsd.svg b/resources/images/param_tpmsd.svg index 247f77c6d2..c66ea26347 100644 --- a/resources/images/param_tpmsd.svg +++ b/resources/images/param_tpmsd.svg @@ -22,93 +22,16 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="24.479167" - inkscape:cx="12.214468" - inkscape:cy="12.88851" + inkscape:zoom="45.254834" + inkscape:cx="17.987029" + inkscape:cy="12.805262" inkscape:window-width="2560" inkscape:window-height="1377" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="svg10" - showguides="true"> - - - - - - - - - - - - - + showguides="true" /> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + diff --git a/resources/profiles/Ginger Additive/process/0.60mm Standard.json b/resources/profiles/Ginger Additive/process/0.60mm Standard.json index 0b08cb66bb..97fc0d11f1 100644 --- a/resources/profiles/Ginger Additive/process/0.60mm Standard.json +++ b/resources/profiles/Ginger Additive/process/0.60mm Standard.json @@ -67,11 +67,13 @@ "travel_acceleration": "2500", "travel_jerk": "7", "travel_speed": "250", - "version": "0.0.0.0", + "version": "0.0.0.1", "wipe_on_loops": "1", "wipe_speed": "30", "xy_contour_compensation": "0", "xy_hole_compensation": "0", "instantiation": "true", + "skin_infill_line_width": "1.2", + "skeleton_infill_line_width": "1.2", "compatible_printers": ["Ginger G1 1.2 nozzle"] } diff --git a/resources/profiles/Ginger Additive/process/1.50mm Standard.json b/resources/profiles/Ginger Additive/process/1.50mm Standard.json index 9657edc661..09f6147be2 100644 --- a/resources/profiles/Ginger Additive/process/1.50mm Standard.json +++ b/resources/profiles/Ginger Additive/process/1.50mm Standard.json @@ -56,7 +56,7 @@ "travel_acceleration": "2500", "travel_jerk": "7", "travel_speed": "250", - "version": "0.0.0.0", + "version": "0.0.0.1", "wall_generator": "arachne", "wall_loops": "1", "wipe_on_loops": "1", @@ -64,5 +64,7 @@ "xy_contour_compensation": "0", "xy_hole_compensation": "0", "instantiation": "true", + "skin_infill_line_width": "3.0", + "skeleton_infill_line_width": "3.0", "compatible_printers": ["Ginger G1 3.0 nozzle"] } diff --git a/resources/profiles/Ginger Additive/process/1.80mm Vasemode.json b/resources/profiles/Ginger Additive/process/1.80mm Vasemode.json index d081db4351..0405ba1923 100644 --- a/resources/profiles/Ginger Additive/process/1.80mm Vasemode.json +++ b/resources/profiles/Ginger Additive/process/1.80mm Vasemode.json @@ -63,12 +63,14 @@ "travel_acceleration": "2500", "travel_jerk": "7", "travel_speed": "250", - "version": "0.0.0.0", + "version": "0.0.0.1", "wall_loops": "1", "wipe_on_loops": "1", "wipe_speed": "40", "xy_contour_compensation": "0", "xy_hole_compensation": "0", "instantiation": "true", + "skin_infill_line_width": "3.0", + "skeleton_infill_line_width": "3.0", "compatible_printers": ["Ginger G1 3.0 nozzle"] } diff --git a/resources/profiles/Ginger Additive/process/2.50mm Standard.json b/resources/profiles/Ginger Additive/process/2.50mm Standard.json index f43aca97b2..b31a1d1607 100644 --- a/resources/profiles/Ginger Additive/process/2.50mm Standard.json +++ b/resources/profiles/Ginger Additive/process/2.50mm Standard.json @@ -63,7 +63,7 @@ "travel_acceleration": "2500", "travel_jerk": "7", "travel_speed": "250", - "version": "0.0.0.0", + "version": "0.0.0.1", "wall_generator": "arachne", "wall_loops": "1", "wipe_on_loops": "1", @@ -71,5 +71,7 @@ "xy_contour_compensation": "0", "xy_hole_compensation": "0", "instantiation": "true", + "skin_infill_line_width": "5.0", + "skeleton_infill_line_width": "5.0", "compatible_printers": ["Ginger G1 5.0 nozzle"] } diff --git a/resources/profiles/Ginger Additive/process/4.00mm Standard.json b/resources/profiles/Ginger Additive/process/4.00mm Standard.json index fe057dc3f1..58b3e95371 100644 --- a/resources/profiles/Ginger Additive/process/4.00mm Standard.json +++ b/resources/profiles/Ginger Additive/process/4.00mm Standard.json @@ -61,7 +61,7 @@ "travel_acceleration": "2500", "travel_jerk": "7", "travel_speed": "250", - "version": "0.0.0.0", + "version": "0.0.0.1", "wall_generator": "arachne", "wall_loops": "1", "wipe_on_loops": "1", @@ -69,5 +69,7 @@ "xy_contour_compensation": "0", "xy_hole_compensation": "0", "instantiation": "true", + "skin_infill_line_width": "8.0", + "skeleton_infill_line_width": "8.0", "compatible_printers": ["Ginger G1 8.0 nozzle"] } diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index b652ce689f..2257ae5f55 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -5986,6 +5986,11 @@ bool CLI::setup(int argc, char **argv) // The resources are packed to 'resources' // Path from Slic3r binary to resources: boost::filesystem::path path_resources = boost::filesystem::canonical(path_to_binary).parent_path().parent_path() / "resources"; + //Orca: for build systems that support multiple configurations, the binary may be in a subdirectory like "bin/Release" or "bin/Debug". + if( !boost::filesystem::exists(path_resources)) { + // If the resources directory does not exist, try to use the resources directory + path_resources = boost::filesystem::canonical(path_to_binary).parent_path().parent_path().parent_path() / "resources"; + } #endif set_resources_dir(path_resources.string()); diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 1b782a6ee6..6a1bc24d81 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -3,9 +3,6 @@ project(libslic3r) include(PrecompiledHeader) -string(TIMESTAMP COMPILE_TIME %Y%m%d-%H%M%S) -set(SLIC3R_BUILD_TIME ${COMPILE_TIME}) - if(NOT DEFINED ORCA_CHECK_GCODE_PLACEHOLDERS) set(ORCA_CHECK_GCODE_PLACEHOLDERS "0") endif() diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index e56d4b2ec7..e001690ce4 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -41,6 +41,8 @@ struct SurfaceFillParams // FillParams float density = 0.f; + // Infill line multiplier count. + int multiline = 1; // Don't adjust spacing to fill the space evenly. // bool dont_adjust = false; // Length of the infill anchor along the perimeter line. @@ -88,6 +90,7 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(overlap); RETURN_COMPARE_NON_EQUAL(angle); RETURN_COMPARE_NON_EQUAL(density); + RETURN_COMPARE_NON_EQUAL(multiline); // RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust); RETURN_COMPARE_NON_EQUAL(anchor_length); RETURN_COMPARE_NON_EQUAL(anchor_length_max); @@ -117,6 +120,7 @@ struct SurfaceFillParams this->bridge == rhs.bridge && this->bridge_angle == rhs.bridge_angle && this->density == rhs.density && + this->multiline == rhs.multiline && // this->dont_adjust == rhs.dont_adjust && this->anchor_length == rhs.anchor_length && this->anchor_length_max == rhs.anchor_length_max && @@ -647,6 +651,7 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.extruder = layerm.region().extruder(extrusion_role); params.pattern = region_config.sparse_infill_pattern.value; params.density = float(region_config.sparse_infill_density); + params.multiline = int(region_config.fill_multiline); params.lattice_angle_1 = region_config.lattice_angle_1; params.lattice_angle_2 = region_config.lattice_angle_2; params.infill_overhang_angle = region_config.infill_overhang_angle; @@ -1023,6 +1028,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: // apply half spacing using this flow's own spacing and generate infill FillParams params; params.density = float(0.01 * surface_fill.params.density); + params.multiline = surface_fill.params.multiline; params.dont_adjust = false; // surface_fill.params.dont_adjust; params.anchor_length = surface_fill.params.anchor_length; params.anchor_length_max = surface_fill.params.anchor_length_max; @@ -1199,6 +1205,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc params.lattice_angle_1 = surface_fill.params.lattice_angle_1; params.lattice_angle_2 = surface_fill.params.lattice_angle_2; params.infill_overhang_angle = surface_fill.params.infill_overhang_angle; + params.multiline = surface_fill.params.multiline; for (ExPolygon &expoly : surface_fill.expolygons) { // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon. diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp index eadcfbf537..34a1ff1b50 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp @@ -1,7 +1,7 @@ #include "../ClipperUtils.hpp" #include "../ShortestPath.hpp" #include "../Surface.hpp" - +#include "FillBase.hpp" #include "Fill3DHoneycomb.hpp" namespace Slic3r { @@ -212,7 +212,7 @@ void Fill3DHoneycomb::_fill_surface_single( // = 4 * integrate(func=4*x(sqrt(2) - 1) + 1, from=0, to=0.25) // = (sqrt(2) + 1) / 2 [... I think] // make a first guess at the preferred grid Size - coordf_t gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) / params.density); + coordf_t gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) * params.multiline / params.density); // This density calculation is incorrect for many values > 25%, possibly // due to quantisation error, so this value is used as a first guess, then the @@ -228,7 +228,7 @@ void Fill3DHoneycomb::_fill_surface_single( layersPerModule = 2; // re-adjust the grid size for a partial octahedral path // (scale of 1.1 guessed based on modeling) - gridSize = (scale_(this->spacing) * 1.1 / params.density); + gridSize = (scale_(this->spacing) * 1.1 * params.multiline / params.density); // re-adjust zScale to make layering consistent zScale = (gridSize * 2) / (layersPerModule * layerHeight); } else { @@ -238,7 +238,7 @@ void Fill3DHoneycomb::_fill_surface_single( // re-adjust zScale to make layering consistent zScale = (gridSize * 2) / (layersPerModule * layerHeight); // re-adjust the grid size to account for the new zScale - gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) / params.density); + gridSize = (scale_(this->spacing) * ((zScale + 1.) / 2.) * params.multiline / params.density); // re-calculate layersPerModule and zScale layersPerModule = floor((gridSize * 2) / (zScale * layerHeight) + 0.05); if(layersPerModule < 2){ @@ -264,11 +264,24 @@ void Fill3DHoneycomb::_fill_surface_single( // move pattern in place for (Polyline &pl : polylines){ pl.translate(bb.min); + pl.simplify(5 * spacing); // simplify to 5x line width } + // Apply multiline offset if needed + multiline_fill(polylines, params, spacing); + // clip pattern to boundaries, chain the clipped polylines polylines = intersection_pl(polylines, to_polygons(expolygon)); + if (! polylines.empty()) { + // Remove very small bits, but be careful to not remove infill lines connecting thin walls! + // The infill perimeter lines should be separated by around a single infill line width. + const double minlength = scale_(0.8 * this->spacing); + polylines.erase( + std::remove_if(polylines.begin(), polylines.end(), [minlength](const Polyline &pl) { return pl.length() < minlength; }), + polylines.end()); + } + // copy from fliplines if (!polylines.empty()) { int infill_start_idx = polylines_out.size(); // only rotate what belongs to us. diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index d4b117b99d..3ec9ec3685 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -1369,6 +1369,10 @@ void Filler::_fill_surface_single( // Convert lines to polylines. all_polylines.reserve(lines.size()); std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; }); + + // Apply multiline offset if needed + multiline_fill(all_polylines, params, spacing); + // Crop all polylines all_polylines = intersection_pl(std::move(all_polylines), expolygon); #endif diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 9f5a54a0d9..8936f5f55f 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "../ClipperUtils.hpp" #include "../EdgeGrid.hpp" #include "../Geometry.hpp" @@ -25,7 +26,6 @@ // BBS: new infill pattern header #include "FillConcentricInternal.hpp" #include "FillCrossHatch.hpp" - // #define INFILL_DEBUG_OUTPUT namespace Slic3r { @@ -190,22 +190,22 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para // Orca: Dedicated function to calculate gap fill lines for the provided surface, according to the print object parameters // and append them to the out ExtrusionEntityCollection. void Fill::_create_gap_fill(const Surface* surface, const FillParams& params, ExtrusionEntityCollection* out){ - + //Orca: just to be safe, check against null pointer for the print object config and if NULL return. if (this->print_object_config == nullptr) return; - + // Orca: Enable gap fill as per the user preference. Return early if gap fill is to not be applied. if ((this->print_object_config->gap_fill_target.value == gftNowhere) || (surface->surface_type == stInternalSolid && this->print_object_config->gap_fill_target.value != gftEverywhere)) return; - + Flow new_flow = params.flow; ExPolygons unextruded_areas; unextruded_areas = diff_ex(this->no_overlap_expolygons, union_ex(out->polygons_covered_by_spacing(10))); ExPolygons gapfill_areas = union_ex(unextruded_areas); if (!this->no_overlap_expolygons.empty()) gapfill_areas = intersection_ex(gapfill_areas, this->no_overlap_expolygons); - + if (gapfill_areas.size() > 0 && params.density >= 1) { double min = 0.2 * new_flow.scaled_spacing() * (1 - INSET_OVERLAP_TOLERANCE); double max = 2. * new_flow.scaled_spacing(); @@ -222,20 +222,20 @@ void Fill::_create_gap_fill(const Surface* surface, const FillParams& params, Ex std::vector order2 = chain_points(ordering_points); for (size_t i : order2) gaps_ex_sorted.emplace_back(std::move(gaps_ex[i])); - + ThickPolylines polylines; for (ExPolygon& ex : gaps_ex_sorted) { //BBS: Use DP simplify to avoid duplicated points and accelerate medial-axis calculation as well. ex.douglas_peucker(SCALED_RESOLUTION * 0.1); ex.medial_axis(min, max, &polylines); } - + if (!polylines.empty() && !is_bridge(params.extrusion_role)) { polylines.erase(std::remove_if(polylines.begin(), polylines.end(), [&](const ThickPolyline& p) { return p.length() < scale_(params.config->filter_out_gap_fill.value); }), polylines.end()); - + ExtrusionEntityCollection gap_fill; variable_width(polylines, erGapFill, params.flow, gap_fill.entities); auto gap = std::move(gap_fill.entities); @@ -2696,4 +2696,55 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const Polygons &boun connect_base_support(std::move(infill_ordered), polygons_src, bbox, polylines_out, spacing, params); } +//Fill Multiline +void multiline_fill(Polylines& polylines, const FillParams& params, float spacing) +{ + if (params.multiline > 1) { + const int n_lines = params.multiline; + const int n_polylines = static_cast(polylines.size()); + Polylines all_polylines; + all_polylines.reserve(n_lines * n_polylines); + + const float center = (n_lines - 1) / 2.0f; + + for (int line = 0; line < n_lines; ++line) { + float offset = (static_cast(line) - center) * spacing; + + for (const Polyline& pl : polylines) { + const size_t n = pl.points.size(); + if (n < 2) { + all_polylines.emplace_back(pl); + continue; + } + + Points new_points; + new_points.reserve(n); + for (size_t i = 0; i < n; ++i) { + Vec2f tangent; + if (i == 0) + tangent = Vec2f(pl.points[1].x() - pl.points[0].x(), pl.points[1].y() - pl.points[0].y()); + else if (i == n - 1) + tangent = Vec2f(pl.points[n - 1].x() - pl.points[n - 2].x(), pl.points[n - 1].y() - pl.points[n - 2].y()); + else + tangent = Vec2f(pl.points[i + 1].x() - pl.points[i - 1].x(), pl.points[i + 1].y() - pl.points[i - 1].y()); + + float len = std::hypot(tangent.x(), tangent.y()); + if (len == 0) + len = 1.0f; + tangent /= len; + Vec2f normal(-tangent.y(), tangent.x()); + + Point p = pl.points[i]; + p.x() += scale_(normal.x() * offset); + p.y() += scale_(normal.y() * offset); + new_points.push_back(p); + } + + all_polylines.emplace_back(std::move(new_points)); + } + } + polylines = std::move(all_polylines); + } +} + } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 4348ba5127..89974c3fde 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -53,6 +53,7 @@ struct FillParams // Fill density, fraction in <0, 1> float density { 0.f }; + int multiline{1}; // Length of an infill anchor along the perimeter. // 1000mm is roughly the maximum length line that fits into a 32bit coord_t. @@ -223,7 +224,8 @@ public: static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance); }; - + //Fill Multiline + void multiline_fill(Polylines& polylines, const FillParams& params, float spacing); } // namespace Slic3r #endif // slic3r_FillBase_hpp_ diff --git a/src/libslic3r/Fill/FillCrossHatch.cpp b/src/libslic3r/Fill/FillCrossHatch.cpp index 3772a1fec2..359c4252c4 100644 --- a/src/libslic3r/Fill/FillCrossHatch.cpp +++ b/src/libslic3r/Fill/FillCrossHatch.cpp @@ -2,7 +2,7 @@ #include "../ShortestPath.hpp" #include "../Surface.hpp" #include - +#include "FillBase.hpp" #include "FillCrossHatch.hpp" namespace Slic3r { @@ -186,7 +186,8 @@ void FillCrossHatch ::_fill_surface_single( BoundingBox bb = expolygon.contour.bounding_box(); // linespace modifier - coord_t line_spacing = coord_t(scale_(this->spacing) / params.density); + double density_adjusted = params.density / params.multiline; + coord_t line_spacing = coord_t(scale_(this->spacing) / density_adjusted); // reduce density if (params.density < 0.999) line_spacing *= 1.08; @@ -204,6 +205,9 @@ void FillCrossHatch ::_fill_surface_single( // shift the pattern to the actual space for (Polyline &pl : polylines) { pl.translate(bb.min); } + // Apply multiline offset if needed + multiline_fill(polylines, params, spacing); + polylines = intersection_pl(polylines, to_polygons(expolygon)); // --- remove small remains from gyroid infill diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index 12c9a8cfec..caa8459bec 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -4,7 +4,7 @@ #include #include #include - +#include "FillBase.hpp" #include "FillGyroid.hpp" namespace Slic3r { @@ -149,10 +149,10 @@ static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double constexpr double FillGyroid::PatternTolerance; void FillGyroid::_fill_surface_single( - const FillParams ¶ms, + const FillParams ¶ms, unsigned int thickness_layers, - const std::pair &direction, - ExPolygon expolygon, + const std::pair &direction, + ExPolygon expolygon, Polylines &polylines_out) { auto infill_angle = float(this->angle + (CorrectionAngle * 2*M_PI) / 360.); @@ -161,7 +161,7 @@ void FillGyroid::_fill_surface_single( BoundingBox bb = expolygon.contour.bounding_box(); // Density adjusted to have a good %of weight. - double density_adjusted = std::max(0., params.density * DensityAdjust); + double density_adjusted = std::max(0., params.density * DensityAdjust / params.multiline); // Distance between the gyroid waves in scaled coordinates. coord_t distance = coord_t(scale_(this->spacing) / density_adjusted); @@ -184,6 +184,9 @@ void FillGyroid::_fill_surface_single( for (Polyline &pl : polylines) pl.translate(bb.min); + // Apply multiline offset if needed + multiline_fill(polylines, params, spacing); + polylines = intersection_pl(polylines, expolygon); if (! polylines.empty()) { diff --git a/src/libslic3r/Fill/FillHoneycomb.cpp b/src/libslic3r/Fill/FillHoneycomb.cpp index 3e37ddbc84..e750425a82 100644 --- a/src/libslic3r/Fill/FillHoneycomb.cpp +++ b/src/libslic3r/Fill/FillHoneycomb.cpp @@ -7,9 +7,9 @@ namespace Slic3r { void FillHoneycomb::_fill_surface_single( - const FillParams ¶ms, + const FillParams ¶ms, unsigned int thickness_layers, - const std::pair &direction, + const std::pair &direction, ExPolygon expolygon, Polylines &polylines_out) { @@ -19,7 +19,7 @@ void FillHoneycomb::_fill_surface_single( if (it_m == this->cache.end()) { it_m = this->cache.insert(it_m, std::pair(cache_id, CacheData())); CacheData &m = it_m->second; - coord_t min_spacing = coord_t(scale_(this->spacing)); + coord_t min_spacing = coord_t(scale_(this->spacing)) * params.multiline; m.distance = coord_t(min_spacing / params.density); m.hex_side = coord_t(m.distance / (sqrt(3)/2)); m.hex_width = m.distance * 2; // $m->{hex_width} == $m->{hex_side} * sqrt(3); @@ -36,14 +36,14 @@ void FillHoneycomb::_fill_surface_single( { // adjust actual bounding box to the nearest multiple of our hex pattern // and align it so that it matches across layers - + BoundingBox bounding_box = expolygon.contour.bounding_box(); { // rotate bounding box according to infill direction Polygon bb_polygon = bounding_box.polygon(); bb_polygon.rotate(direction.first, m.hex_center); bounding_box = bb_polygon.bounding_box(); - + // extend bounding box so that our pattern will be aligned with other layers // $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one // The infill is not aligned to the object bounding box, but to a world coordinate system. Supposedly good enough. @@ -69,10 +69,13 @@ void FillHoneycomb::_fill_surface_single( x += m.distance; } p.rotate(-direction.first, m.hex_center); + p.simplify(5 * spacing); // simplify to 5x line width all_polylines.push_back(p); } } - + // Apply multiline offset if needed + multiline_fill(all_polylines, params, 1.1 * spacing); + all_polylines = intersection_pl(std::move(all_polylines), expolygon); chain_or_connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params); } diff --git a/src/libslic3r/Fill/FillLightning.cpp b/src/libslic3r/Fill/FillLightning.cpp index 5cd7ae5797..502de9d51c 100644 --- a/src/libslic3r/Fill/FillLightning.cpp +++ b/src/libslic3r/Fill/FillLightning.cpp @@ -1,6 +1,6 @@ #include "../Print.hpp" #include "../ShortestPath.hpp" - +#include "FillBase.hpp" #include "FillLightning.hpp" #include "Lightning/Generator.hpp" @@ -16,6 +16,10 @@ void Filler::_fill_surface_single( const Layer &layer = generator->getTreesForLayer(this->layer_id); Polylines fill_lines = layer.convertToLines(to_polygons(expolygon), scaled(0.5 * this->spacing - this->overlap)); + // Apply multiline offset if needed + multiline_fill(fill_lines, params, spacing); + + chain_or_connect_infill(std::move(fill_lines), expolygon, polylines_out, this->spacing, params); } diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 261ae3c046..62cb005a68 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2956,11 +2956,49 @@ void make_fill_lines(const ExPolygonWithOffset &poly_with_offset, Point refpt, d } } + // Remove lines that are too close to each other. +static inline void remove_overlapped(Polylines& polylines, coord_t line_width){ + const coord_t tolerance = coord_t(0.75 * line_width); + Polylines cleaned; + cleaned.reserve(polylines.size()); + + auto midpoint = [](const Polyline& line) -> Point { + const Point& p1 = line.first_point(); + const Point& p2 = line.last_point(); + return Point((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2); + }; + + for (const Polyline& line : polylines) { + Point mp1 = midpoint(line); + bool overlapped = false; + + for (const Polyline& existing : cleaned) { + Point mp2 = midpoint(existing); + + // Early skip: if they're far apart on one axis, skip + if (std::abs(mp1.y() - mp2.y()) > tolerance && + std::abs(mp1.x() - mp2.x()) > tolerance) + continue; + + if (mp1.distance_to(mp2) < tolerance) { + overlapped = true; + break; + } + } + + if (!overlapped) + cleaned.push_back(line); + } + + polylines = std::move(cleaned); +} + bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list &sweep_params, Polylines &polylines_out) { assert(sweep_params.size() >= 1); - assert(! params.full_infill()); + assert(!params.full_infill()); params.density /= double(sweep_params.size()); + int n_multilines = params.multiline; assert(params.density > 0.0001f && params.density <= 1.f); ExPolygonWithOffset poly_with_offset_base(surface->expolygon, 0, float(scale_(this->overlap - 0.5 * this->spacing))); @@ -2970,16 +3008,28 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar Polylines fill_lines; coord_t line_width = coord_t(scale_(this->spacing)); - coord_t line_spacing = coord_t(scale_(this->spacing) / params.density); + coord_t line_spacing = coord_t(scale_(this->spacing) * params.multiline / params.density); std::pair rotate_vector = this->_infill_direction(surface); for (const SweepParams &sweep : sweep_params) { // Rotate polygons so that we can work with vertical lines here float angle = rotate_vector.first + sweep.angle_base; - make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, - angle), rotate_vector.second.rotated(-angle), angle, line_width + coord_t(SCALED_EPSILON), line_spacing, coord_t(scale_(sweep.pattern_shift)), fill_lines); + //Fill Multiline + for (int i = 0; i < n_multilines; ++i) { + coord_t group_offset = i * line_spacing; + coord_t internal_offset = (i - (n_multilines - 1) / 2.0f) * line_width; + coord_t total_offset = group_offset + internal_offset; + coord_t pattern_shift = scale_(sweep.pattern_shift + unscale_(total_offset)); + + make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, -angle), rotate_vector.second.rotated(-angle), angle, + line_width + coord_t(SCALED_EPSILON), line_spacing, pattern_shift, fill_lines); + } } +if ((params.pattern == ip2DLattice || params.pattern == ip2DHoneycomb ) && params.multiline >1 ) + remove_overlapped(fill_lines, line_width); + if (!fill_lines.empty()) { - if (params.dont_connect()) { + if (params.dont_connect()) { if (fill_lines.size() > 1) fill_lines = chain_polylines(std::move(fill_lines)); append(polylines_out, std::move(fill_lines)); @@ -3057,8 +3107,7 @@ Polylines Fill2DLattice::fill_surface(const Surface *surface, const FillParams & return polylines_out; } -Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams ¶ms) -{ +Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams ¶ms){ Polylines polylines_out; if (! this->fill_surface_by_multilines( surface, params, @@ -3073,7 +3122,7 @@ Polylines FillStars::fill_surface(const Surface *surface, const FillParams ¶ Polylines polylines_out; if (! this->fill_surface_by_multilines( surface, params, - { { 0.f, 0.f }, { float(M_PI / 3.), 0.f }, { float(2. * M_PI / 3.), float((3./2.) * this->spacing / params.density) } }, + { { 0.f, 0.f }, { float(M_PI / 3.), 0.f }, { float(2. * M_PI / 3.), float((3./2.) * this->spacing * params.multiline / params.density) } }, polylines_out)) BOOST_LOG_TRIVIAL(error) << "FillStars::fill_surface() failed to fill a region."; return polylines_out; @@ -3094,7 +3143,6 @@ Polylines FillCubic::fill_surface(const Surface *surface, const FillParams ¶ Polylines FillQuarterCubic::fill_surface(const Surface* surface, const FillParams& params) { using namespace boost::math::float_constants; - Polylines polylines_out; coord_t line_width = coord_t(scale_(this->spacing)); @@ -3139,7 +3187,7 @@ Polylines Fill2DHoneycomb::fill_surface(const Surface *surface, const FillParams using namespace boost::math::float_constants; // lets begin calculating some base properties of the honeycomb pattern - const float half_horizontal_period = .5f * (1*(2/3.f) + 2*(1/3.f)) * float(spacing) / params.density; + const float half_horizontal_period = .5f * (1*(2/3.f) + 2*(1/3.f)) * float(spacing) * params.multiline / params.density; const float vertical_period = 3 * half_horizontal_period / tanf(degree * float(params.infill_overhang_angle)); // we want to align the base pattern with its knot on height 0 diff --git a/src/libslic3r/Fill/FillTpmsD.cpp b/src/libslic3r/Fill/FillTpmsD.cpp index 99692b4b68..4750fc55fc 100644 --- a/src/libslic3r/Fill/FillTpmsD.cpp +++ b/src/libslic3r/Fill/FillTpmsD.cpp @@ -55,8 +55,9 @@ static Polylines make_waves(double gridZ, double density_adjusted, double line_s std::vector> wave; {//fill one wave const auto v=[&](double u){return acos(a/b*cos(u));}; - for(int c=0;c<=4;++c){ - const double u=minU+2*M_PI*c/4; + const int initialSegments=16; + for(int c=0;c<=initialSegments;++c){ + const double u=minU+2*M_PI*c/initialSegments; wave.emplace_back(u,v(u)); } {//refine @@ -110,7 +111,7 @@ void FillTpmsD::_fill_surface_single( BoundingBox bb = expolygon.contour.bounding_box(); // Density adjusted to have a good %of weight. - double density_adjusted = std::max(0., params.density * DensityAdjust); + double density_adjusted = std::max(0., params.density * DensityAdjust / params.multiline); // Distance between the gyroid waves in scaled coordinates. coord_t distance = coord_t(scale_(this->spacing) / density_adjusted); @@ -129,6 +130,8 @@ void FillTpmsD::_fill_surface_single( for (Polyline &pl : polylines) pl.translate(bb.min); + // Apply multiline offset if needed + multiline_fill(polylines, params, spacing); polylines = intersection_pl(polylines, expolygon); diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 255270421a..35ee46b27d 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -785,7 +785,7 @@ static std::vector s_Preset_print_options { "layer_height", "initial_layer_print_height", "wall_loops", "alternate_extra_wall", "slice_closing_radius", "spiral_mode", "spiral_mode_smooth", "spiral_mode_max_xy_smoothing", "spiral_starting_flow_ratio", "spiral_finishing_flow_ratio", "slicing_mode", "top_shell_layers", "top_shell_thickness", "top_surface_density", "bottom_surface_density", "bottom_shell_layers", "bottom_shell_thickness", "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "reduce_crossing_wall", "detect_thin_wall", "detect_overhang_wall", "overhang_reverse", "overhang_reverse_threshold","overhang_reverse_internal_only", "wall_direction", - "seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density", "sparse_infill_pattern", "lattice_angle_1", "lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern", + "seam_position", "staggered_inner_seams", "wall_sequence", "is_infill_first", "sparse_infill_density","fill_multiline", "sparse_infill_pattern", "lattice_angle_1", "lattice_angle_2", "infill_overhang_angle", "top_surface_pattern", "bottom_surface_pattern", "infill_direction", "solid_infill_direction", "counterbore_hole_bridging","infill_shift_step", "sparse_infill_rotate_template", "solid_infill_rotate_template", "symmetric_infill_y_axis","skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density", "minimum_sparse_infill_area", "reduce_infill_retraction","internal_solid_infill_pattern","gap_fill_target", "ironing_type", "ironing_pattern", "ironing_flow", "ironing_speed", "ironing_spacing", "ironing_angle", "ironing_inset", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 42de0f68cc..723c1eb3ef 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2361,6 +2361,14 @@ void PrintConfigDef::init_fff_params() def->max = 100; def->set_default_value(new ConfigOptionPercent(20)); + // Infill multiline + def = this->add("fill_multiline", coInt); + def->label = L("Fill Multiline"); + def->tooltip = L("Using multiple lines for the infill pattern, if supported by infill pattern."); + def->min = 1; + def->max = 5; // Maximum number of lines for infill pattern + def->set_default_value(new ConfigOptionInt(1)); + def = this->add("sparse_infill_pattern", coEnum); def->label = L("Sparse infill pattern"); def->category = L("Strength"); @@ -3119,7 +3127,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This parameter adds a rotation of sparse infill direction to each layer according to the specified template. " "The template is a comma-separated list of angles in degrees, e.g. '0,90'. " "The first angle is applied to the first layer, the second angle to the second layer, and so on. " - "If there are more layers than angles, the angles will be repeated. Note that not all all sparse infill patterns support rotation."); + "If there are more layers than angles, the angles will be repeated. Note that not all sparse infill patterns support rotation."); def->sidetext = L("°"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("0,90")); @@ -3131,7 +3139,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("This parameter adds a rotation of solid infill direction to each layer according to the specified template. " "The template is a comma-separated list of angles in degrees, e.g. '0,90'. " "The first angle is applied to the first layer, the second angle to the second layer, and so on. " - "If there are more layers than angles, the angles will be repeated. Note that not all all solid infill patterns support rotation."); + "If there are more layers than angles, the angles will be repeated. Note that not all solid infill patterns support rotation."); def->sidetext = L("°"); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("0,90")); @@ -3189,7 +3197,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloatOrPercent(0.4, false)); + def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); def = this->add("skeleton_infill_line_width", coFloatOrPercent); def->label = L("Skeleton line width"); @@ -3199,7 +3207,7 @@ void PrintConfigDef::init_fff_params() def->ratio_over = "nozzle_diameter"; def->min = 0; def->mode = comAdvanced; - def->set_default_value(new ConfigOptionFloatOrPercent(0.4, false)); + def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); def = this->add("symmetric_infill_y_axis", coBool); def->label = L("Symmetric infill y axis"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index e811b2f497..de981319d2 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -993,6 +993,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionBool, infill_combination)) // Orca: ((ConfigOptionFloatOrPercent, infill_combination_max_layer_height)) + ((ConfigOptionInt, fill_multiline)) // Ironing options ((ConfigOptionEnum, ironing_type)) ((ConfigOptionEnum, ironing_pattern)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 8c13c43cc2..b07c11163f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1065,6 +1065,7 @@ bool PrintObject::invalidate_state_by_config_options( #endif } else if ( opt_key == "interface_shells" + || opt_key == "infill_multiline" || opt_key == "infill_combination" || opt_key == "infill_combination_max_layer_height" || opt_key == "bottom_shell_thickness" diff --git a/src/libslic3r/libslic3r_version.h.in b/src/libslic3r/libslic3r_version.h.in index 31af715bc7..a0e82cd9d3 100644 --- a/src/libslic3r/libslic3r_version.h.in +++ b/src/libslic3r/libslic3r_version.h.in @@ -9,7 +9,6 @@ #define GIT_COMMIT_HASH "0000000" // 0000000 means uninitialized #endif #define SLIC3R_BUILD_ID "@SLIC3R_BUILD_ID@" -#define SLIC3R_BUILD_TIME "@SLIC3R_BUILD_TIME@" //#define SLIC3R_RC_VERSION "@SLIC3R_VERSION@" #define BBL_RELEASE_TO_PUBLIC @BBL_RELEASE_TO_PUBLIC@ #define BBL_INTERNAL_TESTING @BBL_INTERNAL_TESTING@ diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index c7ac162716..181236fad3 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -262,13 +262,6 @@ AboutDialog::AboutDialog() vesizer->Add(version, 0, wxRIGHT | wxALIGN_RIGHT, FromDIP(20)); vesizer->AddSpacer(FromDIP(5)); vesizer->Add(credits_string, 0, wxRIGHT | wxALIGN_RIGHT, FromDIP(20)); - // #if BBL_INTERNAL_TESTING -// wxString build_time = wxString::Format("Build Time: %s", std::string(SLIC3R_BUILD_TIME)); -// wxStaticText* build_time_text = new wxStaticText(this, wxID_ANY, build_time, wxDefaultPosition, wxDefaultSize); -// build_time_text->SetForegroundColour(wxColour("#FFFFFE")); -// build_time_text->SetBackgroundColour(wxColour("#00AF42")); -// vesizer->Add(build_time_text, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); -// #endif vesizer->Add(0, 0, 1, wxEXPAND, FromDIP(5)); } diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 134538137d..aad4c9be30 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -294,6 +294,7 @@ void ConfigManipulation::update_print_fff_config(DynamicPrintConfig* config, con } double sparse_infill_density = config->option("sparse_infill_density")->value; + int fill_multiline = config->option("fill_multiline")->value; auto timelapse_type = config->opt_enum("timelapse_type"); if (!is_plate_config && @@ -546,6 +547,20 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool have_combined_infill = config->opt_bool("infill_combination") && have_infill; toggle_line("infill_combination_max_layer_height", have_combined_infill); + // Infill patterns that support multiline infill. + InfillPattern pattern = config->opt_enum("sparse_infill_pattern"); + bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ip2DLattice || pattern == ip2DHoneycomb || + pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic; + toggle_line("fill_multiline", have_multiline_infill_pattern); + + // If the infill pattern does not support multiline infill, set fill_multiline to 1. + if (!have_multiline_infill_pattern) { + DynamicPrintConfig new_conf = *config; + new_conf.set_key_value("fill_multiline", new ConfigOptionInt(1)); + apply(config, &new_conf); + } + + // Hide infill anchor max if sparse_infill_pattern is not line or if sparse_infill_pattern is line but infill_anchor_max is 0. bool infill_anchor = config->opt_enum("sparse_infill_pattern") != ipLine; toggle_field("infill_anchor_max",infill_anchor); @@ -576,6 +591,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co bool has_solid_infill = has_top_shell || has_bottom_shell; toggle_field("top_surface_pattern", has_top_shell); toggle_field("bottom_surface_pattern", has_bottom_shell); + toggle_field("top_surface_density", has_top_shell); + toggle_field("bottom_surface_density", has_bottom_shell); for (auto el : { "infill_direction", "sparse_infill_line_width", "sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle", "internal_bridge_angle", diff --git a/src/slic3r/GUI/MediaPlayCtrl.h b/src/slic3r/GUI/MediaPlayCtrl.h index d8c29b729f..7eba8e37ce 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.h +++ b/src/slic3r/GUI/MediaPlayCtrl.h @@ -67,10 +67,10 @@ private: static bool get_stream_url(std::string *url = nullptr); private: - static constexpr wxMediaState MEDIASTATE_IDLE = (wxMediaState) 3; - static constexpr wxMediaState MEDIASTATE_INITIALIZING = (wxMediaState) 4; - static constexpr wxMediaState MEDIASTATE_LOADING = (wxMediaState) 5; - static constexpr wxMediaState MEDIASTATE_BUFFERING = (wxMediaState) 6; + static const wxMediaState MEDIASTATE_IDLE = (wxMediaState) 3; + static const wxMediaState MEDIASTATE_INITIALIZING = (wxMediaState) 4; + static const wxMediaState MEDIASTATE_LOADING = (wxMediaState) 5; + static const wxMediaState MEDIASTATE_BUFFERING = (wxMediaState) 6; wxMediaCtrl2 * m_media_ctrl; wxMediaState m_last_state = MEDIASTATE_IDLE; diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index ae6a79f8b4..87b0287255 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -263,6 +263,28 @@ wxColor PresetComboBox::different_color(wxColor const &clr) wxString PresetComboBox::get_tooltip(const Preset &preset) { wxString tooltip = from_u8(preset.name); + + // Add filament notes if available for filament presets + if (m_type == Preset::TYPE_FILAMENT) { + const DynamicConfig* config = &preset.config; + Tab* tab = wxGetApp().get_tab(m_type); + if (tab && tab->current_preset_is_dirty() && tab->get_presets()->get_selected_preset().name == preset.name) { + config = tab->get_config(); + } + + if (config->has("filament_notes")) { + const ConfigOptionStrings* notes_opt = config->option("filament_notes"); + if (notes_opt && !notes_opt->values.empty() && !notes_opt->values[0].empty()) { + std::string notes = notes_opt->values[0]; + // Truncate if longer than 200 characters + if (notes.length() > 200) { + notes = notes.substr(0, 197) + "..."; + } + tooltip += "\n" + from_u8(notes); + } + } + } + // BBS: FIXME #if 0 if (m_type == Preset::TYPE_FILAMENT) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e7f4a4fc18..64816c5ab7 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1522,7 +1522,7 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } update_wiping_button_visibility(); } - + if (opt_key == "single_extruder_multi_material" ){ const auto bSEMM = m_config->opt_bool("single_extruder_multi_material"); @@ -2137,15 +2137,15 @@ void TabPrint::build() optgroup->append_single_option_line("ironing_angle"); optgroup = page->new_optgroup(L("Wall generator"), L"param_wall_generator"); - optgroup->append_single_option_line("wall_generator", "quality_settings_wall-generator"); - optgroup->append_single_option_line("wall_transition_angle"); - optgroup->append_single_option_line("wall_transition_filter_deviation"); - optgroup->append_single_option_line("wall_transition_length"); - optgroup->append_single_option_line("wall_distribution_count"); - optgroup->append_single_option_line("initial_layer_min_bead_width"); - optgroup->append_single_option_line("min_bead_width"); - optgroup->append_single_option_line("min_feature_size"); - optgroup->append_single_option_line("min_length_factor"); + optgroup->append_single_option_line("wall_generator", "quality_settings_wall_generator"); + optgroup->append_single_option_line("wall_transition_angle", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("wall_transition_filter_deviation", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("wall_transition_length", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("wall_distribution_count", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("initial_layer_min_bead_width", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("min_bead_width", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("min_feature_size", "quality_settings_wall_generator#arachne"); + optgroup->append_single_option_line("min_length_factor", "quality_settings_wall_generator#arachne"); optgroup = page->new_optgroup(L("Walls and surfaces"), L"param_wall_surface"); optgroup->append_single_option_line("wall_sequence"); @@ -2195,41 +2195,42 @@ void TabPrint::build() optgroup->append_single_option_line("detect_thin_wall"); optgroup = page->new_optgroup(L("Top/bottom shells"), L"param_shell"); - optgroup->append_single_option_line("top_shell_layers"); - optgroup->append_single_option_line("top_shell_thickness"); - optgroup->append_single_option_line("top_surface_density"); - optgroup->append_single_option_line("top_surface_pattern"); - optgroup->append_single_option_line("bottom_shell_layers"); - optgroup->append_single_option_line("bottom_shell_thickness"); - optgroup->append_single_option_line("bottom_surface_density"); - optgroup->append_single_option_line("bottom_surface_pattern"); - optgroup->append_single_option_line("top_bottom_infill_wall_overlap"); + optgroup->append_single_option_line("top_shell_layers", "strength_top-bottom_shells"); + optgroup->append_single_option_line("top_shell_thickness", "strength_top-bottom_shells"); + optgroup->append_single_option_line("top_surface_density", "strength_top-bottom_shells"); + optgroup->append_single_option_line("top_surface_pattern", "strength_top-bottom_shells"); + optgroup->append_single_option_line("bottom_shell_layers", "strength_top-bottom_shells"); + optgroup->append_single_option_line("bottom_shell_thickness", "strength_top-bottom_shells"); + optgroup->append_single_option_line("bottom_surface_density", "strength_top-bottom_shells"); + optgroup->append_single_option_line("bottom_surface_pattern", "strength_top-bottom_shells"); + optgroup->append_single_option_line("top_bottom_infill_wall_overlap", "strength_top-bottom_shells"); optgroup = page->new_optgroup(L("Infill"), L"param_infill"); optgroup->append_single_option_line("sparse_infill_density", "strength_settings_infill#sparse-infill-density"); + optgroup->append_single_option_line("fill_multiline"); // fill multiline optgroup->append_single_option_line("sparse_infill_pattern", "strength_settings_infill#sparse-infill-pattern"); - optgroup->append_single_option_line("infill_direction"); - optgroup->append_single_option_line("sparse_infill_rotate_template"); - optgroup->append_single_option_line("skin_infill_density"); - optgroup->append_single_option_line("skeleton_infill_density"); - optgroup->append_single_option_line("infill_lock_depth"); - optgroup->append_single_option_line("skin_infill_depth"); - optgroup->append_single_option_line("skin_infill_line_width", "parameter/line-width"); - optgroup->append_single_option_line("skeleton_infill_line_width", "parameter/line-width"); - optgroup->append_single_option_line("symmetric_infill_y_axis"); - optgroup->append_single_option_line("infill_shift_step"); + optgroup->append_single_option_line("infill_direction", "strength_settings_infill#direction"); + optgroup->append_single_option_line("sparse_infill_rotate_template", "strength_settings_infill#rotation"); + optgroup->append_single_option_line("skin_infill_density", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("skeleton_infill_density", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("infill_lock_depth", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("skin_infill_depth", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("skin_infill_line_width", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("skeleton_infill_line_width", "strength_settings_infill#locked-zag"); + optgroup->append_single_option_line("symmetric_infill_y_axis", "strength_settings_infill#zig-zag"); + optgroup->append_single_option_line("infill_shift_step", "strength_settings_infill#cross-hatch"); - optgroup->append_single_option_line("lattice_angle_1"); - optgroup->append_single_option_line("lattice_angle_2"); - optgroup->append_single_option_line("infill_overhang_angle"); - optgroup->append_single_option_line("infill_anchor_max"); - optgroup->append_single_option_line("infill_anchor"); - optgroup->append_single_option_line("internal_solid_infill_pattern"); - optgroup->append_single_option_line("solid_infill_direction"); - optgroup->append_single_option_line("solid_infill_rotate_template"); - optgroup->append_single_option_line("gap_fill_target"); - optgroup->append_single_option_line("filter_out_gap_fill"); - optgroup->append_single_option_line("infill_wall_overlap"); + optgroup->append_single_option_line("lattice_angle_1", "strength_settings_infill#2d-lattice"); + optgroup->append_single_option_line("lattice_angle_2", "strength_settings_infill#2d-lattice"); + optgroup->append_single_option_line("infill_overhang_angle", "strength_settings_infill#2d-honeycomb"); + optgroup->append_single_option_line("infill_anchor_max", "strength_settings_infill#anchor"); + optgroup->append_single_option_line("infill_anchor", "strength_settings_infill#anchor"); + optgroup->append_single_option_line("internal_solid_infill_pattern", "strength_settings_infill#internal-solid-infill"); + optgroup->append_single_option_line("solid_infill_direction", "strength_settings_infill"); + optgroup->append_single_option_line("solid_infill_rotate_template", "strength_settings_infill"); + optgroup->append_single_option_line("gap_fill_target", "strength_settings_infill#apply-gap-fill"); + optgroup->append_single_option_line("filter_out_gap_fill", "strength_settings_infill"); + optgroup->append_single_option_line("infill_wall_overlap", "strength_settings_infill#infill-wall-overlap"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); optgroup->append_single_option_line("bridge_angle"); @@ -2302,9 +2303,9 @@ void TabPrint::build() optgroup->append_single_option_line("default_junction_deviation"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced", 15); - optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope", "speed_extrusion_rate_smoothing"); - optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_segment_length", "speed_extrusion_rate_smoothing"); - optgroup->append_single_option_line("extrusion_rate_smoothing_external_perimeter_only", "speed_extrusion_rate_smoothing"); + optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope", "speed_settings_extrusion_rate_smoothing"); + optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_segment_length", "speed_settings_extrusion_rate_smoothing"); + optgroup->append_single_option_line("extrusion_rate_smoothing_external_perimeter_only", "speed_settings_extrusion_rate_smoothing"); page = add_options_page(L("Support"), "custom-gcode_support"); // ORCA: icon only visible on placeholders optgroup = page->new_optgroup(L("Support"), L"param_support");