Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_world_coordinates

This commit is contained in:
enricoturri1966 2022-03-28 14:14:12 +02:00
commit 2b8f8a2842
133 changed files with 7201 additions and 3178 deletions

View File

@ -0,0 +1,65 @@
name: Bug Report
description: File a bug report
body:
- type: markdown
attributes:
value: |
Before filing, please check if the issue already exists (either open or closed) by using the search bar on the issues page. If it does, comment there. Even if it's closed, we can reopen it based on your comment.
- type: textarea
id: what-happened
attributes:
label: Description of the bug
description: What happened? Please, enclose a screenshot whenever possible (even when you think the description is clear). What did you expect to happen? In case of 3D rendering issues, please attach the content of menu Help -> System Info dialog.
placeholder: |
What is the problem?
What did you expect?
You paste or drop screenshots here
validations:
required: true
- type: textarea
id: to_reproduce
attributes:
label: Project file & How to reproduce
description: "*Please* upload a ZIP archive containing the project file used when the problem arise. Please export it just before the problem occurs. Even if you did nothing and/or there is no object, export it! (it contains your current configuration)."
placeholder: |
`File`->`Export project as...` then zip it & drop it here
Also, if needed include the steps to reproduce the bug:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: checkboxes
attributes:
label: Checklist of files included above
options:
- label: Project file
- label: Screenshot
validations:
required: true
- type: input
id: version
attributes:
label: Version of PrusaSlicer
description: What version of PrusaSlicer are you running? You can see the full version in `Help` -> `About PrusaSlicer`.
placeholder: e.g. 2.4.1-alpha2-win64 / 2.3.3-linux / 2.4.1-alpha0+61-win64-gcd2459455 ...
validations:
required: true
- type: input
id: os
attributes:
label: Operating system
description: with the version if possible
placeholder: e.g. Windows 7/8/10/11 ... , Ubuntu 22.04/Debian ... , macOS 10.15/11.1 ...
validations:
required: true
- type: input
id: printer
attributes:
label: Printer model
description: Please, fill this in even when it seems irrelevant.
placeholder: voron 2.4 with afterburner
validations:
required: true

9
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,9 @@
contact_links:
- name: PrusaSlicer Manual and Support
url: https://help.prusa3d.com/en/article/customer-support_2287/
about: If you are not sure that what you are reporting is really a bug, please, consult the manual first.
- name: PrusaPrinters Forum
url: https://forum.prusaprinters.org/forum/prusaslicer/
about: Please get in touch on our PrusaPrinters Community Forum! (Not an official support channel.)
blank_issues_enabled: false

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe how it would work**
Be as descriptive as your skill level allows you.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or paint drawing about the feature request here.

View File

@ -164,6 +164,9 @@ IF NOT EXIST "%MSVC_DIR%" (
@ECHO ERROR: Compatible Visual Studio installation not found. 1>&2
GOTO :HELP
)
REM Cmake always defaults to latest supported MSVC generator. Let's make sure it uses what we select.
FOR /F "tokens=* USEBACKQ" %%I IN (`^""%VSWHERE%" %MSVC_FILTER% -nologo -property catalog_productLineVersion^"`) DO SET PS_PRODUCT_VERSION=%%I
REM Give the user a chance to cancel if we found something odd.
IF "%PS_ASK_TO_CONTINUE%" EQU "" GOTO :BUILD_ENV
@ECHO.
@ -183,6 +186,7 @@ SET PS_CURRENT_STEP=environment
@ECHO ** Deps path: %PS_DESTDIR%
@ECHO ** Using Microsoft Visual Studio installation found at:
@ECHO ** %MSVC_DIR%
SET CMAKE_GENERATOR=Visual Studio %PS_VERSION% %PS_PRODUCT_VERSION%
CALL "%MSVC_DIR%\Common7\Tools\vsdevcmd.bat" -arch=%PS_ARCH% -host_arch=%PS_ARCH_HOST% -app_platform=Desktop
IF %ERRORLEVEL% NEQ 0 GOTO :END
REM Need to reset the echo state after vsdevcmd.bat clobbers it.

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.4.1-rc1
0.1.1 Fixed before layer change g-code for Mega Zero.
0.1.0 Added Anycubic 4Max Pro 2.0
min_slic3r_version = 2.3.2-alpha0
0.0.12 Updated Anycubic i3 MEGA(S) profiles.

View File

@ -5,7 +5,7 @@
name = Anycubic
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 0.1.0
config_version = 0.1.1
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -742,7 +742,7 @@ filament_density = 1.27
[printer:*common_mega0*]
printer_technology = FFF
bed_shape = 0x0,220x0,220x220,0x220
before_layer_gcode = ; BEFORE_LAYER_CHANGE [layer_num] @ [layer_z]mm
before_layer_gcode = ; BEFORE_LAYER_CHANGE [layer_num] @ [layer_z]mm\nG92 E0
between_objects_gcode =
deretract_speed = 0
extruder_colour = #FFFF00

View File

@ -1,4 +1,5 @@
min_slic3r_version = 2.4.0-rc
1.4.4 Added multiple Fiberlogy filament profiles. Updated Extrudr filament profiles.
1.4.3 Added new filament profiles and SLA materials.
1.4.2 Added SLA material profiles.
1.4.1 Updated firmware version.

View File

@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 1.4.3
config_version = 1.4.4
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@ -2050,7 +2050,7 @@ compatible_printers_condition = nozzle_diameter[0]!=0.8 and printer_model!="MK2S
inherits = Fillamentum ASA
filament_vendor = Extrudr
bed_temperature = 90
filament_cost = 25.98
filament_cost = 34.64
filament_density = 1.05
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=120"
first_layer_bed_temperature = 90
@ -2083,8 +2083,8 @@ filament_vendor = Extrudr
[filament:Extrudr XPETG CF]
inherits = Extrudr PETG
filament_cost = 49.99
filament_density = 1.41
filament_cost = 62.49
filament_density = 1.29
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=198"
first_layer_temperature = 235
temperature = 235
@ -2125,7 +2125,7 @@ filament_spool_weight = 230
[filament:Extrudr Flax]
inherits = *PLA*
filament_vendor = Extrudr
filament_cost = 56.23
filament_cost = 50.91
filament_density = 1.45
filament_notes = "High Performance Filament for decorative parts.\nPrints as easily as PLA with much higher strength and temperature resistance.\nFully biodegradable with a nice matt finish.\n\nhttps://www.extrudr.com/en/products/catalogue/?material=131"
first_layer_temperature = 190
@ -2140,13 +2140,13 @@ filament_spool_weight = 262
[filament:Extrudr GreenTEC]
inherits = *PLA*
filament_vendor = Extrudr
filament_cost = 56
filament_cost = 50.91
filament_density = 1.3
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=106"
filament_notes = "https://www.extrudr.com/en/products/catalogue/?ignorechildren=1&material=106"
first_layer_temperature = 208
temperature = 208
slowdown_below_layer_time = 20
filament_spool_weight = 230
filament_spool_weight = 262
[filament:Extrudr GreenTEC Pro]
inherits = *PLA*
@ -2164,7 +2164,7 @@ filament_spool_weight = 230
[filament:Extrudr GreenTEC Pro Carbon]
inherits = *PLA*
filament_vendor = Extrudr
filament_cost = 56.23
filament_cost = 62.49
filament_density = 1.2
filament_notes = "High Performance Filament for technical parts.\nPrints as easily as PLA with much higher stregnth and temperature resistance.\nFully biodegradable with a nice matt finish.\n\nhttps://www.extrudr.com/en/products/catalogue/?material=138"
first_layer_temperature = 225
@ -2221,8 +2221,8 @@ extrusion_multiplier = 1.2
filament_cost = 39.98
filament_density = 1.19
filament_deretract_speed = nil
filament_max_volumetric_speed = 2
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=115"
filament_max_volumetric_speed = 3
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=117"
filament_retract_length = 0.4
filament_wipe = nil
filament_spool_weight = 230
@ -2236,8 +2236,8 @@ extrusion_multiplier = 1.2
filament_cost = 39.98
filament_density = 1.18
filament_deretract_speed = nil
filament_max_volumetric_speed = 1.2
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=115"
filament_max_volumetric_speed = 1.8
filament_notes = "https://www.extrudr.com/en/products/catalogue/?material=116"
filament_retract_length = 0.4
filament_wipe = nil
filament_spool_weight = 230
@ -3511,13 +3511,6 @@ filament_density = 1.27
filament_spool_weight = 235
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Fiberlogy PETG]
inherits = *PET*
filament_vendor = Fiberlogy
filament_cost = 21.50
filament_density = 1.27
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Prusament PETG]
inherits = *PET*
filament_vendor = Prusa Polymers
@ -3580,8 +3573,9 @@ filament_density = 1.27
filament_spool_weight = 235
filament_type = PETG
[filament:Fiberlogy PETG @0.6 nozzle]
[filament:Fiberlogy Easy PET-G @0.6 nozzle]
inherits = *PET06*
renamed_from = Fiberlogy PETG @0.6 nozzle
filament_vendor = Fiberlogy
first_layer_temperature = 230
temperature = 240
@ -3673,11 +3667,297 @@ filament_density = 1.24
filament_spool_weight = 230
compatible_printers_condition = nozzle_diameter[0]!=0.8 and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Fiberlogy PLA]
[filament:Fiberlogy Easy PLA]
inherits = *PLA*
renamed_from = Fiberlogy PLA
filament_vendor = Fiberlogy
filament_cost = 25.4
filament_cost = 20
filament_density = 1.24
first_layer_temperature = 220
temperature = 220
filament_spool_weight = 330
[filament:Fiberlogy Easy PET-G]
inherits = *PET*
renamed_from = Fiberlogy PETG
filament_vendor = Fiberlogy
filament_spool_weight = 330
filament_cost = 20
filament_density = 1.27
compatible_printers_condition = nozzle_diameter[0]!=0.6 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
first_layer_bed_temperature = 80
bed_temperature = 80
first_layer_temperature = 235
temperature = 235
min_fan_speed = 15
max_fan_speed = 30
bridge_fan_speed = 60
disable_fan_first_layers = 5
full_fan_speed_layer = 5
slowdown_below_layer_time = 15
[filament:Fiberlogy ASA]
inherits = *ABS*
filament_vendor = Fiberlogy
filament_cost = 33
filament_density = 1.07
filament_spool_weight = 330
fan_always_on = 0
cooling = 1
min_fan_speed = 10
max_fan_speed = 15
bridge_fan_speed = 30
min_print_speed = 15
slowdown_below_layer_time = 15
first_layer_temperature = 260
temperature = 260
first_layer_bed_temperature = 105
bed_temperature = 110
filament_type = ASA
fan_below_layer_time = 30
disable_fan_first_layers = 5
[filament:Fiberlogy ASA @MINI]
inherits = Fiberlogy ASA; *ABSMINI*
[filament:Fiberlogy Easy ABS]
inherits = Fiberlogy ASA
filament_cost = 22.67
filament_density = 1.09
fan_always_on = 0
cooling = 1
min_fan_speed = 10
max_fan_speed = 15
min_print_speed = 15
slowdown_below_layer_time = 15
first_layer_temperature = 250
temperature = 250
first_layer_bed_temperature = 100
bed_temperature = 100
filament_type = ABS
fan_below_layer_time = 25
disable_fan_first_layers = 5
[filament:Fiberlogy Easy ABS @MINI]
inherits = Fiberlogy Easy ABS; *ABSMINI*
[filament:Fiberlogy CPE HT]
inherits = *PET*
filament_vendor = Fiberlogy
filament_cost = 42.67
filament_density = 1.18
extrusion_multiplier = 0.98
filament_spool_weight = 330
fan_always_on = 1
cooling = 1
min_fan_speed = 0
max_fan_speed = 0
bridge_fan_speed = 50
min_print_speed = 15
first_layer_temperature = 275
temperature = 275
first_layer_bed_temperature = 105
bed_temperature = 110
filament_type = CPE
fan_below_layer_time = 20
slowdown_below_layer_time = 15
disable_fan_first_layers = 5
[filament:Fiberlogy PCTG]
inherits = Fiberlogy CPE HT
filament_vendor = Fiberlogy
filament_cost = 29.41
filament_density = 1.23
extrusion_multiplier = 0.98
min_fan_speed = 10
max_fan_speed = 15
bridge_fan_speed = 50
min_print_speed = 15
first_layer_temperature = 265
temperature = 265
first_layer_bed_temperature = 90
bed_temperature = 90
filament_type = CPE
fan_below_layer_time = 20
slowdown_below_layer_time = 15
disable_fan_first_layers = 5
[filament:Fiberlogy FiberFlex 40D]
inherits = *FLEX*
filament_vendor = Fiberlogy
fan_always_on = 1
filament_max_volumetric_speed = 1.5
extrusion_multiplier = 1.12
first_layer_temperature = 230
first_layer_bed_temperature = 60
temperature = 230
bed_temperature = 60
bridge_fan_speed = 75
min_fan_speed = 25
max_fan_speed = 75
filament_retract_before_travel = 2
filament_cost = 39.41
filament_density = 1.16
filament_retract_length = 1.2
filament_retract_speed = nil
filament_deretract_speed = 20
filament_retract_lift = 0
filament_wipe = 0
disable_fan_first_layers = 5
full_fan_speed_layer = 5
min_print_speed = 15
cooling = 1
filament_spool_weight = 330
[filament:Fiberlogy FiberFlex 40D @MINI]
inherits = *FLEXMINI*
filament_vendor = Fiberlogy
filament_max_volumetric_speed = 1.5
fan_always_on = 1
first_layer_temperature = 240
first_layer_bed_temperature = 60
temperature = 240
bed_temperature = 60
filament_retract_length = 4
filament_retract_before_travel = 5
bridge_fan_speed = 80
min_fan_speed = 25
max_fan_speed = 60
min_print_speed = 15
slowdown_below_layer_time = 10
cooling = 1
filament_cost = 84.68
[filament:Fiberlogy MattFlex 40D]
inherits = Fiberlogy FiberFlex 40D
filament_vendor = Fiberlogy
fan_always_on = 1
filament_max_volumetric_speed = 1.35
extrusion_multiplier = 1.1
filament_retract_before_travel = 2
filament_cost = 49.11
filament_retract_length = 1.2
[filament:Fiberlogy FiberFlex 30D]
inherits = Fiberlogy FiberFlex 40D
filament_max_volumetric_speed = 1.2
extrusion_multiplier = 1.15
first_layer_temperature = 240
temperature = 240
min_fan_speed = 25
max_fan_speed = 60
filament_density = 1.07
filament_retract_length = 1.2
[filament:Fiberlogy FiberSatin]
inherits = Fiberlogy Easy PLA
first_layer_temperature = 215
temperature = 215
extrusion_multiplier = 1.03
filament_density = 1.2
filament_cost = 32.35
[filament:Fiberlogy FiberSilk]
inherits = Fiberlogy FiberSatin
first_layer_temperature = 230
temperature = 230
extrusion_multiplier = 0.97
filament_density = 1.22
filament_cost = 32.35
[filament:Fiberlogy FiberWood]
inherits = Fiberlogy Easy PLA
first_layer_temperature = 185
temperature = 185
extrusion_multiplier = 1
filament_density = 1.23
filament_cost = 38.66
filament_max_volumetric_speed = 8
[filament:Fiberlogy HD PLA]
inherits = Fiberlogy Easy PLA
first_layer_temperature = 230
temperature = 230
extrusion_multiplier = 1
filament_density = 1.24
filament_cost = 30.59
[filament:Fiberlogy PLA Mineral]
inherits = Fiberlogy Easy PLA
first_layer_temperature = 195
temperature = 190
extrusion_multiplier = 0.98
filament_density = 1.38
filament_cost = 37.64
filament_max_volumetric_speed = 10
[filament:Fiberlogy Impact PLA]
inherits = Fiberlogy HD PLA
filament_density = 1.22
filament_cost = 27.65
[filament:Fiberlogy Nylon PA12]
inherits = Fiberlogy ASA
filament_type = NYLON
filament_density = 1.01
filament_cost = 48
first_layer_bed_temperature = 105
bed_temperature = 110
first_layer_temperature = 265
temperature = 265
min_fan_speed = 10
max_fan_speed = 15
fan_below_layer_time = 20
bridge_fan_speed = 30
fan_always_on = 0
filament_retract_lift = 0.2
filament_max_volumetric_speed = 6
start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.08{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K26{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0"
[filament:Fiberlogy Nylon PA12+CF15]
inherits = Fiberlogy Nylon PA12
extrusion_multiplier = 0.97
filament_density = 1.07
filament_cost = 87.5
first_layer_bed_temperature = 105
bed_temperature = 110
first_layer_temperature = 265
temperature = 265
min_fan_speed = 10
max_fan_speed = 15
fan_below_layer_time = 20
bridge_fan_speed = 30
fan_always_on = 0
filament_max_volumetric_speed = 8
compatible_printers_condition = nozzle_diameter[0]>=0.4 and printer_model!="MK2SMM" and printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
[filament:Fiberlogy Nylon PA12+GF15]
inherits = Fiberlogy Nylon PA12+CF15
filament_density = 1.13
filament_max_volumetric_speed = 8
[filament:Fiberlogy PP]
inherits = *ABS*
filament_vendor = Fiberlogy
filament_cost = 36.67
filament_density = 1.05
extrusion_multiplier = 1.05
filament_spool_weight = 330
fan_always_on = 1
cooling = 1
min_fan_speed = 0
max_fan_speed = 25
bridge_fan_speed = 70
min_print_speed = 15
slowdown_below_layer_time = 15
first_layer_temperature = 245
temperature = 245
first_layer_bed_temperature = 0
bed_temperature = 0
filament_type = PP
fan_below_layer_time = 100
disable_fan_first_layers = 5
filament_max_volumetric_speed = 5
[filament:Filament PM PLA]
inherits = *PLA*
@ -3736,7 +4016,7 @@ filament_density = 1.24
inherits = *PLA*
filament_vendor = Prusa Polymers
temperature = 215
filament_cost = 30.24
filament_cost = 36.29
filament_density = 1.24
filament_spool_weight = 201
filament_notes = "Affordable filament for everyday printing in premium quality manufactured in-house by Josef Prusa"
@ -3790,7 +4070,7 @@ filament_spool_weight = 230
[filament:Prusament PLA @MMU2]
inherits = *PLA MMU2*
filament_vendor = Prusa Polymers
filament_cost = 30.24
filament_cost = 36.29
filament_density = 1.24
filament_spool_weight = 201
@ -4124,8 +4404,9 @@ renamed_from = "Plasty Mladec PETG @MMU1"
[filament:Verbatim PETG @MMU1]
inherits = Verbatim PETG; *PETMMU1*
[filament:Fiberlogy PETG @MMU1]
inherits = Fiberlogy PETG; *PETMMU1*
[filament:Fiberlogy Easy PET-G @MMU1]
inherits = Fiberlogy Easy PET-G; *PETMMU1*
renamed_from = Fiberlogy PETG @MMU1
[filament:Prusa PETG @MMU1]
inherits = Prusa PETG; *PETMMU1*
@ -4215,8 +4496,9 @@ compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.
inherits = Verbatim PETG; *PETMINI*
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.6
[filament:Fiberlogy PETG @MINI]
inherits = Fiberlogy PETG; *PETMINI*
[filament:Fiberlogy Easy PET-G @MINI]
inherits = Fiberlogy Easy PET-G; *PETMINI*
renamed_from = Fiberlogy PETG @MINI
compatible_printers_condition = printer_model=="MINI" and nozzle_diameter[0]!=0.6
[filament:Generic ABS @MINI]
@ -4303,8 +4585,9 @@ renamed_from = "Plasty Mladec PETG @0.6 nozzle MINI"
[filament:Verbatim PETG @0.6 nozzle MINI]
inherits = Verbatim PETG; *PETMINI06*
[filament:Fiberlogy PETG @0.6 nozzle MINI]
inherits = Fiberlogy PETG; *PETMINI06*
[filament:Fiberlogy Easy PET-G @0.6 nozzle MINI]
inherits = Fiberlogy Easy PET-G; *PETMINI06*
renamed_from = Fiberlogy PETG @0.6 nozzle MINI
[filament:Prusament ASA @MINI]
inherits = Prusament ASA; *ABSMINI*

View File

@ -0,0 +1,2 @@
min_slic3r_version = 2.4.1
1.0.0 Initial Snapmaker bundle

View File

@ -0,0 +1,473 @@
# Snapmaker profiles
# Based on the profiles from: https://github.com/nivekmai/snapmaker-prusa by nivekmai, WilliamBosacker, mrworf
[vendor]
# Vendor name will be shown by the Config Wizard.
name = Snapmaker
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the Slic3r configuration to be downgraded.
config_version = 1.0.0
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Snapmaker/
# The printer models will be shown by the Configuration Wizard in this order,
[printer_model:A250]
name = Snapmaker A250
variants = 0.4
technology = FFF
bed_model = A250_bed.stl
bed_texture = A250_texture.svg
default_materials = Generic PLA @Snapmaker; Generic PETG @Snapmaker
[printer_model:A350]
name = Snapmaker A350
variants = 0.4
technology = FFF
bed_model = A350_bed.stl
bed_texture = A350_texture.svg
default_materials = Generic PLA @Snapmaker; Generic PETG @Snapmaker
[print:*common*]
avoid_crossing_perimeters = 1
avoid_crossing_perimeters_max_detour = 0
bottom_fill_pattern = monotonic
bottom_solid_layers = 4
bottom_solid_min_thickness = 0
bridge_acceleration = 0
bridge_angle = 0
bridge_flow_ratio = 1
bridge_speed = 60
brim_separation = 0
brim_type = outer_only
brim_width = 0
clip_multipart_objects = 1
complete_objects = 0
default_acceleration = 0
dont_support_bridges = 1
draft_shield = disabled
elefant_foot_compensation = 0.1
ensure_vertical_shell_thickness = 1
external_perimeter_extrusion_width = 0.45
external_perimeter_speed = 50%
external_perimeters_first = 0
extra_perimeters = 0
extruder_clearance_height = 25
extruder_clearance_radius = 75
extrusion_width = 0.45
fill_angle = 45
fill_density = 20%
fill_pattern = gyroid
first_layer_acceleration = 0
first_layer_acceleration_over_raft = 0
first_layer_extrusion_width = 0.45
first_layer_height = 0.2
first_layer_speed = 15
first_layer_speed_over_raft = 30
fuzzy_skin = none
fuzzy_skin_point_dist = 0.8
fuzzy_skin_thickness = 0.3
gap_fill_enabled = 1
gap_fill_speed = 20
gcode_comments = 0
gcode_label_objects = 0
gcode_resolution = 0.0125
gcode_substitutions =
infill_acceleration = 0
infill_anchor = 600%
infill_anchor_max = 50
infill_every_layers = 1
infill_extruder = 1
infill_extrusion_width = 0.45
infill_first = 0
infill_only_where_needed = 0
infill_overlap = 25%
infill_speed = 100
inherits =
interface_shells = 0
ironing = 0
ironing_flowrate = 15%
ironing_spacing = 0.25
ironing_speed = 15
ironing_type = top
layer_height = 0.2
max_print_speed = 100
max_volumetric_speed = 0
min_skirt_length = 4
mmu_segmented_region_max_width = 0
notes =
only_retract_when_crossing_perimeters = 0
ooze_prevention = 0
output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{printer_model}_{print_time}.gcode
overhangs = 0
perimeter_acceleration = 0
perimeter_extruder = 1
perimeter_extrusion_width = 0.45
perimeter_speed = 60
perimeters = 2
post_process =
print_settings_id =
raft_contact_distance = 0.1
raft_expansion = 1.5
raft_first_layer_density = 90%
raft_first_layer_expansion = 3
raft_layers = 0
resolution = 0
seam_position = nearest
single_extruder_multi_material_priming = 1
skirt_distance = 5
skirt_height = 1
skirts = 3
slice_closing_radius = 0.049
slicing_mode = regular
small_perimeter_speed = 25%
solid_infill_below_area = 0
solid_infill_every_layers = 0
solid_infill_extruder = 1
solid_infill_extrusion_width = 0.45
solid_infill_speed = 80%
spiral_vase = 0
standby_temperature_delta = -5
support_material = 0
support_material_angle = 0
support_material_auto = 1
support_material_bottom_contact_distance = 0
support_material_bottom_interface_layers = -1
support_material_buildplate_only = 0
support_material_closing_radius = 2
support_material_contact_distance = 0.15
support_material_enforce_layers = 0
support_material_extruder = 0
support_material_extrusion_width = 0.38
support_material_interface_contact_loops = 0
support_material_interface_extruder = 0
support_material_interface_layers = 2
support_material_interface_pattern = rectilinear
support_material_interface_spacing = 0.2
support_material_interface_speed = 100%
support_material_pattern = rectilinear
support_material_spacing = 2
support_material_speed = 60
support_material_style = grid
support_material_synchronize_layers = 0
support_material_threshold = 45
support_material_with_sheath = 0
support_material_xy_spacing = 60%
thick_bridges = 1
thin_walls = 0
threads = 8
top_fill_pattern = monotonic
top_infill_extrusion_width = 0.4
top_solid_infill_speed = 60%
top_solid_layers = 4
top_solid_min_thickness = 0
travel_speed = 150
travel_speed_z = 0
wipe_tower = 0
wipe_tower_bridging = 10
wipe_tower_brim_width = 2
wipe_tower_no_sparse_layers = 0
wipe_tower_rotation_angle = 0
wipe_tower_width = 60
wipe_tower_x = 170
wipe_tower_y = 140
xy_size_compensation = 0
compatible_printers_condition = nozzle_diameter[0]==0.4
[print:0.10mm HIGHDETAIL @SnapmakerA350]
inherits = *common*
layer_height = 0.1
bottom_solid_layers = 7
top_solid_layers = 8
top_solid_min_thickness = 0.8
bottom_solid_min_thickness = 0.8
bridge_speed = 40
infill_speed = 50
perimeter_speed = 40
support_material_speed = 40
max_print_speed = 50
skirt_distance = 10
first_layer_speed = 25%
compatible_printers_condition = nozzle_diameter[0]==0.4 and printer_model=="A350"
[print:0.16mm OPTIMAL @SnapmakerA350]
inherits = *common*
layer_height = 0.16
top_solid_layers = 6
bottom_solid_layers = 6
first_layer_speed = 25%
max_print_speed = 60
compatible_printers_condition = nozzle_diameter[0]==0.4 and printer_model=="A350"
[print:0.20mm NORMAL @SnapmakerA350]
inherits = *common*
compatible_printers_condition = nozzle_diameter[0]==0.4 and printer_model=="A350"
[print:0.20mm FAST @SnapmakerA350]
inherits = 0.20mm NORMAL @SnapmakerA350
bridge_speed = 80
gap_fill_speed = 30
infill_speed = 120
ironing_speed = 20
perimeter_speed = 80
support_material_speed = 80
compatible_printers_condition = nozzle_diameter[0]==0.4 and printer_model=="A350"
[print:0.08mm DETAIL @SnapmakerA250]
inherits = 0.20mm NORMAL @SnapmakerA250
layer_height = 0.08
infill_speed = 40
external_perimeter_speed = 10
perimeter_speed = 15
top_solid_infill_speed = 20
travel_speed = 70
first_layer_extrusion_width = 0.45
perimeter_extrusion_width = 0.4
external_perimeter_extrusion_width = 0.4
infill_extrusion_width = 0.4
solid_infill_extrusion_width = 0.4
top_infill_extrusion_width = 0.4
[print:0.20mm NORMAL @SnapmakerA250]
inherits = *common*
compatible_printers_condition = nozzle_diameter[0]==0.4 and printer_model=="A250"
first_layer_speed = 15
gap_fill_speed = 15
infill_speed = 50
perimeter_speed = 25
small_perimeter_speed = 20
external_perimeter_speed = 15
support_material_speed = 25
top_solid_infill_speed = 25
travel_speed = 80
max_print_speed = 80
skirt_distance = 3
min_skirt_length = 25
[print:0.24mm FAST @SnapmakerA250]
inherits = 0.20mm NORMAL @SnapmakerA250
layer_height = 0.24
infill_speed = 60
external_perimeter_speed = 20
top_solid_infill_speed = 30
[filament:*common*]
bed_temperature = 60
bridge_fan_speed = 100
compatible_printers =
compatible_printers_condition =
compatible_prints =
compatible_prints_condition =
cooling = 1
disable_fan_first_layers = 3
end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n"
extrusion_multiplier = 1
fan_always_on = 1
fan_below_layer_time = 60
filament_colour = #29B2B2
filament_cooling_final_speed = 3.4
filament_cooling_initial_speed = 2.2
filament_cooling_moves = 4
filament_cost = 0
filament_density = 0
filament_deretract_speed = nil
filament_diameter = 1.75
filament_load_time = 0
filament_loading_speed = 28
filament_loading_speed_start = 3
filament_max_volumetric_speed = 0
filament_minimal_purge_on_wipe_tower = 15
filament_notes = ""
filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6"
filament_retract_before_travel = nil
filament_retract_before_wipe = nil
filament_retract_layer_change = nil
filament_retract_length = nil
filament_retract_lift = nil
filament_retract_lift_above = nil
filament_retract_lift_below = nil
filament_retract_restart_extra = nil
filament_retract_speed = nil
filament_settings_id = ""
filament_soluble = 0
filament_spool_weight = 0
filament_toolchange_delay = 0
filament_type = PLA
filament_unload_time = 0
filament_unloading_speed = 90
filament_unloading_speed_start = 100
filament_wipe = nil
first_layer_bed_temperature = 60
first_layer_temperature = 210
full_fan_speed_layer = 0
inherits =
max_fan_speed = 100
min_fan_speed = 35
min_print_speed = 10
slowdown_below_layer_time = 5
start_filament_gcode = "; Filament gcode\n"
temperature = 210
[filament:*PLA*]
inherits = *common*
[filament:*PETG*]
inherits = *common*
first_layer_bed_temperature = 80
bed_temperature = 75
first_layer_temperature = 245
temperature = 245
filament_density = 1.27
disable_fan_first_layers = 3
min_fan_speed = 20
max_fan_speed = 50
fan_below_layer_time = 20
min_print_speed = 20
filament_max_volumetric_speed = 8
filament_type = PETG
[filament:Generic PLA @Snapmaker]
inherits = *PLA*
filament_vendor = Generic
[filament:Generic PETG @Snapmaker]
inherits = *PETG*
filament_vendor = Generic
[filament:Snapmaker PLA @Snapmaker]
inherits = *PLA*
filament_vendor = Snapmaker
[filament:Overture PLA @Snapmaker]
inherits = *PLA*
filament_vendor = Overture
bed_temperature = 50
first_layer_temperature = 205
temperature = 205
filament_density = 1.24
disable_fan_first_layers = 1
min_fan_speed = 100
max_fan_speed = 100
full_fan_speed_layer = 3
fan_below_layer_time = 100
min_print_speed = 15
filament_max_volumetric_speed = 0
[filament:MatterHackers Build Translucent @Snapmaker]
inherits = *PETG*
filament_vendor = MatterHackers
[filament:MatterHackers Build White @Snapmaker]
inherits = MatterHackers Build Translucent @Snapmaker
bed_temperature = 65
first_layer_bed_temperature = 70
first_layer_temperature = 260
temperature = 255
filament_density = 1.28
disable_fan_first_layers = 3
full_fan_speed_layer = 5
min_fan_speed = 40
max_fan_speed = 100
fan_below_layer_time = 60
min_print_speed = 10
[filament:Overture TPU @Snapmaker]
inherits = *common*
filament_vendor = Overture
filament_type = FLEX
first_layer_temperature = 220
temperature = 220
filament_density = 1.22
disable_fan_first_layers = 1
min_fan_speed = 100
max_fan_speed = 100
fan_below_layer_time = 100
min_print_speed = 15
filament_retract_speed = 40
filament_deretract_speed = 25
filament_retract_length = 1.8
filament_max_volumetric_speed = 3
# Common printer preset
[printer:*common*]
bed_shape = 0x0,320x0,320x350,0x350
color_change_gcode = M600
cooling_tube_length = 5
cooling_tube_retraction = 91.5
default_filament_profile = ""
default_print_profile =
end_gcode = ;End GCode begin\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off\nG90 ;absolute positioning\nG92 E0\nG1 E-2 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG28 X0 Y0 ; home\nM84 ;steppers off\nM107 ;fan off\nM82 ;absolute extrusion mode\n;End GCode end
extra_loading_move = -2
extruder_colour = ""
extruder_offset = 0x0
gcode_flavor = marlin
high_current_on_filament_swap = 0
machine_limits_usage = time_estimate_only
machine_max_acceleration_e = 10000
machine_max_acceleration_extruding = 1000
machine_max_acceleration_retracting = 1000
machine_max_acceleration_travel = 1500
machine_max_acceleration_x = 3000
machine_max_acceleration_y = 3000
machine_max_acceleration_z = 100
machine_max_feedrate_e = 25
machine_max_feedrate_x = 150
machine_max_feedrate_y = 150
machine_max_feedrate_z = 50
machine_max_jerk_e = 2.5
machine_max_jerk_x = 10
machine_max_jerk_y = 10
machine_max_jerk_z = 0.2
machine_min_extruding_rate = 0
machine_min_travel_rate = 0
max_layer_height = 0.3
max_print_height = 330
min_layer_height = 0.08
nozzle_diameter = 0.4
parking_pos_retraction = 92
pause_print_gcode =
printer_technology = FFF
remaining_times = 0
retract_before_travel = 2
retract_before_wipe = 0%
retract_layer_change = 1
retract_length = 3
retract_length_toolchange = 10
retract_lift = 0
retract_lift_above = 0
retract_lift_below = 328
retract_restart_extra = 0
retract_restart_extra_toolchange = 0
retract_speed = 60
deretract_speed = 40
silent_mode = 0
single_extruder_multi_material = 0
start_gcode = M82 ;absolute extrusion mode\n;Start GCode begin\nM140 S[first_layer_bed_temperature] ;Start warming Bed\nM104 S[first_layer_temperature] ;Start warming Nozzle\nG28 ; home all axes\nG90 ;absolute positioning\nG1 X-10 Y-10 F3000\nG1 Z0 F1800\nM190 S[first_layer_bed_temperature] ;Wait For Bed Temperature\nM109 S[first_layer_temperature] ;Wait for Hotend Temperature\nG92 E0\nG1 E20 F200 ; Prime extrude for wipe\nG92 E0
thumbnails = 16x16,220x124
use_firmware_retraction = 0
use_relative_e_distances = 0
use_volumetric_e = 0
variable_layer_height = 1
wipe = 0
z_offset = 0
[printer:Snapmaker A350]
inherits = *common*
printer_model = A350
printer_variant = 0.4
default_filament_profile = Generic PLA @Snapmaker
default_print_profile = 0.20mm NORMAL @SnapmakerA350
[printer:Snapmaker A250]
inherits = *common*
printer_model = A250
printer_variant = 0.4
bed_shape = 0x0,230x0,230x250,0x250
thumbnails =
variable_layer_height = 0
retract_lift_below = 0
max_print_height = 235
start_gcode = M82 ;absolute extrusion mode\n;Start GCode begin\nM140 S[first_layer_bed_temperature] ;Start Warming Bed\nM104 S160 ;Preheat Nozzle\nG28 ; home all axes\nG90 ;absolute positioning\nG1 X-10 Y-10 F3000\nG1 Z0 F1800\nG1 Z5 F5000 ; lift nozzle\nM190 S[first_layer_bed_temperature] ;Wait For Bed Temperature\nM109 S[first_layer_temperature] ;Wait for Hotend Temperature\nG92 E0\nG1 E10 F200\nG1 E-2 F300\nG92 E0\n;Start GCode end\nG1 F3600 E-2
end_gcode = M140 S0\n;End GCode begin\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG90 ;absolute positioning\nG92 E0\nG1 E-2 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z330 E-1 F80 ;move Z up a bit and retract filament even more\nG1 X0 F3000 ;move X to min endstops, so the head is out of the way\nG1 Y250 F3000 ;so the head is out of the way and Plate is moved forward\nM84 ;steppers off\n;End GCode end\nM82 ;absolute extrusion mode\nM104 S0\nM107\n;End of Gcode
default_filament_profile = Generic PLA @Snapmaker
default_print_profile = 0.20mm NORMAL @SnapmakerA250

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -1,2 +1,4 @@
min_slic3r_version = 2.4.0-beta0
1.0.2 Fixed start g-code.
1.0.1 Updated start g-code.
1.0.0 Initial version

View File

@ -9,7 +9,7 @@ name = Ultimaker
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
config_version = 1.0.0
config_version = 1.0.2
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Ultimaker/
@ -396,5 +396,5 @@ printer_notes = Dont remove the following keywords! These keywords are used in t
nozzle_diameter = 0.4
default_print_profile = 0.20mm NORMAL @ULTIMAKER2
default_filament_profile = Generic PLA @ULTIMAKER2
start_gcode = ; Printer_Settings_ID: [printer_settings_id]\n\n; # # # # # # START Header\nG21 ; metric values\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nM107 ; start with the fan off\n\nG28 X0 Y0 Z0 ; move X/Y/Z to endstops\nG1 X1 Y6 F15000 ; move X/Y to start position\nG1 Z35 F9000 ; move Z to start position\n\n; Heat up bed and nozzle\nM190 S{first_layer_bed_temperature[0] - 5} ; wait for bed temperature - 5\nM140 S[first_layer_bed_temperature] ; continue bed heating\nM109 S[first_layer_temperature] ; wait for nozzle temperature\n\nG92 E0 ; zero the extruded length\nG1 F150 E22 ; purge nozzle with filament\nG92 E0 ; zero the extruded length again\nG1 F75 E7 ; additional priming\nG92 E0 ; zero the extruded length again\n\n; # # # # # # END Header
start_gcode = ; Printer_Settings_ID: [printer_settings_id]\n\n; # # # # # # START Header\nG21 ; metric values\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nM107 ; start with the fan off\n\nM140 S[first_layer_bed_temperature] ; start bed heating\n\nG28 X0 Y0 Z0 ; move X/Y/Z to endstops\nG1 X1 Y6 F15000 ; move X/Y to start position\nG1 Z35 F9000 ; move Z to start position\n\n; Wait for bed and nozzle temperatures\nM190 S{first_layer_bed_temperature[0] - 5} ; wait for bed temperature - 5\nM140 S[first_layer_bed_temperature] ; continue bed heating\nM109 S[first_layer_temperature] ; wait for nozzle temperature\n\n; Purge and prime\nM83 ; set extruder to relative mode\nG92 E0 ; reset extrusion distance\nG0 X0 Y1 F10000\nG1 F150 E20 ; compress the bowden tube\nG1 E-8 F1200\nG0 X30 Y1 F5000 \nG0 F1200 Z{first_layer_height/2} ; Cut the connection to priming blob\nG0 X100 F10000 ; disconnect with the prime blob\nG0 X50 ; Avoid the metal clip holding the Ultimaker glass plate\nG0 Z0.2 F720\nG1 E8 F1200\nG1 X80 E3 F1000 ; intro line 1\nG1 X110 E4 F1000 ; intro line 2\nG1 X140 F600 ; drag filament to decompress bowden tube\nG1 X100 F3200 ; wipe backwards a bit\nG1 X150 F3200 ; back to where there is no plastic: avoid dragging\nG92 E0 ; reset extruder reference\nM82 ; set extruder to absolute mode\n\n; # # # # # # END Header
end_gcode = ; # # # # # # START Footer\nG91 ; relative coordinates\n;G1 E-1 F1200 ; retract the filament\nG1 Z+15 X-10 Y-10 E-7 F6000 ; move Z a bit\n; G1 X-10 Y-10 F6000 ; move XY a bit\nG1 E-5.5 F300 ; retract the filament\nG28 X0 Y0 ; move X/Y to min endstops, so the head is out of the way\nM104 S0 ; extruder heater off\nM140 S0 ; heated bed heater off (if you have it)\nM84 ; disable motors\n; # # # # # # END Footer\n

View File

@ -0,0 +1,11 @@
#version 110
uniform vec4 top_color;
uniform vec4 bottom_color;
varying vec2 tex_coord;
void main()
{
gl_FragColor = mix(bottom_color, top_color, tex_coord.y);
}

View File

@ -0,0 +1,8 @@
#version 110
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

@ -1,10 +1,10 @@
#version 110
attribute vec3 v_position;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);

View File

@ -0,0 +1,10 @@
#version 110
uniform sampler2D uniform_texture;
varying vec2 tex_coord;
void main()
{
gl_FragColor = texture2D(uniform_texture, tex_coord);
}

View File

@ -1,11 +1,11 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
attribute vec2 v_tex_coord;
varying vec2 tex_coord;
void main()

View File

@ -0,0 +1,86 @@
#version 110
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const float EPSILON = 0.0001;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform vec4 uniform_color;
uniform SlopeDetection slope;
uniform bool offset_depth_buffer;
#ifdef ENABLE_ENVIRONMENT_MAP
uniform sampler2D environment_tex;
uniform bool use_environment_tex;
#endif // ENABLE_ENVIRONMENT_MAP
uniform PrintVolumeDetection print_volume;
varying vec3 clipping_planes_dots;
// x = diffuse, y = specular;
varying vec2 intensity;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
color = vec3(0.7, 0.7, 1.0);
alpha = 1.0;
}
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = ZERO;
vec3 pv_check_max = ZERO;
if (print_volume.type == 0) {
// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
}
else if (print_volume.type == 1) {
// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
}
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
#ifdef ENABLE_ENVIRONMENT_MAP
if (use_environment_tex)
gl_FragColor = vec4(0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
else
#endif
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
// In the support painting gizmo and the seam painting gizmo are painted triangles rendered over the already
// rendered object. To resolved z-fighting between previously rendered object and painted triangles, values
// inside the depth buffer are offset by small epsilon for painted triangles inside those gizmos.
gl_FragDepth = gl_FragCoord.z - (offset_depth_buffer ? EPSILON : 0.0);
}

View File

@ -25,9 +25,6 @@ struct SlopeDetection
mat3 volume_world_normal_matrix;
};
attribute vec3 v_position;
attribute vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
@ -39,6 +36,9 @@ uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
attribute vec3 v_position;
attribute vec3 v_normal;
// x = diffuse, y = specular;
varying vec2 intensity;

View File

@ -0,0 +1,12 @@
#version 110
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -14,13 +14,13 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
attribute vec3 v_position;
attribute vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
attribute vec3 v_position;
attribute vec3 v_normal;
// x = tainted, y = specular;
varying vec2 intensity;

View File

@ -0,0 +1,12 @@
#version 110
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
varying vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -14,6 +14,10 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
// vertex attributes
attribute vec3 v_position;
attribute vec3 v_normal;
@ -21,10 +25,6 @@ attribute vec3 v_normal;
attribute vec3 i_offset;
attribute vec2 i_scales;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
// x = tainted, y = specular;
varying vec2 intensity;

View File

@ -1,10 +1,10 @@
#version 110
attribute vec3 v_position;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);

View File

@ -2,8 +2,6 @@
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
attribute vec3 v_position;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
@ -13,6 +11,8 @@ uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
attribute vec3 v_position;
varying vec3 clipping_planes_dots;
varying vec4 model_pos;

View File

@ -0,0 +1,34 @@
#version 110
const vec3 back_color_dark = vec3(0.235, 0.235, 0.235);
const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
uniform sampler2D texture;
uniform bool transparent_background;
uniform bool svg_source;
varying vec2 tex_coord;
vec4 svg_color()
{
// takes foreground from texture
vec4 fore_color = texture2D(texture, tex_coord);
// calculates radial gradient
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5)))));
// blends foreground with background
return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
}
vec4 non_svg_color()
{
// takes foreground from texture
vec4 color = texture2D(texture, tex_coord);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}
void main()
{
gl_FragColor = svg_source ? svg_color() : non_svg_color();
}

View File

@ -1,11 +1,11 @@
#version 110
attribute vec3 v_position;
attribute vec2 v_tex_coord;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
attribute vec3 v_position;
attribute vec2 v_tex_coord;
varying vec2 tex_coord;
void main()

View File

@ -0,0 +1,19 @@
#version 110
const vec4 BLACK = vec4(vec3(0.1), 1.0);
const vec4 WHITE = vec4(vec3(1.0), 1.0);
const float emission_factor = 0.25;
uniform vec3 world_center;
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 world_position;
void main()
{
vec3 delta = world_position - world_center;
vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0);
}

View File

@ -14,13 +14,13 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
attribute vec3 v_position;
attribute vec3 v_normal;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
attribute vec3 v_position;
attribute vec3 v_normal;
// x = tainted, y = specular;
varying vec2 intensity;
varying vec3 world_position;

View File

@ -0,0 +1,41 @@
#version 110
#define M_PI 3.1415926535897932384626433832795
// 2D texture (1D texture split by the rows) of color along the object Z axis.
uniform sampler2D z_texture;
// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
uniform float z_to_texture_row;
uniform float z_texture_row_to_normalized;
uniform float z_cursor;
uniform float z_cursor_band_width;
// x = tainted, y = specular;
varying vec2 intensity;
varying float object_z;
void main()
{
float object_z_row = z_to_texture_row * object_z;
// Index of the row in the texture.
float z_texture_row = floor(object_z_row);
// Normalized coordinate from 0. to 1.
float z_texture_col = object_z_row - z_texture_row;
float z_blend = 0.25 * cos(min(M_PI, abs(M_PI * (object_z - z_cursor) * 1.8 / z_cursor_band_width))) + 0.25;
// Calculate level of detail from the object Z coordinate.
// This makes the slowly sloping surfaces to be shown with high detail (with stripes),
// and the vertical surfaces to be shown with low detail (no stripes)
float z_in_cells = object_z_row * 190.;
// Gradient of Z projected on the screen.
float dx_vtc = dFdx(z_in_cells);
float dy_vtc = dFdy(z_in_cells);
float lod = clamp(0.5 * log2(max(dx_vtc * dx_vtc, dy_vtc * dy_vtc)), 0., 1.);
// Sample the Z texture. Texture coordinates are normalized to <0, 1>.
vec4 color = vec4(0.25, 0.25, 0.25, 1.0);
if (z_texture_row >= 0.0)
color = mix(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
// Mix the final color.
gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
}

View File

@ -14,16 +14,16 @@ const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define INTENSITY_AMBIENT 0.3
attribute vec3 v_position;
attribute vec3 v_normal;
attribute vec2 v_tex_coord;
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
uniform mat4 volume_world_matrix;
uniform float object_max_z;
attribute vec3 v_position;
attribute vec3 v_normal;
attribute vec2 v_tex_coord;
// x = tainted, y = specular;
varying vec2 intensity;

View File

@ -0,0 +1,11 @@
#version 140
uniform vec4 top_color;
uniform vec4 bottom_color;
in vec2 tex_coord;
void main()
{
gl_FragColor = mix(bottom_color, top_color, tex_coord.y);
}

View File

@ -0,0 +1,12 @@
#version 140
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coord;
void main()
{
tex_coord = v_tex_coord;
gl_Position = vec4(v_position, 1.0);
}

View File

@ -0,0 +1,8 @@
#version 140
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,10 @@
#version 140
uniform sampler2D uniform_texture;
in vec2 tex_coord;
void main()
{
gl_FragColor = texture(uniform_texture, tex_coord);
}

View File

@ -0,0 +1,15 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coord;
void main()
{
tex_coord = v_tex_coord;
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,86 @@
#version 140
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const float EPSILON = 0.0001;
struct PrintVolumeDetection
{
// 0 = rectangle, 1 = circle, 2 = custom, 3 = invalid
int type;
// type = 0 (rectangle):
// x = min.x, y = min.y, z = max.x, w = max.y
// type = 1 (circle):
// x = center.x, y = center.y, z = radius
vec4 xy_data;
// x = min z, y = max z
vec2 z_data;
};
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform vec4 uniform_color;
uniform SlopeDetection slope;
uniform bool offset_depth_buffer;
#ifdef ENABLE_ENVIRONMENT_MAP
uniform sampler2D environment_tex;
uniform bool use_environment_tex;
#endif // ENABLE_ENVIRONMENT_MAP
uniform PrintVolumeDetection print_volume;
in vec3 clipping_planes_dots;
// x = diffuse, y = specular;
in vec2 intensity;
in vec4 world_pos;
in float world_normal_z;
in vec3 eye_normal;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
if (slope.actived && world_normal_z < slope.normal_z - EPSILON) {
color = vec3(0.7, 0.7, 1.0);
alpha = 1.0;
}
// if the fragment is outside the print volume -> use darker color
vec3 pv_check_min = ZERO;
vec3 pv_check_max = ZERO;
if (print_volume.type == 0) {
// rectangle
pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x);
pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y);
}
else if (print_volume.type == 1) {
// circle
float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy);
pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x);
pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y);
}
color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color;
#ifdef ENABLE_ENVIRONMENT_MAP
if (use_environment_tex)
gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color * intensity.x, alpha);
else
#endif
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
// In the support painting gizmo and the seam painting gizmo are painted triangles rendered over the already
// rendered object. To resolved z-fighting between previously rendered object and painted triangles, values
// inside the depth buffer are offset by small epsilon for painted triangles inside those gizmos.
gl_FragDepth = gl_FragCoord.z - (offset_depth_buffer ? EPSILON : 0.0);
}

View File

@ -0,0 +1,77 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
struct SlopeDetection
{
bool actived;
float normal_z;
mat3 volume_world_normal_matrix;
};
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
uniform mat4 volume_world_matrix;
uniform SlopeDetection slope;
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
in vec3 v_position;
in vec3 v_normal;
// x = diffuse, y = specular;
out vec2 intensity;
out vec3 clipping_planes_dots;
out vec4 world_pos;
out float world_normal_z;
out vec3 eye_normal;
void main()
{
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 position = view_model_matrix * vec4(v_position, 1.0);
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Point in homogenous coordinates.
world_pos = volume_world_matrix * vec4(v_position, 1.0);
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
gl_Position = projection_matrix * position;
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
}

View File

@ -0,0 +1,12 @@
#version 140
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
in vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -0,0 +1,45 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
in vec3 v_position;
in vec3 v_normal;
// x = tainted, y = specular;
out vec2 intensity;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 position = view_model_matrix * vec4(v_position, 1.0);
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,12 @@
#version 140
uniform vec4 uniform_color;
uniform float emission_factor;
// x = tainted, y = specular;
in vec2 intensity;
void main()
{
gl_FragColor = vec4(vec3(intensity.y) + uniform_color.rgb * (intensity.x + emission_factor), uniform_color.a);
}

View File

@ -0,0 +1,50 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
// vertex attributes
in vec3 v_position;
in vec3 v_normal;
// instance attributes
in vec3 i_offset;
in vec2 i_scales;
// x = tainted, y = specular;
out vec2 intensity;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 world_position = vec4(v_position * vec3(vec2(1.5 * i_scales.x), 1.5 * i_scales.y) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0);
vec4 eye_position = view_model_matrix * world_position;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_Position = projection_matrix * eye_position;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform sampler2D Texture;
in vec2 Frag_UV;
in vec4 Frag_Color;
void main()
{
gl_FragColor = Frag_Color * texture(Texture, Frag_UV.st);
}

View File

@ -0,0 +1,17 @@
#version 140
uniform mat4 ProjMtx;
in vec2 Position;
in vec2 UV;
in vec4 Color;
out vec2 Frag_UV;
out vec4 Frag_Color;
void main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy, 0.0, 1.0);
}

View File

@ -0,0 +1,13 @@
#version 140
const float EPSILON = 0.0001;
uniform vec4 uniform_color;
void main()
{
gl_FragColor = uniform_color;
// Values inside depth buffer for fragments of the contour of a selected area are offset
// by small epsilon to solve z-fighting between painted triangles and contour lines.
gl_FragDepth = gl_FragCoord.z - EPSILON;
}

View File

@ -0,0 +1,11 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
void main()
{
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,63 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
const float EPSILON = 0.0001;
uniform vec4 uniform_color;
uniform bool volume_mirrored;
uniform mat4 view_model_matrix;
uniform mat3 normal_matrix;
in vec3 clipping_planes_dots;
in vec4 model_pos;
void main()
{
if (any(lessThan(clipping_planes_dots, ZERO)))
discard;
vec3 color = uniform_color.rgb;
float alpha = uniform_color.a;
vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
#ifdef FLIP_TRIANGLE_NORMALS
triangle_normal = -triangle_normal;
#endif
if (volume_mirrored)
triangle_normal = -triangle_normal;
// First transform the normal into camera space and normalize the result.
vec3 eye_normal = normalize(normal_matrix * triangle_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
// x = diffuse, y = specular;
vec2 intensity = vec2(0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (view_model_matrix * model_pos).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
}

View File

@ -0,0 +1,28 @@
#version 140
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat4 volume_world_matrix;
// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
uniform vec2 z_range;
// Clipping plane - general orientation. Used by the SLA gizmo.
uniform vec4 clipping_plane;
in vec3 v_position;
out vec3 clipping_planes_dots;
out vec4 model_pos;
void main()
{
model_pos = vec4(v_position, 1.0);
// Point in homogenous coordinates.
vec4 world_pos = volume_world_matrix * model_pos;
gl_Position = projection_matrix * view_model_matrix * model_pos;
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
}

View File

@ -0,0 +1,35 @@
#version 140
const vec3 back_color_dark = vec3(0.235, 0.235, 0.235);
const vec3 back_color_light = vec3(0.365, 0.365, 0.365);
uniform sampler2D in_texture;
uniform bool transparent_background;
uniform bool svg_source;
in vec2 tex_coord;
out vec4 frag_color;
vec4 svg_color()
{
// takes foreground from texture
vec4 fore_color = texture(in_texture, tex_coord);
// calculates radial gradient
vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5)))));
// blends foreground with background
return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
}
vec4 non_svg_color()
{
// takes foreground from texture
vec4 color = texture(in_texture, tex_coord);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}
void main()
{
frag_color = svg_source ? svg_color() : non_svg_color();
}

View File

@ -0,0 +1,15 @@
#version 140
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
in vec3 v_position;
in vec2 v_tex_coord;
out vec2 tex_coord;
void main()
{
tex_coord = v_tex_coord;
gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
}

View File

@ -0,0 +1,19 @@
#version 140
const vec4 BLACK = vec4(vec3(0.1), 1.0);
const vec4 WHITE = vec4(vec3(1.0), 1.0);
const float emission_factor = 0.25;
uniform vec3 world_center;
// x = tainted, y = specular;
in vec2 intensity;
in vec3 world_position;
void main()
{
vec3 delta = world_position - world_center;
vec4 color = delta.x * delta.y * delta.z > 0.0 ? BLACK : WHITE;
gl_FragColor = vec4(vec3(intensity.y) + color.rgb * (intensity.x + emission_factor), 1.0);
}

View File

@ -0,0 +1,47 @@
#version 140
#define INTENSITY_CORRECTION 0.6
// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
in vec3 v_position;
in vec3 v_normal;
// x = tainted, y = specular;
out vec2 intensity;
out vec3 world_position;
void main()
{
// First transform the normal into camera space and normalize the result.
vec3 normal = normalize(normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 position = view_model_matrix * vec4(v_position, 1.0);
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
world_position = v_position;
gl_Position = projection_matrix * position;
}

View File

@ -0,0 +1,41 @@
#version 140
#define M_PI 3.1415926535897932384626433832795
// 2D texture (1D texture split by the rows) of color along the object Z axis.
uniform sampler2D z_texture;
// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
uniform float z_to_texture_row;
uniform float z_texture_row_to_normalized;
uniform float z_cursor;
uniform float z_cursor_band_width;
// x = tainted, y = specular;
in vec2 intensity;
in float object_z;
void main()
{
float object_z_row = z_to_texture_row * object_z;
// Index of the row in the texture.
float z_texture_row = floor(object_z_row);
// Normalized coordinate from 0. to 1.
float z_texture_col = object_z_row - z_texture_row;
float z_blend = 0.25 * cos(min(M_PI, abs(M_PI * (object_z - z_cursor) * 1.8 / z_cursor_band_width))) + 0.25;
// Calculate level of detail from the object Z coordinate.
// This makes the slowly sloping surfaces to be shown with high detail (with stripes),
// and the vertical surfaces to be shown with low detail (no stripes)
float z_in_cells = object_z_row * 190.;
// Gradient of Z projected on the screen.
float dx_vtc = dFdx(z_in_cells);
float dy_vtc = dFdy(z_in_cells);
float lod = clamp(0.5 * log2(max(dx_vtc * dx_vtc, dy_vtc * dy_vtc)), 0., 1.);
// Sample the Z texture. Texture coordinates are normalized to <0, 1>.
vec4 color = vec4(0.25, 0.25, 0.25, 1.0);
if (z_texture_row >= 0.0)
color = mix(texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
texture(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
// Mix the final color.
gl_FragColor = vec4(vec3(intensity.y), 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
}

View File

@ -0,0 +1,60 @@
#version 140
#define INTENSITY_CORRECTION 0.6
const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
#define LIGHT_TOP_SHININESS 20.0
const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
//#define LIGHT_FRONT_SHININESS 5.0
#define INTENSITY_AMBIENT 0.3
uniform mat4 view_model_matrix;
uniform mat4 projection_matrix;
uniform mat3 normal_matrix;
uniform mat4 volume_world_matrix;
uniform float object_max_z;
in vec3 v_position;
in vec3 v_normal;
in vec2 v_tex_coord;
// x = tainted, y = specular;
out vec2 intensity;
out float object_z;
void main()
{
// =====================================================
// NOTE:
// when object_max_z > 0.0 we are rendering the overlay
// when object_max_z == 0.0 we are rendering the volumes
// =====================================================
// First transform the normal into camera space and normalize the result.
vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(normal_matrix * v_normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec4 position = view_model_matrix * vec4(v_position, 1.0);
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular)
NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
// Scaled to widths of the Z texture.
object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z;
gl_Position = projection_matrix * position;
}

View File

@ -11,6 +11,7 @@
#include "FillBase.hpp"
#include "FillRectilinear.hpp"
#include "FillLightning.hpp"
namespace Slic3r {
@ -318,7 +319,7 @@ void export_group_fills_to_svg(const char *path, const std::vector<SurfaceFill>
#endif
// friend to Layer
void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree)
void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator)
{
for (LayerRegion *layerm : m_regions)
layerm->fills.clear();
@ -348,6 +349,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
f->angle = surface_fill.params.angle;
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
if (surface_fill.params.pattern == ipLightning)
dynamic_cast<FillLightning::Filler*>(f.get())->generator = lightning_generator;
// calculate flow spacing for infill pattern generation
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge;
double link_max_length = 0.;

View File

@ -46,9 +46,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
case ipAdaptiveCubic: return new FillAdaptive::Filler();
case ipSupportCubic: return new FillAdaptive::Filler();
case ipSupportBase: return new FillSupportBase();
#if HAS_LIGHTNING_INFILL
case ipLightning: return new FillLightning::Filler();
#endif // HAS_LIGHTNING_INFILL
default: throw Slic3r::InvalidArgument("unknown type");
}
}

View File

@ -406,13 +406,15 @@ public:
// for the infill pattern, don't cut the corners.
// default miterLimt = 3
//double miterLimit = 10.;
assert(aoffset1 < 0);
// FIXME: Resolve properly the cases when it is constructed with aoffset1 = 0 and aoffset2 = 0,
// that is used in sample_grid_pattern() for Lightning infill.
// assert(aoffset1 < 0);
assert(aoffset2 <= 0);
assert(aoffset2 == 0 || aoffset2 < aoffset1);
// assert(aoffset2 == 0 || aoffset2 < aoffset1);
// bool sticks_removed =
remove_sticks(polygons_src);
// if (sticks_removed) BOOST_LOG_TRIVIAL(error) << "Sticks removed!";
polygons_outer = offset(polygons_src, float(aoffset1), ClipperLib::jtMiter, miterLimit);
polygons_outer = aoffset1 == 0 ? polygons_src : offset(polygons_src, float(aoffset1), ClipperLib::jtMiter, miterLimit);
if (aoffset2 < 0)
polygons_inner = shrink(polygons_outer, float(aoffset1 - aoffset2), ClipperLib::jtMiter, miterLimit);
// Filter out contours with zero area or small area, contours with 2 points only.

View File

@ -10,13 +10,14 @@ namespace Slic3r::FillLightning
constexpr coord_t radius_per_cell_size = 6; // The cell-size should be small compared to the radius, but not so small as to be inefficient.
DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang) :
DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outline, const BoundingBox& current_outlines_bbox, const Polygons& current_overhang) :
m_cell_size(radius / radius_per_cell_size),
m_supporting_radius(radius)
m_supporting_radius(radius),
m_unsupported_points_bbox(current_outlines_bbox)
{
m_supporting_radius2 = double(radius) * double(radius);
m_supporting_radius2 = Slic3r::sqr(int64_t(radius));
// Sample source polygons with a regular grid sampling pattern.
for (const ExPolygon &expoly : union_ex(current_outline)) {
for (const ExPolygon &expoly : union_ex(current_overhang)) {
for (const Point &p : sample_grid_pattern(expoly, m_cell_size)) {
// Find a squared distance to the source expolygon boundary.
double d2 = std::numeric_limits<double>::max();
@ -31,6 +32,7 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
}
}
m_unsupported_points.emplace_back(p, sqrt(d2));
assert(m_unsupported_points_bbox.contains(p));
}
}
m_unsupported_points.sort([&radius](const UnsupportedCell &a, const UnsupportedCell &b) {
@ -41,8 +43,11 @@ DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outl
});
for (auto it = m_unsupported_points.begin(); it != m_unsupported_points.end(); ++it) {
UnsupportedCell& cell = *it;
m_unsupported_points_grid.emplace(Point{ cell.loc.x() / m_cell_size, cell.loc.y() / m_cell_size }, it);
m_unsupported_points_grid.emplace(this->to_grid_point(cell.loc), it);
}
// Because the distance between two points is at least one axis equal to m_cell_size, every cell
// in m_unsupported_points_grid contains exactly one point.
assert(m_unsupported_points.size() == m_unsupported_points_grid.size());
}
void DistanceField::update(const Point& to_node, const Point& added_leaf)
@ -60,17 +65,24 @@ void DistanceField::update(const Point& to_node, const Point& added_leaf)
grid.merge(to_node + iextent);
grid.merge(added_leaf - iextent);
grid.merge(added_leaf + iextent);
grid.min /= m_cell_size;
grid.max /= m_cell_size;
// Clip grid by m_unsupported_points_bbox. Mainly to ensure that grid.min is a non-negative value.
grid.min.x() = std::max(grid.min.x(), m_unsupported_points_bbox.min.x());
grid.min.y() = std::max(grid.min.y(), m_unsupported_points_bbox.min.y());
grid.max.x() = std::min(grid.max.x(), m_unsupported_points_bbox.max.x());
grid.max.y() = std::min(grid.max.y(), m_unsupported_points_bbox.max.y());
grid.min = this->to_grid_point(grid.min);
grid.max = this->to_grid_point(grid.max);
}
Point grid_addr;
Point grid_loc;
for (coord_t row = grid.min.y(); row <= grid.max.y(); ++ row) {
grid_loc.y() = row * m_cell_size;
for (coord_t col = grid.min.x(); col <= grid.max.y(); ++ col) {
grid_loc.x() = col * m_cell_size;
for (grid_addr.y() = grid.min.y(); grid_addr.y() <= grid.max.y(); ++grid_addr.y()) {
for (grid_addr.x() = grid.min.x(); grid_addr.x() <= grid.max.x(); ++grid_addr.x()) {
grid_loc = this->from_grid_point(grid_addr);
// Test inside a circle at the new leaf.
if ((grid_loc - added_leaf).cast<double>().squaredNorm() > m_supporting_radius2) {
if ((grid_loc - added_leaf).cast<int64_t>().squaredNorm() > m_supporting_radius2) {
// Not inside a circle at the end of the new leaf.
// Test inside a rotated rectangle.
Vec2d vx = (grid_loc - to_node).cast<double>();
@ -84,10 +96,10 @@ void DistanceField::update(const Point& to_node, const Point& added_leaf)
}
// Inside a circle at the end of the new leaf, or inside a rotated rectangle.
// Remove unsupported leafs at this grid location.
if (auto it = m_unsupported_points_grid.find(grid_loc); it != m_unsupported_points_grid.end()) {
if (auto it = m_unsupported_points_grid.find(grid_addr); it != m_unsupported_points_grid.end()) {
std::list<UnsupportedCell>::iterator& list_it = it->second;
UnsupportedCell& cell = *list_it;
if ((cell.loc - added_leaf).cast<double>().squaredNorm() <= m_supporting_radius2) {
if ((cell.loc - added_leaf).cast<int64_t>().squaredNorm() <= m_supporting_radius2) {
m_unsupported_points.erase(list_it);
m_unsupported_points_grid.erase(it);
}
@ -96,4 +108,25 @@ void DistanceField::update(const Point& to_node, const Point& added_leaf)
}
}
#if 0
void DistanceField::update(const Point &to_node, const Point &added_leaf)
{
const Point supporting_radius_point(m_supporting_radius, m_supporting_radius);
const BoundingBox grid(this->to_grid_point(added_leaf - supporting_radius_point), this->to_grid_point(added_leaf + supporting_radius_point));
for (coord_t grid_y = grid.min.y(); grid_y <= grid.max.y(); ++grid_y) {
for (coord_t grid_x = grid.min.x(); grid_x <= grid.max.x(); ++grid_x) {
if (auto it = m_unsupported_points_grid.find({grid_x, grid_y}); it != m_unsupported_points_grid.end()) {
std::list<UnsupportedCell>::iterator &list_it = it->second;
UnsupportedCell &cell = *list_it;
if ((cell.loc - added_leaf).cast<int64_t>().squaredNorm() <= m_supporting_radius2) {
m_unsupported_points.erase(list_it);
m_unsupported_points_grid.erase(it);
}
}
}
}
}
#endif
} // namespace Slic3r::FillLightning

View File

@ -4,6 +4,7 @@
#ifndef LIGHTNING_DISTANCE_FIELD_H
#define LIGHTNING_DISTANCE_FIELD_H
#include "../../BoundingBox.hpp"
#include "../../Point.hpp"
#include "../../Polygon.hpp"
@ -29,7 +30,7 @@ public:
* \param current_overhang The overhang that needs to be supported on this
* layer.
*/
DistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang);
DistanceField(const coord_t& radius, const Polygons& current_outline, const BoundingBox& current_outlines_bbox, const Polygons& current_overhang);
/*!
* Gets the next unsupported location to be supported by a new branch.
@ -69,14 +70,14 @@ protected:
* branch of a tree.
*/
coord_t m_supporting_radius;
double m_supporting_radius2;
int64_t m_supporting_radius2;
/*!
* Represents a small discrete area of infill that needs to be supported.
*/
struct UnsupportedCell
{
UnsupportedCell(Point loc, coord_t dist_to_boundary) : loc(loc), dist_to_boundary(dist_to_boundary) {}
UnsupportedCell(const Point &loc, coord_t dist_to_boundary) : loc(loc), dist_to_boundary(dist_to_boundary) {}
// The position of the center of this cell.
Point loc;
// How far this cell is removed from the ``current_outline`` polygon, the edge of the infill area.
@ -88,11 +89,30 @@ protected:
*/
std::list<UnsupportedCell> m_unsupported_points;
/*!
* BoundingBox of all points in m_unsupported_points. Used for mapping of sign integer numbers to positive integer numbers.
*/
const BoundingBox m_unsupported_points_bbox;
/*!
* Links the unsupported points to a grid point, so that we can quickly look
* up the cell belonging to a certain position in the grid.
*/
std::unordered_map<Point, std::list<UnsupportedCell>::iterator, PointHash> m_unsupported_points_grid;
/*!
* Maps the point to the grid coordinates.
*/
Point to_grid_point(const Point &point) const {
return (point - m_unsupported_points_bbox.min) / m_cell_size;
}
/*!
* Maps the point to the grid coordinates.
*/
Point from_grid_point(const Point &point) const {
return point * m_cell_size + m_unsupported_points_bbox.min;
}
};
} // namespace Slic3r::FillLightning

View File

@ -35,17 +35,17 @@ Generator::Generator(const PrintObject &print_object)
// const int infill_extruder = region_config.infill_extruder.value;
const double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter));
// Note: There's not going to be a layer below the first one, so the 'initial layer height' doesn't have to be taken into account.
const double layer_thickness = object_config.layer_height;
const double layer_thickness = scaled<double>(object_config.layer_height.value);
m_infill_extrusion_width = scaled<float>(region_config.infill_extrusion_width.percent ? default_infill_extrusion_width * 0.01 * region_config.infill_extrusion_width : region_config.infill_extrusion_width);
m_supporting_radius = scaled<coord_t>(m_infill_extrusion_width * 0.001 / region_config.fill_density);
m_supporting_radius = coord_t(m_infill_extrusion_width) * 100 / coord_t(region_config.fill_density.value);
const double lightning_infill_overhang_angle = M_PI / 4; // 45 degrees
const double lightning_infill_prune_angle = M_PI / 4; // 45 degrees
const double lightning_infill_straightening_angle = M_PI / 4; // 45 degrees
m_wall_supporting_radius = layer_thickness * std::tan(lightning_infill_overhang_angle);
m_prune_length = layer_thickness * std::tan(lightning_infill_prune_angle);
m_straightening_max_distance = layer_thickness * std::tan(lightning_infill_straightening_angle);
m_wall_supporting_radius = coord_t(layer_thickness * std::tan(lightning_infill_overhang_angle));
m_prune_length = coord_t(layer_thickness * std::tan(lightning_infill_prune_angle));
m_straightening_max_distance = coord_t(layer_thickness * std::tan(lightning_infill_straightening_angle));
generateInitialInternalOverhangs(print_object);
generateTrees(print_object);
@ -54,19 +54,20 @@ Generator::Generator(const PrintObject &print_object)
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object)
{
m_overhang_per_layer.resize(print_object.layers().size());
const float infill_wall_offset = - m_infill_extrusion_width;
// FIXME: It can be adjusted to improve bonding between infill and perimeters.
const float infill_wall_offset = 0;// m_infill_extrusion_width;
Polygons infill_area_above;
//Iterate from top to bottom, to subtract the overhang areas above from the overhang areas on the layer below, to get only overhang in the top layer where it is overhanging.
for (int layer_nr = print_object.layers().size() - 1; layer_nr >= 0; layer_nr--) {
for (int layer_nr = int(print_object.layers().size()) - 1; layer_nr >= 0; layer_nr--) {
Polygons infill_area_here;
for (const LayerRegion* layerm : print_object.get_layer(layer_nr)->regions())
for (const Surface& surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal)
append(infill_area_here, offset(surface.expolygon, infill_wall_offset));
append(infill_area_here, infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset));
//Remove the part of the infill area that is already supported by the walls.
Polygons overhang = diff(offset(infill_area_here, -m_wall_supporting_radius), infill_area_above);
Polygons overhang = diff(offset(infill_area_here, -float(m_wall_supporting_radius)), infill_area_above);
m_overhang_per_layer[layer_nr] = overhang;
infill_area_above = std::move(infill_area_here);
@ -82,16 +83,17 @@ const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
void Generator::generateTrees(const PrintObject &print_object)
{
m_lightning_layers.resize(print_object.layers().size());
const coord_t infill_wall_offset = - m_infill_extrusion_width;
// FIXME: It can be adjusted to improve bonding between infill and perimeters.
const coord_t infill_wall_offset = 0;// m_infill_extrusion_width;
std::vector<Polygons> infill_outlines(print_object.layers().size(), Polygons());
// For-each layer from top to bottom:
for (int layer_id = print_object.layers().size() - 1; layer_id >= 0; layer_id--)
for (int layer_id = int(print_object.layers().size()) - 1; layer_id >= 0; layer_id--)
for (const LayerRegion *layerm : print_object.get_layer(layer_id)->regions())
for (const Surface &surface : layerm->fill_surfaces.surfaces)
if (surface.surface_type == stInternal)
append(infill_outlines[layer_id], offset(surface.expolygon, infill_wall_offset));
append(infill_outlines[layer_id], infill_wall_offset == 0 ? surface.expolygon : offset(surface.expolygon, infill_wall_offset));
// For various operations its beneficial to quickly locate nearby features on the polygon:
const size_t top_layer_id = print_object.layers().size() - 1;
@ -99,16 +101,16 @@ void Generator::generateTrees(const PrintObject &print_object)
outlines_locator.create(infill_outlines[top_layer_id], locator_cell_size);
// For-each layer from top to bottom:
for (int layer_id = top_layer_id; layer_id >= 0; layer_id--)
{
for (int layer_id = int(top_layer_id); layer_id >= 0; layer_id--) {
Layer &current_lightning_layer = m_lightning_layers[layer_id];
Polygons& current_outlines = infill_outlines[layer_id];
const Polygons &current_outlines = infill_outlines[layer_id];
const BoundingBox &current_outlines_bbox = get_extents(current_outlines);
// register all trees propagated from the previous layer as to-be-reconnected
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, current_outlines_bbox, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
// Initialize trees for next lower layer from the current one.
if (layer_id == 0)

View File

@ -45,7 +45,7 @@ public:
* already be calculated at this point.
* \param mesh The mesh to generate infill for.
*/
Generator(const PrintObject &print_object);
explicit Generator(const PrintObject &print_object);
/*!
* Get a tree of paths generated for a certain layer of the mesh.

View File

@ -3,12 +3,11 @@
#include "Layer.hpp" //The class we're implementing.
#include <iterator> // advance
#include "DistanceField.hpp"
#include "TreeNode.hpp"
#include "../../Geometry.hpp"
#include "Utils.hpp"
namespace Slic3r::FillLightning {
@ -23,10 +22,15 @@ Point GroundingLocation::p() const
return tree_node ? tree_node->getLocation() : *boundary_location;
}
void Layer::fillLocator(SparseNodeGrid &tree_node_locator)
inline static Point to_grid_point(const Point &point, const BoundingBox &bbox)
{
std::function<void(NodeSPtr)> add_node_to_locator_func = [&tree_node_locator](NodeSPtr node) {
tree_node_locator.insert(std::make_pair(Point(node->getLocation().x() / locator_cell_size, node->getLocation().y() / locator_cell_size), node));
return (point - bbox.min) / locator_cell_size;
}
void Layer::fillLocator(SparseNodeGrid &tree_node_locator, const BoundingBox& current_outlines_bbox)
{
std::function<void(NodeSPtr)> add_node_to_locator_func = [&tree_node_locator, &current_outlines_bbox](const NodeSPtr &node) {
tree_node_locator.insert(std::make_pair(to_grid_point(node->getLocation(), current_outlines_bbox), node));
};
for (auto& tree : tree_roots)
tree->visitNodes(add_node_to_locator_func);
@ -36,38 +40,46 @@ void Layer::generateNewTrees
(
const Polygons& current_overhang,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outlines_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius
)
{
DistanceField distance_field(supporting_radius, current_outlines, current_overhang);
DistanceField distance_field(supporting_radius, current_outlines, current_outlines_bbox, current_overhang);
SparseNodeGrid tree_node_locator;
fillLocator(tree_node_locator);
fillLocator(tree_node_locator, current_outlines_bbox);
// Until no more points need to be added to support all:
// Determine next point from tree/outline areas via distance-field
Point unsupported_location;
while (distance_field.tryGetNextPoint(&unsupported_location)) {
GroundingLocation grounding_loc = getBestGroundingLocation(
unsupported_location, current_outlines, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator);
unsupported_location, current_outlines, current_outlines_bbox, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator);
NodeSPtr new_parent;
NodeSPtr new_child;
this->attach(unsupported_location, grounding_loc, new_child, new_parent);
tree_node_locator.insert(std::make_pair(Point(new_child->getLocation().x() / locator_cell_size, new_child->getLocation().y() / locator_cell_size), new_child));
tree_node_locator.insert(std::make_pair(to_grid_point(new_child->getLocation(), current_outlines_bbox), new_child));
if (new_parent)
tree_node_locator.insert(std::make_pair(Point(new_parent->getLocation().x() / locator_cell_size, new_parent->getLocation().y() / locator_cell_size), new_parent));
tree_node_locator.insert(std::make_pair(to_grid_point(new_parent->getLocation(), current_outlines_bbox), new_parent));
// update distance field
distance_field.update(grounding_loc.p(), unsupported_location);
}
#ifdef LIGHTNING_TREE_NODE_DEBUG_OUTPUT
{
static int iRun = 0;
export_to_svg(debug_out_path("FillLightning-TreeNodes-%d.svg", iRun++), current_outlines, this->tree_roots);
}
#endif /* LIGHTNING_TREE_NODE_DEBUG_OUTPUT */
}
static bool polygonCollidesWithLineSegment(const Point from, const Point to, const EdgeGrid::Grid &loc_to_line)
static bool polygonCollidesWithLineSegment(const Point &from, const Point &to, const EdgeGrid::Grid &loc_to_line)
{
struct Visitor {
explicit Visitor(const EdgeGrid::Grid &grid) : grid(grid) {}
explicit Visitor(const EdgeGrid::Grid &grid, const Line &line) : grid(grid), line(line) {}
bool operator()(coord_t iy, coord_t ix) {
// Called with a row and colum of the grid cell, which is intersected by a line.
@ -87,7 +99,7 @@ static bool polygonCollidesWithLineSegment(const Point from, const Point to, con
const EdgeGrid::Grid& grid;
Line line;
bool intersect = false;
} visitor(loc_to_line);
} visitor(loc_to_line, {from, to});
loc_to_line.visit_cells_intersecting_line(from, to, visitor);
return visitor.intersect;
@ -97,6 +109,7 @@ GroundingLocation Layer::getBestGroundingLocation
(
const Point& unsupported_location,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius,
@ -128,8 +141,8 @@ GroundingLocation Layer::getBestGroundingLocation
if (current_dist >= wall_supporting_radius) { // Only reconnect tree roots to other trees if they are not already close to the outlines.
const coord_t search_radius = std::min(current_dist, within_dist);
BoundingBox region(unsupported_location - Point(search_radius, search_radius), unsupported_location + Point(search_radius + locator_cell_size, search_radius + locator_cell_size));
region.min /= locator_cell_size;
region.max /= locator_cell_size;
region.min = to_grid_point(region.min, current_outlines_bbox);
region.max = to_grid_point(region.max, current_outlines_bbox);
Point grid_addr;
for (grid_addr.y() = region.min.y(); grid_addr.y() < region.max.y(); ++ grid_addr.y())
for (grid_addr.x() = region.min.x(); grid_addr.x() < region.max.x(); ++ grid_addr.x()) {
@ -176,6 +189,7 @@ void Layer::reconnectRoots
(
std::vector<NodeSPtr>& to_be_reconnected_tree_roots,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius
@ -184,10 +198,10 @@ void Layer::reconnectRoots
constexpr coord_t tree_connecting_ignore_offset = 100;
SparseNodeGrid tree_node_locator;
fillLocator(tree_node_locator);
fillLocator(tree_node_locator, current_outlines_bbox);
const coord_t within_max_dist = outline_locator.resolution() * 2;
for (auto root_ptr : to_be_reconnected_tree_roots)
for (const auto &root_ptr : to_be_reconnected_tree_roots)
{
auto old_root_it = std::find(tree_roots.begin(), tree_roots.end(), root_ptr);
@ -203,7 +217,7 @@ void Layer::reconnectRoots
root_ptr->addChild(new_root);
new_root->reroot();
tree_node_locator.insert(std::make_pair(Point(new_root->getLocation().x() / locator_cell_size, new_root->getLocation().y() / locator_cell_size), new_root));
tree_node_locator.insert(std::make_pair(to_grid_point(new_root->getLocation(), current_outlines_bbox), new_root));
*old_root_it = std::move(new_root); // replace old root with new root
continue;
@ -217,6 +231,7 @@ void Layer::reconnectRoots
(
root_ptr->getLocation(),
current_outlines,
current_outlines_bbox,
outline_locator,
supporting_radius,
tree_connecting_ignore_width,
@ -233,7 +248,7 @@ void Layer::reconnectRoots
attach_ptr->reroot();
new_root->addChild(attach_ptr);
tree_node_locator.insert(std::make_pair(new_root->getLocation(), new_root));
tree_node_locator.insert(std::make_pair(to_grid_point(new_root->getLocation(), current_outlines_bbox), new_root));
*old_root_it = std::move(new_root); // replace old root with new root
}
@ -256,14 +271,24 @@ void Layer::reconnectRoots
}
}
/*
/*!
* Moves the point \p from onto the nearest polygon or leaves the point as-is, when the comb boundary is not within the root of \p max_dist2 distance.
* Given a \p distance more than zero, the point will end up inside, and conversely outside.
* When the point is already in/outside by more than \p distance, \p from is unaltered, but the polygon is returned.
* When the point is in/outside by less than \p distance, \p from is moved to the correct place.
* Implementation assumes moving inside, but moving outside should just as well be possible.
*
* \param polygons The polygons onto which to move the point
* \param from[in,out] The point to move.
* \param distance The distance by which to move the point.
* \param max_dist2 The squared maximal allowed distance from the point to the nearest polygon.
* \return The index to the polygon onto which we have moved the point.
*/
static unsigned int moveInside(const Polygons& polygons, Point& from, int distance, int64_t maxDist2)
{
Point ret = from;
int64_t bestDist2 = std::numeric_limits<int64_t>::max();
unsigned int bestPoly = static_cast<unsigned int>(-1);
auto bestPoly = static_cast<unsigned int>(-1);
bool is_already_on_correct_side_of_boundary = false; // whether [from] is already on the right side of the boundary
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
@ -333,7 +358,7 @@ static unsigned int moveInside(const Polygons& polygons, Point& from, int distan
else
{ // x is projected to a point properly on the line segment (not onto a vertex). The case which looks like | .
projected_p_beyond_prev_segment = false;
Point x = a + ab * dot_prod / ab_length2;
Point x = (a.cast<int64_t>() + ab.cast<int64_t>() * dot_prod / ab_length2).cast<coord_t>();
int64_t dist2 = (p - x).cast<int64_t>().squaredNorm();
if (dist2 < bestDist2)

View File

@ -41,9 +41,10 @@ public:
(
const Polygons& current_overhang,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius
coord_t supporting_radius,
coord_t wall_supporting_radius
);
/*! Determine & connect to connection point in tree/outline.
@ -53,9 +54,10 @@ public:
(
const Point& unsupported_location,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius,
coord_t supporting_radius,
coord_t wall_supporting_radius,
const SparseNodeGrid& tree_node_locator,
const NodeSPtr& exclude_tree = nullptr
);
@ -71,16 +73,17 @@ public:
(
std::vector<NodeSPtr>& to_be_reconnected_tree_roots,
const Polygons& current_outlines,
const BoundingBox& current_outlines_bbox,
const EdgeGrid::Grid& outline_locator,
const coord_t supporting_radius,
const coord_t wall_supporting_radius
coord_t supporting_radius,
coord_t wall_supporting_radius
);
Polylines convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const;
Polylines convertToLines(const Polygons& limit_to_outline, coord_t line_width) const;
coord_t getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location);
void fillLocator(SparseNodeGrid& tree_node_locator);
void fillLocator(SparseNodeGrid& tree_node_locator, const BoundingBox& current_outlines_bbox);
};
} // namespace Slic3r::FillLightning

View File

@ -4,7 +4,6 @@
#include "TreeNode.hpp"
#include "../../Geometry.hpp"
#include "../../ClipperUtils.hpp"
namespace Slic3r::FillLightning {
@ -107,7 +106,7 @@ NodeSPtr Node::deepCopy() const
return local_root;
}
void Node::reroot(NodeSPtr new_parent /*= nullptr*/)
void Node::reroot(const NodeSPtr &new_parent)
{
if (! m_is_root) {
auto old_parent = m_parent.lock();
@ -142,7 +141,7 @@ NodeSPtr Node::closestNode(const Point& loc)
return result;
}
bool inside(const Polygons &polygons, const Point p)
bool inside(const Polygons &polygons, const Point &p)
{
int poly_count_inside = 0;
for (const Polygon &poly : polygons) {
@ -181,7 +180,7 @@ bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const EdgeG
} visitor { outline_locator, a.cast<double>(), b.cast<double>() };
outline_locator.visit_cells_intersecting_line(a, b, visitor);
return visitor.d2min < within_max_dist * within_max_dist;
return visitor.d2min < double(within_max_dist) * double(within_max_dist);
}
bool Node::realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locator, std::vector<NodeSPtr>& rerooted_parts)
@ -226,14 +225,14 @@ bool Node::realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locat
void Node::straighten(const coord_t magnitude, const coord_t max_remove_colinear_dist)
{
straighten(magnitude, m_p, 0, max_remove_colinear_dist * max_remove_colinear_dist);
straighten(magnitude, m_p, 0, int64_t(max_remove_colinear_dist) * int64_t(max_remove_colinear_dist));
}
Node::RectilinearJunction Node::straighten(
const coord_t magnitude,
const Point& junction_above,
const coord_t accumulated_dist,
const coord_t max_remove_colinear_dist2)
const int64_t max_remove_colinear_dist2)
{
constexpr coord_t junction_magnitude_factor_numerator = 3;
constexpr coord_t junction_magnitude_factor_denominator = 4;
@ -245,13 +244,13 @@ Node::RectilinearJunction Node::straighten(
auto child_dist = coord_t((m_p - child_p->m_p).cast<double>().norm());
RectilinearJunction junction_below = child_p->straighten(magnitude, junction_above, accumulated_dist + child_dist, max_remove_colinear_dist2);
coord_t total_dist_to_junction_below = junction_below.total_recti_dist;
Point a = junction_above;
const Point& a = junction_above;
Point b = junction_below.junction_loc;
if (a != b) // should always be true!
{
Point ab = b - a;
Point destination = a + ab * accumulated_dist / std::max(coord_t(1), total_dist_to_junction_below);
if ((destination - m_p).cast<double>().squaredNorm() <= magnitude * magnitude)
Point destination = (a.cast<int64_t>() + ab.cast<int64_t>() * int64_t(accumulated_dist) / std::max(int64_t(1), int64_t(total_dist_to_junction_below))).cast<coord_t>();
if ((destination - m_p).cast<int64_t>().squaredNorm() <= int64_t(magnitude) * int64_t(magnitude))
m_p = destination;
else
m_p += ((destination - m_p).cast<double>().normalized() * magnitude).cast<coord_t>();
@ -262,7 +261,7 @@ Node::RectilinearJunction Node::straighten(
child_p = m_children.front(); //recursive call to straighten might have removed the child
const NodeSPtr& parent_node = m_parent.lock();
if (parent_node &&
(child_p->m_p - parent_node->m_p).cast<double>().squaredNorm() < max_remove_colinear_dist2 &&
(child_p->m_p - parent_node->m_p).cast<int64_t>().squaredNorm() < max_remove_colinear_dist2 &&
Line::distance_to_squared(m_p, parent_node->m_p, child_p->m_p) < close_enough * close_enough) {
child_p->m_parent = m_parent;
for (auto& sibling : parent_node->m_children)
@ -347,7 +346,7 @@ coord_t Node::prune(const coord_t& pruning_distance)
void Node::convertToPolylines(Polygons& output, const coord_t line_width) const
{
Polygons result;
output.emplace_back();
result.emplace_back();
convertToPolylines(0, result);
removeJunctionOverlap(result, line_width);
append(output, std::move(result));
@ -386,7 +385,7 @@ void Node::removeJunctionOverlap(Polygons& result_lines, const coord_t line_widt
coord_t to_be_reduced = reduction;
Point a = polyline.back();
for (int point_idx = polyline.size() - 2; point_idx >= 0; point_idx--) {
for (int point_idx = int(polyline.size()) - 2; point_idx >= 0; point_idx--) {
const Point b = polyline[point_idx];
const Point ab = b - a;
const auto ab_len = coord_t(ab.cast<double>().norm());
@ -408,4 +407,29 @@ void Node::removeJunctionOverlap(Polygons& result_lines, const coord_t line_widt
}
}
#ifdef LIGHTNING_TREE_NODE_DEBUG_OUTPUT
void export_to_svg(const NodeSPtr &root_node, SVG &svg)
{
for (const NodeSPtr &children : root_node->m_children) {
svg.draw(Line(root_node->getLocation(), children->getLocation()), "red");
export_to_svg(children, svg);
}
}
void export_to_svg(const std::string &path, const Polygons &contour, const std::vector<NodeSPtr> &root_nodes) {
BoundingBox bbox = get_extents(contour);
bbox.offset(SCALED_EPSILON);
SVG svg(path, bbox);
svg.draw_outline(contour, "blue");
for (const NodeSPtr &root_node: root_nodes) {
for (const NodeSPtr &children: root_node->m_children) {
svg.draw(Line(root_node->getLocation(), children->getLocation()), "red");
export_to_svg(children, svg);
}
}
}
#endif /* LIGHTNING_TREE_NODE_DEBUG_OUTPUT */
} // namespace Slic3r::FillLightning

View File

@ -11,6 +11,9 @@
#include "../../EdgeGrid.hpp"
#include "../../Polygon.hpp"
#include "SVG.hpp"
//#define LIGHTNING_TREE_NODE_DEBUG_OUTPUT
namespace Slic3r::FillLightning
{
@ -99,9 +102,9 @@ public:
std::vector<NodeSPtr>& next_trees,
const Polygons& next_outlines,
const EdgeGrid::Grid& outline_locator,
const coord_t prune_distance,
const coord_t smooth_magnitude,
const coord_t max_remove_colinear_dist
coord_t prune_distance,
coord_t smooth_magnitude,
coord_t max_remove_colinear_dist
) const;
/*!
@ -156,7 +159,7 @@ public:
* This is then recursively bubbled up until it reaches the (former) root, which then will become a leaf.
* \param new_parent The (new) parent-node of the root, useful for recursing or immediately attaching the node to another tree.
*/
void reroot(NodeSPtr new_parent = nullptr);
void reroot(const NodeSPtr &new_parent = nullptr);
/*!
* Retrieves the closest node to the specified location.
@ -211,7 +214,7 @@ protected:
* \param magnitude The maximum allowed distance to move the node.
* \param max_remove_colinear_dist Maximum distance of the (compound) line-segment from which a co-linear point may be removed.
*/
void straighten(const coord_t magnitude, const coord_t max_remove_colinear_dist);
void straighten(coord_t magnitude, coord_t max_remove_colinear_dist);
/*! Recursive part of \ref straighten(.)
* \param junction_above The last seen junction with multiple children above
@ -219,7 +222,7 @@ protected:
* \param max_remove_colinear_dist2 Maximum distance _squared_ of the (compound) line-segment from which a co-linear point may be removed.
* \return the total distance along the tree from the last junction above to the first next junction below and the location of the next junction below
*/
RectilinearJunction straighten(const coord_t magnitude, const Point& junction_above, const coord_t accumulated_dist, const coord_t max_remove_colinear_dist2);
RectilinearJunction straighten(coord_t magnitude, const Point& junction_above, coord_t accumulated_dist, int64_t max_remove_colinear_dist2);
/*! Prune the tree from the extremeties (leaf-nodes) until the pruning distance is reached.
* \return The distance that has been pruned. If less than \p distance, then the whole tree was puned away.
@ -236,7 +239,7 @@ public:
*
* \param output all branches in this tree connected into polylines
*/
void convertToPolylines(Polygons& output, const coord_t line_width) const;
void convertToPolylines(Polygons& output, coord_t line_width) const;
/*! If this was ever a direct child of the root, it'll have a previous grounding location.
*
@ -257,7 +260,7 @@ protected:
*/
void convertToPolylines(size_t long_line_idx, Polygons& output) const;
void removeJunctionOverlap(Polygons& polylines, const coord_t line_width) const;
void removeJunctionOverlap(Polygons& polylines, coord_t line_width) const;
bool m_is_root;
Point m_p;
@ -265,10 +268,20 @@ protected:
std::vector<NodeSPtr> m_children;
std::optional<Point> m_last_grounding_location; //<! The last known grounding location, see 'getLastGroundingLocation()'.
#ifdef LIGHTNING_TREE_NODE_DEBUG_OUTPUT
friend void export_to_svg(const NodeSPtr &root_node, Slic3r::SVG &svg);
friend void export_to_svg(const std::string &path, const Polygons &contour, const std::vector<NodeSPtr> &root_nodes);
#endif /* LIGHTNING_TREE_NODE_DEBUG_OUTPUT */
};
bool inside(const Polygons &polygons, const Point p);
bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const EdgeGrid::Grid& outline_locator, Point& result, const coord_t within_max_dist);
bool inside(const Polygons &polygons, const Point &p);
bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const EdgeGrid::Grid& outline_locator, Point& result, coord_t within_max_dist);
#ifdef LIGHTNING_TREE_NODE_DEBUG_OUTPUT
void export_to_svg(const NodeSPtr &root_node, SVG &svg);
void export_to_svg(const std::string &path, const Polygons &contour, const std::vector<NodeSPtr> &root_nodes);
#endif /* LIGHTNING_TREE_NODE_DEBUG_OUTPUT */
} // namespace Slic3r::FillLightning

View File

@ -36,6 +36,10 @@ static const float DEFAULT_FILAMENT_DIAMETER = 1.75f;
static const float DEFAULT_FILAMENT_DENSITY = 1.245f;
static const Slic3r::Vec3f DEFAULT_EXTRUDER_OFFSET = Slic3r::Vec3f::Zero();
#if ENABLE_PROCESS_G2_G3_LINES
static const std::string INTERNAL_G2G3_TAG = "!#!#! internal only - from G2/G3 expansion !#!#!";
#endif // ENABLE_PROCESS_G2_G3_LINES
namespace Slic3r {
const std::vector<std::string> GCodeProcessor::Reserved_Tags = {
@ -737,9 +741,7 @@ void GCodeProcessorResult::reset() {
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
#if ENABLE_SPIRAL_VASE_LAYERS
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
#endif // ENABLE_SPIRAL_VASE_LAYERS
time = 0;
}
#else
@ -755,9 +757,7 @@ void GCodeProcessorResult::reset() {
filament_diameters = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DIAMETER);
filament_densities = std::vector<float>(MIN_EXTRUDERS_COUNT, DEFAULT_FILAMENT_DENSITY);
custom_gcode_per_print_z = std::vector<CustomGCode::Item>();
#if ENABLE_SPIRAL_VASE_LAYERS
spiral_vase_layers = std::vector<std::pair<float, std::pair<size_t, size_t>>>();
#endif // ENABLE_SPIRAL_VASE_LAYERS
}
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -905,17 +905,13 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_result.max_print_height = config.max_print_height;
#if ENABLE_SPIRAL_VASE_LAYERS
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
if (spiral_vase != nullptr)
m_spiral_vase_active = spiral_vase->value;
#endif // ENABLE_SPIRAL_VASE_LAYERS
#if ENABLE_Z_OFFSET_CORRECTION
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
if (z_offset != nullptr)
m_z_offset = z_offset->value;
#endif // ENABLE_Z_OFFSET_CORRECTION
}
void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
@ -1160,17 +1156,13 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
if (max_print_height != nullptr)
m_result.max_print_height = max_print_height->value;
#if ENABLE_SPIRAL_VASE_LAYERS
const ConfigOptionBool* spiral_vase = config.option<ConfigOptionBool>("spiral_vase");
if (spiral_vase != nullptr)
m_spiral_vase_active = spiral_vase->value;
#endif // ENABLE_SPIRAL_VASE_LAYERS
#if ENABLE_Z_OFFSET_CORRECTION
const ConfigOptionFloat* z_offset = config.option<ConfigOptionFloat>("z_offset");
if (z_offset != nullptr)
m_z_offset = z_offset->value;
#endif // ENABLE_Z_OFFSET_CORRECTION
}
void GCodeProcessor::enable_stealth_time_estimator(bool enabled)
@ -1203,9 +1195,7 @@ void GCodeProcessor::reset()
m_forced_height = 0.0f;
m_mm3_per_mm = 0.0f;
m_fan_speed = 0.0f;
#if ENABLE_Z_OFFSET_CORRECTION
m_z_offset = 0.0f;
#endif // ENABLE_Z_OFFSET_CORRECTION
m_extrusion_role = erNone;
m_extruder_id = 0;
@ -1220,7 +1210,6 @@ void GCodeProcessor::reset()
m_extruded_last_z = 0.0f;
m_first_layer_height = 0.0f;
m_processing_start_custom_gcode = false;
m_g1_line_id = 0;
m_layer_id = 0;
m_cp_color.reset();
@ -1238,9 +1227,7 @@ void GCodeProcessor::reset()
m_options_z_corrector.reset();
#if ENABLE_SPIRAL_VASE_LAYERS
m_spiral_vase_active = false;
#endif // ENABLE_SPIRAL_VASE_LAYERS
#if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_mm3_per_mm_compare.reset();
@ -1596,6 +1583,10 @@ void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line, bool
switch (cmd[1]) {
case '0': { process_G0(line); break; } // Move
case '1': { process_G1(line); break; } // Move
#if ENABLE_PROCESS_G2_G3_LINES
case '2': { process_G2_G3(line, true); break; } // CW Arc Move
case '3': { process_G2_G3(line, false); break; } // CCW Arc Move
#endif // ENABLE_PROCESS_G2_G3_LINES
default: break;
}
break;
@ -1826,7 +1817,6 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
set_extrusion_role(ExtrusionEntity::string_to_role(comment.substr(reserved_tag(ETags::Role).length())));
if (m_extrusion_role == erExternalPerimeter)
m_seams_detector.activate(true);
m_processing_start_custom_gcode = (m_extrusion_role == erCustom && m_g1_line_id == 0);
return;
}
@ -1950,7 +1940,6 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
// layer change tag
if (comment == reserved_tag(ETags::Layer_Change)) {
++m_layer_id;
#if ENABLE_SPIRAL_VASE_LAYERS
if (m_spiral_vase_active) {
if (m_result.moves.empty())
m_result.spiral_vase_layers.push_back({ m_first_layer_height, { 0, 0 } });
@ -1962,7 +1951,6 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers
m_result.spiral_vase_layers.push_back({ static_cast<float>(m_end_position[Z]), { move_id, move_id } });
}
}
#endif // ENABLE_SPIRAL_VASE_LAYERS
return;
}
@ -2453,9 +2441,10 @@ void GCodeProcessor::process_G0(const GCodeReader::GCodeLine& line)
void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
{
float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back();
float filament_radius = 0.5f * filament_diameter;
float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
const float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back();
const float filament_radius = 0.5f * filament_diameter;
const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
#if !ENABLE_PROCESS_G2_G3_LINES
auto absolute_position = [this, area_filament_cross_section](Axis axis, const GCodeReader::GCodeLine& lineG1) {
bool is_relative = (m_global_positioning_type == EPositioningType::Relative);
if (axis == E)
@ -2471,6 +2460,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
else
return m_start_position[axis];
};
#endif // !ENABLE_PROCESS_G2_G3_LINES
auto move_type = [this](const AxisCoords& delta_pos) {
EMoveType type = EMoveType::Noop;
@ -2498,7 +2488,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// updates axes positions from line
for (unsigned char a = X; a <= E; ++a) {
#if ENABLE_PROCESS_G2_G3_LINES
m_end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section));
#else
m_end_position[a] = absolute_position((Axis)a, line);
#endif // ENABLE_PROCESS_G2_G3_LINES
}
// updates feedrate from line, if present
@ -2517,11 +2511,11 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (max_abs_delta == 0.0f)
return;
EMoveType type = move_type(delta_pos);
const EMoveType type = move_type(delta_pos);
if (type == EMoveType::Extrude) {
float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
const float delta_xyz = std::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
const float volume_extruded_filament = area_filament_cross_section * delta_pos[E];
const float area_toolpath_cross_section = volume_extruded_filament / delta_xyz;
// save extruded volume to the cache
m_used_filaments.increase_caches(volume_extruded_filament);
@ -2532,12 +2526,25 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
m_mm3_per_mm_compare.update(area_toolpath_cross_section, m_extrusion_role);
#endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
#if ENABLE_PROCESS_G2_G3_LINES
if (m_forced_height > 0.0f)
m_height = m_forced_height;
else if (m_layer_id == 0)
m_height = (m_end_position[Z] <= double(m_first_layer_height)) ? m_end_position[Z] : m_first_layer_height;
else if (line.comment() != INTERNAL_G2G3_TAG){
if (m_end_position[Z] > m_extruded_last_z + EPSILON && delta_pos[Z] == 0.0)
m_height = m_end_position[Z] - m_extruded_last_z;
}
#else
if (m_forced_height > 0.0f)
m_height = m_forced_height;
else if (m_layer_id == 0)
m_height = (m_end_position[Z] <= double(m_first_layer_height)) ? m_end_position[Z] : m_first_layer_height;
else {
if (m_end_position[Z] > m_extruded_last_z + EPSILON)
m_height = m_end_position[Z] - m_extruded_last_z;
}
#endif // ENABLE_PROCESS_G2_G3_LINES
if (m_height == 0.0f)
m_height = DEFAULT_TOOLPATH_HEIGHT;
@ -2545,6 +2552,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
if (m_end_position[Z] == 0.0f)
m_end_position[Z] = m_height;
#if ENABLE_PROCESS_G2_G3_LINES
if (line.comment() != INTERNAL_G2G3_TAG)
#endif // ENABLE_PROCESS_G2_G3_LINES
m_extruded_last_z = m_end_position[Z];
m_options_z_corrector.update(m_height);
@ -2585,9 +2595,9 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
return delta_pos[X] == 0.0f && delta_pos[Y] == 0.0f && delta_pos[Z] == 0.0f && delta_pos[E] != 0.0f;
};
float distance = move_length(delta_pos);
const float distance = move_length(delta_pos);
assert(distance != 0.0f);
float inv_distance = 1.0f / distance;
const float inv_distance = 1.0f / distance;
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
TimeMachine& machine = m_time_processor.machines[i];
@ -2618,7 +2628,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]);
if (curr.abs_axis_feedrate[a] != 0.0f) {
float axis_max_feedrate = get_axis_max_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
const float axis_max_feedrate = get_axis_max_feedrate(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
if (axis_max_feedrate != 0.0f)
min_feedrate_factor = std::min<float>(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]);
}
@ -2641,7 +2651,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
get_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i)));
for (unsigned char a = X; a <= E; ++a) {
float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
const float axis_max_acceleration = get_axis_max_acceleration(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration)
acceleration = axis_max_acceleration;
}
@ -2652,7 +2662,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
curr.safe_feedrate = block.feedrate_profile.cruise;
for (unsigned char a = X; a <= E; ++a) {
float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
const float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
if (curr.abs_axis_feedrate[a] > axis_max_jerk)
curr.safe_feedrate = std::min(curr.safe_feedrate, axis_max_jerk);
}
@ -2686,7 +2696,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
}
// Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction.
float jerk =
const float jerk =
(v_exit > v_entry) ?
((v_entry > 0.0f || v_exit < 0.0f) ?
// coasting
@ -2700,7 +2710,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// axis reversal
std::max(-v_exit, v_entry));
float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
const float axis_max_jerk = get_axis_max_jerk(static_cast<PrintEstimatedStatistics::ETimeMode>(i), static_cast<Axis>(a));
if (jerk > axis_max_jerk) {
v_factor *= axis_max_jerk / jerk;
limited = true;
@ -2712,14 +2722,14 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// Now the transition velocity is known, which maximizes the shared exit / entry velocity while
// respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints.
float vmax_junction_threshold = vmax_junction * 0.99f;
const float vmax_junction_threshold = vmax_junction * 0.99f;
// Not coasting. The machine will stop and start the movements anyway, better to start the segment from start.
if (prev.safe_feedrate > vmax_junction_threshold && curr.safe_feedrate > vmax_junction_threshold)
vmax_junction = curr.safe_feedrate;
}
float v_allowable = max_allowable_speed(-acceleration, curr.safe_feedrate, block.distance);
const float v_allowable = max_allowable_speed(-acceleration, curr.safe_feedrate, block.distance);
block.feedrate_profile.entry = std::min(vmax_junction, v_allowable);
block.max_entry_speed = vmax_junction;
@ -2755,11 +2765,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
// the threshold value = 0.0625f == 0.25 * 0.25 is arbitrary, we may find some smarter condition later
if ((new_pos - *first_vertex).squaredNorm() < 0.0625f) {
#if ENABLE_Z_OFFSET_CORRECTION
set_end_position(0.5f * (new_pos + *first_vertex) + m_z_offset * Vec3f::UnitZ());
#else
set_end_position(0.5f * (new_pos + *first_vertex));
#endif // ENABLE_Z_OFFSET_CORRECTION
store_move_vertex(EMoveType::Seam);
set_end_position(curr_pos);
}
@ -2772,15 +2778,221 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
m_seams_detector.set_first_vertex(m_result.moves.back().position - m_extruder_offsets[m_extruder_id]);
}
#if ENABLE_SPIRAL_VASE_LAYERS
if (m_spiral_vase_active && !m_result.spiral_vase_layers.empty() && !m_result.moves.empty())
m_result.spiral_vase_layers.back().second.second = m_result.moves.size() - 1;
#endif // ENABLE_SPIRAL_VASE_LAYERS
// store move
#if ENABLE_PROCESS_G2_G3_LINES
store_move_vertex(type, line.comment() == INTERNAL_G2G3_TAG);
#else
store_move_vertex(type);
#endif // ENABLE_PROCESS_G2_G3_LINES
}
#if ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise)
{
if (!line.has('X') || !line.has('Y') || !line.has('I') || !line.has('J'))
return;
// relative center
Vec3f rel_center = Vec3f::Zero();
if (!line.has_value('I', rel_center.x()) || !line.has_value('J', rel_center.y()))
return;
// scale center, if needed
if (m_units == EUnits::Inches)
rel_center *= INCHES_TO_MM;
struct Arc
{
Vec3d start{ Vec3d::Zero() };
Vec3d end{ Vec3d::Zero() };
Vec3d center{ Vec3d::Zero() };
double angle{ 0.0 };
double delta_x() const { return end.x() - start.x(); }
double delta_y() const { return end.y() - start.y(); }
double delta_z() const { return end.z() - start.z(); }
double length() const { return angle * start_radius(); }
double travel_length() const { return std::sqrt(sqr(length() + sqr(delta_z()))); }
double start_radius() const { return (start - center).norm(); }
double end_radius() const { return (end - center).norm(); }
Vec3d relative_start() const { return start - center; }
Vec3d relative_end() const { return end - center; }
bool closed() const { return end.isApprox(start); }
};
Arc arc;
// arc start endpoint
arc.start = Vec3d(m_start_position[X], m_start_position[Y], m_start_position[Z]);
// arc center
arc.center = arc.start + rel_center.cast<double>();
const float filament_diameter = (static_cast<size_t>(m_extruder_id) < m_result.filament_diameters.size()) ? m_result.filament_diameters[m_extruder_id] : m_result.filament_diameters.back();
const float filament_radius = 0.5f * filament_diameter;
const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(filament_radius);
AxisCoords end_position = m_start_position;
for (unsigned char a = X; a <= E; ++a) {
end_position[a] = extract_absolute_position_on_axis((Axis)a, line, double(area_filament_cross_section));
}
// arc end endpoint
arc.end = Vec3d(end_position[X], end_position[Y], end_position[Z]);
// radii
if (std::abs(arc.end_radius() - arc.start_radius()) > EPSILON) {
// what to do ???
}
// updates feedrate from line
std::optional<float> feedrate;
if (line.has_f())
feedrate = m_feed_multiply.current * line.f() * MMMIN_TO_MMSEC;
// updates extrusion from line
std::optional<float> extrusion;
if (line.has_e())
extrusion = end_position[E] - m_start_position[E];
// relative arc endpoints
const Vec3d rel_arc_start = arc.relative_start();
const Vec3d rel_arc_end = arc.relative_end();
// arc angle
if (arc.closed())
arc.angle = 2.0 * PI;
else {
arc.angle = std::atan2(rel_arc_start.x() * rel_arc_end.y() - rel_arc_start.y() * rel_arc_end.x(),
rel_arc_start.x() * rel_arc_end.x() + rel_arc_start.y() * rel_arc_end.y());
if (arc.angle < 0.0)
arc.angle += 2.0 * PI;
if (clockwise)
arc.angle -= 2.0 * PI;
}
const double travel_length = arc.travel_length();
if (travel_length < 0.001)
return;
auto adjust_target = [this, area_filament_cross_section](const AxisCoords& target, const AxisCoords& prev_position) {
AxisCoords ret = target;
if (m_global_positioning_type == EPositioningType::Relative) {
for (unsigned char a = X; a <= E; ++a) {
ret[a] -= prev_position[a];
}
}
else if (m_e_local_positioning_type == EPositioningType::Relative)
ret[E] -= prev_position[E];
if (m_use_volumetric_e)
ret[E] *= area_filament_cross_section;
const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0;
for (unsigned char a = X; a <= E; ++a) {
ret[a] /= lengthsScaleFactor;
}
return ret;
};
auto internal_only_g1_line = [](const AxisCoords& target, bool has_z, const std::optional<float>& feedrate, const std::optional<float>& extrusion) {
std::string ret = (boost::format("G1 X%1% Y%2%") % target[X] % target[Y]).str();
if (has_z)
ret += (boost::format(" Z%1%") % target[Z]).str();
if (feedrate.has_value())
ret += (boost::format(" F%1%") % *feedrate).str();
if (extrusion.has_value())
ret += (boost::format(" E%1%") % target[E]).str();
ret += (boost::format(" ;%1%\n") % INTERNAL_G2G3_TAG).str();
return ret;
};
// calculate arc segments
// reference:
// Prusa-Firmware\Firmware\motion_control.cpp - mc_arc()
// segments count
static const double MM_PER_ARC_SEGMENT = 1.0;
const size_t segments = std::max<size_t>(std::floor(travel_length / MM_PER_ARC_SEGMENT), 1);
const double theta_per_segment = arc.angle / double(segments);
const double z_per_segment = arc.delta_z() / double(segments);
const double extruder_per_segment = (extrusion.has_value()) ? *extrusion / double(segments) : 0.0;
double cos_T = 1.0 - 0.5 * sqr(theta_per_segment); // Small angle approximation
double sin_T = theta_per_segment;
AxisCoords prev_target = m_start_position;
AxisCoords arc_target;
double sin_Ti;
double cos_Ti;
double r_axisi;
size_t count = 0;
// Initialize the linear axis
arc_target[Z] = m_start_position[Z];
// Initialize the extruder axis
arc_target[E] = m_start_position[E];
static const size_t N_ARC_CORRECTION = 25;
Vec3d curr_rel_arc_start = arc.relative_start();
std::string gcode;
for (size_t i = 1; i < segments; ++i) { // Increment (segments-1)
if (count < N_ARC_CORRECTION) {
// Apply vector rotation matrix
r_axisi = curr_rel_arc_start.x() * sin_T + curr_rel_arc_start.y() * cos_T;
curr_rel_arc_start.x() = curr_rel_arc_start.x() * cos_T - curr_rel_arc_start.y() * sin_T;
curr_rel_arc_start.y() = r_axisi;
count++;
}
else {
// Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
// Compute exact location by applying transformation matrix from initial radius vector(=-offset).
cos_Ti = ::cos(double(i) * theta_per_segment);
sin_Ti = ::sin(double(i) * theta_per_segment);
curr_rel_arc_start.x() = -double(rel_center.x()) * cos_Ti + double(rel_center.y()) * sin_Ti;
curr_rel_arc_start.y() = -double(rel_center.x()) * sin_Ti - double(rel_center.y()) * cos_Ti;
count = 0;
}
// Update arc_target location
arc_target[X] = arc.center.x() + curr_rel_arc_start.x();
arc_target[Y] = arc.center.y() + curr_rel_arc_start.y();
arc_target[Z] += z_per_segment;
arc_target[E] += extruder_per_segment;
gcode += internal_only_g1_line(adjust_target(arc_target, prev_target), z_per_segment != 0.0, feedrate, extrusion);
prev_target = arc_target;
// feedrate is constant, we do not need to repeat it
feedrate.reset();
}
// Ensure last segment arrives at target location.
gcode += internal_only_g1_line(adjust_target(end_position, prev_target), arc.delta_z() != 0.0, feedrate, extrusion);
// process fake gcode lines
GCodeReader parser;
parser.parse_buffer(gcode, [this](GCodeReader&, const GCodeReader::GCodeLine& line) {
// force all lines to share the same id
--m_line_id;
process_gcode_line(line, false);
});
}
#endif // ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::process_G10(const GCodeReader::GCodeLine& line)
{
// stores retract move
@ -3281,7 +3493,11 @@ void GCodeProcessor::process_T(const std::string_view command)
}
}
#if ENABLE_PROCESS_G2_G3_LINES
void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
#else
void GCodeProcessor::store_move_vertex(EMoveType type)
#endif // ENABLE_PROCESS_G2_G3_LINES
{
m_last_line_id = (type == EMoveType::Color_change || type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) ?
m_line_id + 1 :
@ -3293,11 +3509,7 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
m_extrusion_role,
m_extruder_id,
m_cp_color.current,
#if ENABLE_Z_OFFSET_CORRECTION
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z] - m_z_offset) + m_extruder_offsets[m_extruder_id],
#else
Vec3f(m_end_position[X], m_end_position[Y], m_processing_start_custom_gcode ? m_first_layer_height : m_end_position[Z]) + m_extruder_offsets[m_extruder_id],
#endif // ENABLE_Z_OFFSET_CORRECTION
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z] - m_z_offset) + m_extruder_offsets[m_extruder_id],
static_cast<float>(m_end_position[E] - m_start_position[E]),
m_feedrate,
m_width,
@ -3305,7 +3517,12 @@ void GCodeProcessor::store_move_vertex(EMoveType type)
m_mm3_per_mm,
m_fan_speed,
m_extruder_temps[m_extruder_id],
#if ENABLE_PROCESS_G2_G3_LINES
static_cast<float>(m_result.moves.size()),
internal_only
#else
static_cast<float>(m_result.moves.size())
#endif // ENABLE_PROCESS_G2_G3_LINES
});
// stores stop time placeholders for later use
@ -3502,5 +3719,24 @@ void GCodeProcessor::update_estimated_times_stats()
m_result.print_statistics.used_filaments_per_role = m_used_filaments.filaments_per_role;
}
#if ENABLE_PROCESS_G2_G3_LINES
double GCodeProcessor::extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section)
{
if (line.has(Slic3r::Axis(axis))) {
bool is_relative = (m_global_positioning_type == EPositioningType::Relative);
if (axis == E)
is_relative |= (m_e_local_positioning_type == EPositioningType::Relative);
const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0;
double ret = line.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
if (axis == E && m_use_volumetric_e)
ret /= area_filament_cross_section;
return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret;
}
else
return m_start_position[axis];
}
#endif // ENABLE_PROCESS_G2_G3_LINES
} /* namespace Slic3r */

View File

@ -113,6 +113,9 @@ namespace Slic3r {
float fan_speed{ 0.0f }; // percentage
float temperature{ 0.0f }; // Celsius degrees
float time{ 0.0f }; // s
#if ENABLE_PROCESS_G2_G3_LINES
bool internal_only{ false };
#endif // ENABLE_PROCESS_G2_G3_LINES
float volumetric_rate() const { return feedrate * mm3_per_mm; }
};
@ -131,9 +134,7 @@ namespace Slic3r {
std::vector<float> filament_densities;
PrintEstimatedStatistics print_statistics;
std::vector<CustomGCode::Item> custom_gcode_per_print_z;
#if ENABLE_SPIRAL_VASE_LAYERS
std::vector<std::pair<float, std::pair<size_t, size_t>>> spiral_vase_layers;
#endif // ENABLE_SPIRAL_VASE_LAYERS
#if ENABLE_GCODE_VIEWER_STATISTICS
int64_t time{ 0 };
@ -542,16 +543,13 @@ namespace Slic3r {
float m_forced_height; // mm
float m_mm3_per_mm;
float m_fan_speed; // percentage
#if ENABLE_Z_OFFSET_CORRECTION
float m_z_offset; // mm
#endif // ENABLE_Z_OFFSET_CORRECTION
ExtrusionRole m_extrusion_role;
unsigned char m_extruder_id;
ExtruderColors m_extruder_colors;
ExtruderTemps m_extruder_temps;
float m_extruded_last_z;
float m_first_layer_height; // mm
bool m_processing_start_custom_gcode;
unsigned int m_g1_line_id;
unsigned int m_layer_id;
CpColor m_cp_color;
@ -559,9 +557,7 @@ namespace Slic3r {
SeamsDetector m_seams_detector;
OptionsZCorrector m_options_z_corrector;
size_t m_last_default_color_id;
#if ENABLE_SPIRAL_VASE_LAYERS
bool m_spiral_vase_active;
#endif // ENABLE_SPIRAL_VASE_LAYERS
#if ENABLE_GCODE_VIEWER_STATISTICS
std::chrono::time_point<std::chrono::high_resolution_clock> m_start_time;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
@ -652,6 +648,11 @@ namespace Slic3r {
void process_G0(const GCodeReader::GCodeLine& line);
void process_G1(const GCodeReader::GCodeLine& line);
#if ENABLE_PROCESS_G2_G3_LINES
// Arc Move
void process_G2_G3(const GCodeReader::GCodeLine& line, bool clockwise);
#endif // ENABLE_PROCESS_G2_G3_LINES
// Retract
void process_G10(const GCodeReader::GCodeLine& line);
@ -752,7 +753,11 @@ namespace Slic3r {
void process_T(const GCodeReader::GCodeLine& line);
void process_T(const std::string_view command);
#if ENABLE_PROCESS_G2_G3_LINES
void store_move_vertex(EMoveType type, bool internal_only = false);
#else
void store_move_vertex(EMoveType type);
#endif // ENABLE_PROCESS_G2_G3_LINES
void set_extrusion_role(ExtrusionRole role);
@ -777,6 +782,10 @@ namespace Slic3r {
void simulate_st_synchronize(float additional_time = 0.0f);
void update_estimated_times_stats();
#if ENABLE_PROCESS_G2_G3_LINES
double extract_absolute_position_on_axis(Axis axis, const GCodeReader::GCodeLine& line, double area_filament_cross_section);
#endif // ENABLE_PROCESS_G2_G3_LINES
};
} /* namespace Slic3r */

View File

@ -20,6 +20,10 @@ namespace FillAdaptive {
struct Octree;
};
namespace FillLightning {
class Generator;
};
class LayerRegion
{
public:
@ -151,8 +155,8 @@ public:
}
void make_perimeters();
// Phony version of make_fills() without parameters for Perl integration only.
void make_fills() { this->make_fills(nullptr, nullptr); }
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree);
void make_fills() { this->make_fills(nullptr, nullptr, nullptr); }
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree, FillLightning::Generator* lightning_generator);
void make_ironing();
void export_region_slices_to_svg(const char *path) const;

View File

@ -8,7 +8,7 @@
namespace Slic3r {
static ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance)
static ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
{
ExtrusionPaths paths;
ExtrusionPath path(role);
@ -71,7 +71,7 @@ static ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thi
path.height = new_flow.height();
} else {
thickness_delta = fabs(scale_(flow.width()) - w);
if (thickness_delta <= tolerance) {
if (thickness_delta <= merge_tolerance) {
// the width difference between this line and the current flow width is
// within the accepted tolerance
path.polyline.append(line.b);
@ -95,7 +95,7 @@ static void variable_width(const ThickPolylines& polylines, ExtrusionRole role,
// of segments, and any pruning shall be performed before we apply this tolerance.
const float tolerance = float(scale_(0.05));
for (const ThickPolyline &p : polylines) {
ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance);
ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance, tolerance);
// Append paths to collection.
if (! paths.empty()) {
if (paths.front().first_point() == paths.back().last_point())

View File

@ -177,6 +177,11 @@ inline bool operator<(const Point &l, const Point &r)
return l.x() < r.x() || (l.x() == r.x() && l.y() < r.y());
}
inline Point operator* (const Point& l, const double &r)
{
return {coord_t(l.x() * r), coord_t(l.y() * r)};
}
inline bool is_approx(const Point &p1, const Point &p2, coord_t epsilon = coord_t(SCALED_EPSILON))
{
Point d = (p2 - p1).cwiseAbs();

View File

@ -35,7 +35,13 @@ namespace FillAdaptive {
struct Octree;
struct OctreeDeleter;
using OctreePtr = std::unique_ptr<Octree, OctreeDeleter>;
};
}; // namespace FillAdaptive
namespace FillLightning {
class Generator;
struct GeneratorDeleter;
using GeneratorPtr = std::unique_ptr<Generator, GeneratorDeleter>;
}; // namespace FillLightning
// Print step IDs for keeping track of the print state.
// The Print steps are applied in this order.
@ -387,6 +393,7 @@ private:
void combine_infill();
void _generate_support_material();
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> prepare_adaptive_infill_data();
FillLightning::GeneratorPtr prepare_lightning_infill_data();
// XYZ in scaled coordinates
Vec3crd m_size;

View File

@ -108,9 +108,7 @@ static const t_config_enum_values s_keys_map_InfillPattern {
{ "octagramspiral", ipOctagramSpiral },
{ "adaptivecubic", ipAdaptiveCubic },
{ "supportcubic", ipSupportCubic },
#if HAS_LIGHTNING_INFILL
{ "lightning", ipLightning }
#endif // HAS_LIGHTNING_INFILL
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern)
@ -1155,9 +1153,7 @@ void PrintConfigDef::init_fff_params()
def->enum_values.push_back("octagramspiral");
def->enum_values.push_back("adaptivecubic");
def->enum_values.push_back("supportcubic");
#if HAS_LIGHTNING_INFILL
def->enum_values.push_back("lightning");
#endif // HAS_LIGHTNING_INFILL
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Aligned Rectilinear"));
def->enum_labels.push_back(L("Grid"));
@ -1174,9 +1170,7 @@ void PrintConfigDef::init_fff_params()
def->enum_labels.push_back(L("Octagram Spiral"));
def->enum_labels.push_back(L("Adaptive Cubic"));
def->enum_labels.push_back(L("Support Cubic"));
#if HAS_LIGHTNING_INFILL
def->enum_labels.push_back(L("Lightning"));
#endif // HAS_LIGHTNING_INFILL
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
def = this->add("first_layer_acceleration", coFloat);

View File

@ -57,14 +57,10 @@ enum class FuzzySkinType {
All,
};
#define HAS_LIGHTNING_INFILL 0
enum InfillPattern : int {
ipRectilinear, ipMonotonic, ipAlignedRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipSupportCubic, ipSupportBase,
#if HAS_LIGHTNING_INFILL
ipLightning,
#endif // HAS_LIGHTNING_INFILL
ipCount,
};

View File

@ -14,6 +14,7 @@
#include "TriangleMeshSlicer.hpp"
#include "Utils.hpp"
#include "Fill/FillAdaptive.hpp"
#include "Fill/FillLightning.hpp"
#include "Format/STL.hpp"
#include <float.h>
@ -353,14 +354,15 @@ void PrintObject::infill()
if (this->set_started(posInfill)) {
auto [adaptive_fill_octree, support_fill_octree] = this->prepare_adaptive_infill_data();
auto lightning_generator = this->prepare_lightning_infill_data();
BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - start";
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_layers.size()),
[this, &adaptive_fill_octree = adaptive_fill_octree, &support_fill_octree = support_fill_octree](const tbb::blocked_range<size_t>& range) {
[this, &adaptive_fill_octree = adaptive_fill_octree, &support_fill_octree = support_fill_octree, &lightning_generator](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
m_print->throw_if_canceled();
m_layers[layer_idx]->make_fills(adaptive_fill_octree.get(), support_fill_octree.get());
m_layers[layer_idx]->make_fills(adaptive_fill_octree.get(), support_fill_octree.get(), lightning_generator.get());
}
}
);
@ -453,6 +455,18 @@ std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare
support_line_spacing ? build_octree(mesh, overhangs.front(), support_line_spacing, true) : OctreePtr());
}
FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data()
{
bool has_lightning_infill = false;
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id)
if (const PrintRegionConfig &config = this->printing_region(region_id).config(); config.fill_density > 0 && config.fill_pattern == ipLightning) {
has_lightning_infill = true;
break;
}
return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this)) : FillLightning::GeneratorPtr();
}
void PrintObject::clear_layers()
{
for (Layer *l : m_layers)

View File

@ -1174,7 +1174,8 @@ sla::SupportPoints SLAPrintObject::transformed_support_points() const
{
assert(m_model_object != nullptr);
auto spts = m_model_object->sla_support_points;
auto tr = trafo().cast<float>();
const Transform3d& vol_trafo = m_model_object->volumes.front()->get_transformation().get_matrix();
const Transform3f& tr = (trafo() * vol_trafo).cast<float>();
for (sla::SupportPoint& suppt : spts) {
suppt.pos = tr * suppt.pos;
}
@ -1186,8 +1187,10 @@ sla::DrainHoles SLAPrintObject::transformed_drainhole_points() const
{
assert(m_model_object != nullptr);
auto pts = m_model_object->sla_drain_holes;
auto tr = trafo().cast<float>();
auto sc = m_model_object->instances.front()->get_scaling_factor().cast<float>();
const Transform3d& vol_trafo = m_model_object->volumes.front()->get_transformation().get_matrix();
const Geometry::Transformation trans(trafo() * vol_trafo);
const Transform3f& tr = trans.get_matrix().cast<float>();
const Vec3f sc = trans.get_scaling_factor().cast<float>();
for (sla::DrainHole &hl : pts) {
hl.pos = tr * hl.pos;
hl.normal = tr * hl.normal - tr.translation();

View File

@ -36,17 +36,6 @@
#define ENABLE_SMOOTH_NORMALS 0
//================
// 2.4.1.rc techs
//================
#define ENABLE_2_4_1_RC 1
// Enable detection of layers for spiral vase prints
#define ENABLE_SPIRAL_VASE_LAYERS (1 && ENABLE_2_4_1_RC)
// Enable correction of toolpaths when z offset is set
#define ENABLE_Z_OFFSET_CORRECTION (1 && ENABLE_2_4_1_RC)
//====================
// 2.5.0.alpha1 techs
//====================
@ -94,5 +83,9 @@
#define ENABLE_NEW_CAMERA_MOVEMENTS (1 && ENABLE_2_5_0_ALPHA1)
// Enable modified rectangle selection
#define ENABLE_NEW_RECTANGLE_SELECTION (1 && ENABLE_2_5_0_ALPHA1)
// Enable alternative version of file_wildcards()
#define ENABLE_ALTERNATIVE_FILE_WILDCARDS_GENERATOR (1 && ENABLE_2_5_0_ALPHA1)
// Enable processing of gcode G2 and G3 lines
#define ENABLE_PROCESS_G2_G3_LINES (1 && ENABLE_2_5_0_ALPHA1)
#endif // _prusaslicer_technologies_h_

View File

@ -217,6 +217,8 @@ set(SLIC3R_GUI_SOURCES
GUI/DesktopIntegrationDialog.hpp
GUI/HintNotification.cpp
GUI/HintNotification.hpp
Utils/AppUpdater.cpp
Utils/AppUpdater.hpp
Utils/Http.cpp
Utils/Http.hpp
Utils/FixModelByWin10.cpp
@ -254,6 +256,7 @@ if (APPLE)
list(APPEND SLIC3R_GUI_SOURCES
Utils/RetinaHelperImpl.mm
Utils/MacDarkMode.mm
Utils/MacUtils.mm
GUI/RemovableDriveManagerMM.mm
GUI/RemovableDriveManagerMM.h
GUI/Mouse3DHandlerMac.mm

View File

@ -131,11 +131,7 @@ void Bed3D::Axes::render()
if (!m_arrow.is_initialized())
m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@ -634,11 +630,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
#if ENABLE_LEGACY_OPENGL_REMOVAL
init_triangles();
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
@ -762,11 +754,7 @@ void Bed3D::render_model()
}
if (!m_model.get_filename().empty()) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
@ -830,11 +818,7 @@ void Bed3D::render_default(bool bottom, bool picking)
init_gridlines();
init_triangles();
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();

View File

@ -1085,14 +1085,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
return;
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat_attr");
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat_attr");
assert(boost::algorithm::iends_with(shader->get_name(), "_attr"));
#else
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat");
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (type == ERenderType::Transparent) {

View File

@ -106,26 +106,36 @@ double Camera::get_fov() const
void Camera::apply_viewport(int x, int y, unsigned int w, unsigned int h)
{
glsafe(::glViewport(0, 0, w, h));
#if ENABLE_LEGACY_OPENGL_REMOVAL
m_viewport = { 0, 0, int(w), int(h) };
#else
glsafe(::glGetIntegerv(GL_VIEWPORT, m_viewport.data()));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void Camera::apply_view_matrix()
{
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glLoadIdentity());
glsafe(::glMultMatrixd(m_view_matrix.data()));
}
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double far_z)
{
double w = 0.0;
double h = 0.0;
#if !ENABLE_LEGACY_OPENGL_REMOVAL
const double old_distance = m_distance;
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
m_frustrum_zs = calc_tight_frustrum_zs_around(box);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
if (m_distance != old_distance)
// the camera has been moved re-apply view matrix
apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (near_z > 0.0)
m_frustrum_zs.first = std::max(std::min(m_frustrum_zs.first, near_z), FrustrumMinNearZ);
@ -159,6 +169,35 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
}
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
switch (m_type)
{
default:
case EType::Ortho:
{
const double dz = m_frustrum_zs.second - m_frustrum_zs.first;
const double zz = m_frustrum_zs.first + m_frustrum_zs.second;
m_projection_matrix.matrix() << 1.0 / w, 0.0, 0.0, 0.0,
0.0, 1.0 / h, 0.0, 0.0,
0.0, 0.0, -2.0 / dz, -zz / dz,
0.0, 0.0, 0.0, 1.0;
break;
}
case EType::Perspective:
{
const double n = m_frustrum_zs.first;
const double f = m_frustrum_zs.second;
const double dz = f - n;
const double zz = n + f;
const double fn = n * f;
m_projection_matrix.matrix() << n / w, 0.0, 0.0, 0.0,
0.0, n / h, 0.0, 0.0,
0.0, 0.0, -zz / dz, -2.0 * fn / dz,
0.0, 0.0, -1.0, 0.0;
break;
}
}
#else
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glLoadIdentity());
@ -179,6 +218,7 @@ void Camera::apply_projection(const BoundingBoxf3& box, double near_z, double fa
glsafe(::glGetDoublev(GL_PROJECTION_MATRIX, m_projection_matrix.data()));
glsafe(::glMatrixMode(GL_MODELVIEW));
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void Camera::zoom_to_box(const BoundingBoxf3& box, double margin_factor)
@ -298,8 +338,8 @@ std::pair<double, double> Camera::calc_tight_frustrum_zs_around(const BoundingBo
// box in eye space
const BoundingBoxf3 eye_box = box.transformed(m_view_matrix);
near_z = -eye_box.max(2);
far_z = -eye_box.min(2);
near_z = -eye_box.max.z();
far_z = -eye_box.min.z();
// apply margin
near_z -= FrustrumZMargin;
@ -465,19 +505,19 @@ void Camera::look_at(const Vec3d& position, const Vec3d& target, const Vec3d& up
m_distance = (position - target).norm();
const Vec3d new_position = m_target + m_distance * unit_z;
m_view_matrix(0, 0) = unit_x(0);
m_view_matrix(0, 1) = unit_x(1);
m_view_matrix(0, 2) = unit_x(2);
m_view_matrix(0, 0) = unit_x.x();
m_view_matrix(0, 1) = unit_x.y();
m_view_matrix(0, 2) = unit_x.z();
m_view_matrix(0, 3) = -unit_x.dot(new_position);
m_view_matrix(1, 0) = unit_y(0);
m_view_matrix(1, 1) = unit_y(1);
m_view_matrix(1, 2) = unit_y(2);
m_view_matrix(1, 0) = unit_y.x();
m_view_matrix(1, 1) = unit_y.y();
m_view_matrix(1, 2) = unit_y.z();
m_view_matrix(1, 3) = -unit_y.dot(new_position);
m_view_matrix(2, 0) = unit_z(0);
m_view_matrix(2, 1) = unit_z(1);
m_view_matrix(2, 2) = unit_z(2);
m_view_matrix(2, 0) = unit_z.x();
m_view_matrix(2, 1) = unit_z.y();
m_view_matrix(2, 2) = unit_z.z();
m_view_matrix(2, 3) = -unit_z.dot(new_position);
m_view_matrix(3, 0) = 0.0;

View File

@ -92,7 +92,9 @@ public:
double get_fov() const;
void apply_viewport(int x, int y, unsigned int w, unsigned int h);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
void apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// Calculates and applies the projection matrix tighting the frustrum z range around the given box.
// If larger z span is needed, pass the desired values of near and far z (negative values are ignored)
void apply_projection(const BoundingBoxf3& box, double near_z = -1.0, double far_z = -1.0);

View File

@ -184,11 +184,7 @@ void GCodeViewer::COG::render()
init();
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@ -331,11 +327,7 @@ void GCodeViewer::SequentialView::Marker::render()
if (!m_visible)
return;
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@ -703,11 +695,7 @@ void GCodeViewer::init()
#if !DISABLE_GCODEVIEWER_INSTANCED_MODELS
if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
#if ENABLE_GL_SHADERS_ATTRIBUTES
buffer.shader = "gouraud_light_instanced_attr";
#else
buffer.shader = "gouraud_light_instanced";
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
buffer.model.model.init_from(diamond(16));
buffer.model.color = option_color(type);
buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
@ -716,12 +704,7 @@ void GCodeViewer::init()
#endif // !DISABLE_GCODEVIEWER_INSTANCED_MODELS
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
#if ENABLE_GL_SHADERS_ATTRIBUTES
buffer.shader = "gouraud_light_attr";
#else
buffer.shader = "gouraud_light";
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
buffer.model.data = diamond(16);
buffer.model.color = option_color(type);
buffer.model.instances.format = InstanceVBuffer::EFormat::BatchedModel;
@ -734,18 +717,14 @@ void GCodeViewer::init()
case EMoveType::Extrude: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
#if ENABLE_GL_SHADERS_ATTRIBUTES
buffer.shader = "gouraud_light_attr";
#else
buffer.shader = "gouraud_light";
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
break;
}
case EMoveType::Travel: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
#if ENABLE_GL_SHADERS_ATTRIBUTES
buffer.vertices.format = VBuffer::EFormat::Position;
buffer.shader = "flat_attr";
buffer.shader = "flat";
#else
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "toolpaths_lines";
@ -2284,6 +2263,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
size_t move_id = i - seams_count;
if (move.type == EMoveType::Extrude) {
#if ENABLE_PROCESS_G2_G3_LINES
if (move.extrusion_role != erNone && !move.internal_only) {
#endif // ENABLE_PROCESS_G2_G3_LINES
// layers zs
const double* const last_z = m_layers.empty() ? nullptr : &m_layers.get_zs().back();
const double z = static_cast<double>(move.position.z());
@ -2291,6 +2273,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
m_layers.append(z, { last_travel_s_id, move_id });
else
m_layers.get_ranges().back().last = move_id;
#if ENABLE_PROCESS_G2_G3_LINES
}
#endif // ENABLE_PROCESS_G2_G3_LINES
// extruder ids
m_extruder_ids.emplace_back(move.extruder_id);
// roles
@ -2313,7 +2298,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
sort_remove_duplicates(m_extruder_ids);
m_extruder_ids.shrink_to_fit();
#if ENABLE_SPIRAL_VASE_LAYERS
// replace layers for spiral vase mode
if (!gcode_result.spiral_vase_layers.empty()) {
m_layers.reset();
@ -2321,7 +2305,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
m_layers.append(layer.first, { layer.second.first, layer.second.second });
}
}
#endif // ENABLE_SPIRAL_VASE_LAYERS
// set layers z range
if (!m_layers.empty())
@ -3163,11 +3146,8 @@ void GCodeViewer::render_toolpaths()
const int position_id = shader->get_attrib_location("v_position");
const int normal_id = shader->get_attrib_location("v_normal");
#else
switch (buffer.render_primitive_type) {
case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break;
default: break;
}
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Line)
shader_init_as_lines(*shader);
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
const int uniform_color = shader->get_uniform_location("uniform_color");
@ -3324,11 +3304,7 @@ void GCodeViewer::render_shells()
if (!m_shells.visible || m_shells.volumes.empty())
return;
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;

View File

@ -161,11 +161,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
bool GLCanvas3D::LayersEditing::is_allowed() const
{
#if ENABLE_GL_SHADERS_ATTRIBUTES
return wxGetApp().get_shader("variable_layer_height_attr") != nullptr && m_z_texture_id > 0;
#else
return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0;
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
bool GLCanvas3D::LayersEditing::is_enabled() const
@ -328,11 +324,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
bool GLCanvas3D::LayersEditing::is_initialized() const
{
#if ENABLE_GL_SHADERS_ATTRIBUTES
return wxGetApp().get_shader("variable_layer_height_attr") != nullptr;
#else
return wxGetApp().get_shader("variable_layer_height") != nullptr;
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const
@ -375,11 +367,8 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
return;
const float cnv_inv_width = 1.0f / cnv_width;
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
if (shader == nullptr)
return;
@ -550,11 +539,7 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
m_profile.profile.init_from(std::move(init_data));
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
@ -594,11 +579,7 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
if (current_shader != nullptr)
current_shader->stop_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@ -1075,11 +1056,7 @@ void GLCanvas3D::SequentialPrintClearance::render()
const ColorRGBA NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f };
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
@ -1685,13 +1662,17 @@ void GLCanvas3D::render()
camera.requires_zoom_to_bed = false;
}
#if !ENABLE_LEGACY_OPENGL_REMOVAL
camera.apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
camera.apply_projection(_max_bounding_box(true, true));
#if !ENABLE_LEGACY_OPENGL_REMOVAL
GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
glsafe(::glLightfv(GL_LIGHT1, GL_POSITION, position_cam));
GLfloat position_top[4] = { -0.5f, -0.5f, 1.0f, 0.0f };
glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top));
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
wxGetApp().imgui()->new_frame();
@ -2232,7 +2213,13 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
if (state.step[istep].state == PrintStateBase::DONE) {
TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles);
assert(! mesh.empty());
mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse());
// sla_trafo does not contain volume trafo. To get a mesh to create
// a new volume from, we have to apply vol trafo inverse separately.
const ModelObject& mo = *m_model->objects[volume.object_idx()];
Transform3d trafo = sla_print->sla_trafo(mo)
* mo.volumes.front()->get_transformation().get_matrix();
mesh.transform(trafo.inverse());
#if ENABLE_SMOOTH_NORMALS
#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.init_from(mesh, true);
@ -3451,6 +3438,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
else {
#if ENABLE_NEW_RECTANGLE_SELECTION
const bool rectangle_selection_dragging = m_rectangle_selection.is_dragging();
if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports &&
m_gizmos.get_current_type() != GLGizmosManager::FdmSupports &&
@ -3467,8 +3455,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
// during the scene manipulation.
#if ENABLE_NEW_RECTANGLE_SELECTION
if (m_picking_enabled && (!any_gizmo_active || !evt.ShiftDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled()) &&
!m_rectangle_selection.is_dragging()) {
if (m_picking_enabled && !any_gizmo_active && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled()) && !rectangle_selection_dragging) {
#else
if (m_picking_enabled && (!any_gizmo_active || !evt.CmdDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled())) {
#endif // ENABLE_NEW_RECTANGLE_SELECTION
@ -3612,9 +3599,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
// do not process the dragging if the left mouse was set down in another canvas
#if ENABLE_NEW_CAMERA_MOVEMENTS
else if (evt.LeftIsDown() || evt.MiddleIsDown()) {
else if (evt.LeftIsDown()) {
// if dragging over blank area with left button, rotate
if ((any_gizmo_active || evt.CmdDown() || evt.MiddleIsDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
if ((any_gizmo_active || evt.CmdDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
#else
// if dragging over blank area with left button, rotate
else if (evt.LeftIsDown()) {
@ -3638,13 +3625,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
m_mouse.drag.start_position_3D = Vec3d((double)pos.x(), (double)pos.y(), 0.0);
}
#if ENABLE_NEW_CAMERA_MOVEMENTS
else if (evt.RightIsDown()) {
// If dragging with right button, pan.
#else
else if (evt.MiddleIsDown() || evt.RightIsDown()) {
// If dragging over blank area with right button, pan.
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
// If dragging over blank area with right/middle button, pan.
if (m_mouse.is_start_position_2D_defined()) {
// get point in model space at Z = 0
float z = 0.0f;
@ -4578,7 +4560,9 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
camera.set_scene_box(scene_bounding_box());
camera.apply_viewport(0, 0, thumbnail_data.width, thumbnail_data.height);
camera.zoom_to_box(volumes_box);
#if !ENABLE_LEGACY_OPENGL_REMOVAL
camera.apply_view_matrix();
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
const Transform3d& view_matrix = camera.get_view_matrix();
@ -4602,11 +4586,7 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
camera.apply_projection(volumes_box, near_z, far_z);
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@ -5545,11 +5525,7 @@ void GLCanvas3D::_render_background()
m_background.init_from(std::move(init_data));
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("background_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("background");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("top_color", use_error_color ? ERROR_BG_LIGHT_COLOR : DEFAULT_BG_LIGHT_COLOR);
@ -5675,11 +5651,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify);
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
@ -5904,11 +5876,7 @@ void GLCanvas3D::_render_overlays()
void GLCanvas3D::_render_volumes_for_picking() const
{
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
@ -6097,50 +6065,45 @@ void GLCanvas3D::_render_camera_target()
#if ENABLE_LEGACY_OPENGL_REMOVAL
const Vec3f& target = wxGetApp().plater()->get_camera().get_target().cast<float>();
bool target_changed = !m_camera_target.target.isApprox(target.cast<double>());
m_camera_target.target = target.cast<double>();
for (int i = 0; i < 3; ++i) {
if (!m_camera_target.axis[i].is_initialized() || target_changed) {
if (!m_camera_target.axis[i].is_initialized()) {
m_camera_target.axis[i].reset();
GLModel::Geometry init_data;
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.color = (i == X) ? ColorRGBA::X() : ((i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
// vertices
if (i == X) {
init_data.add_vertex(Vec3f(target.x() - half_length, target.y(), target.z()));
init_data.add_vertex(Vec3f(target.x() + half_length, target.y(), target.z()));
init_data.add_vertex(Vec3f(-half_length, 0.0f, 0.0f));
init_data.add_vertex(Vec3f(+half_length, 0.0f, 0.0f));
}
else if (i == Y) {
init_data.add_vertex(Vec3f(target.x(), target.y() - half_length, target.z()));
init_data.add_vertex(Vec3f(target.x(), target.y() + half_length, target.z()));
init_data.add_vertex(Vec3f(0.0f, -half_length, 0.0f));
init_data.add_vertex(Vec3f(0.0f, +half_length, 0.0f));
}
else {
init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() - half_length));
init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() + half_length));
init_data.add_vertex(Vec3f(0.0f, 0.0f, -half_length));
init_data.add_vertex(Vec3f(0.0f, 0.0f, +half_length));
}
// indices
init_data.add_ushort_line(0, 1);
init_data.add_line(0, 1);
m_camera_target.axis[i].init_from(std::move(init_data));
}
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::assemble_transform(m_camera_target.target));
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
for (int i = 0; i < 3; ++i) {
@ -6316,11 +6279,7 @@ void GLCanvas3D::_render_sla_slices()
}
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();

View File

@ -861,7 +861,7 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
#if ENABLE_GL_SHADERS_ATTRIBUTES
position_id = shader->get_attrib_location("v_position");
if (position_id != -1) {
glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format)));
glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format)));
glsafe(::glEnableVertexAttribArray(position_id));
}
#else
@ -873,7 +873,7 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
#if ENABLE_GL_SHADERS_ATTRIBUTES
normal_id = shader->get_attrib_location("v_normal");
if (normal_id != -1) {
glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format)));
glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format)));
glsafe(::glEnableVertexAttribArray(normal_id));
}
#else
@ -885,7 +885,7 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
#if ENABLE_GL_SHADERS_ATTRIBUTES
tex_coord_id = shader->get_attrib_location("v_tex_coord");
if (tex_coord_id != -1) {
glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::tex_coord_offset_bytes(data.format)));
glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format)));
glsafe(::glEnableVertexAttribArray(tex_coord_id));
}
#else
@ -930,16 +930,12 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (instances_vbo == 0)
if (instances_vbo == 0 || instances_count == 0)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced_attr"))
#else
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced"))
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
// vertex attributes
@ -974,11 +970,12 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo));
#if ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0));
const size_t instance_stride = 5 * sizeof(float);
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, instance_stride, (const void*)0));
glsafe(::glEnableVertexAttribArray(offset_id));
glsafe(::glVertexAttribDivisor(offset_id, 1));
glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float))));
glsafe(::glVertexAttribPointer(scales_id, 2, GL_FLOAT, GL_FALSE, instance_stride, (const void*)(3 * sizeof(float))));
glsafe(::glEnableVertexAttribArray(scales_id));
glsafe(::glVertexAttribDivisor(scales_id, 1));
#else
@ -1000,8 +997,6 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
const GLenum mode = get_primitive_mode(data.format);
const GLenum index_type = get_index_type(data);
shader->set_uniform("uniform_color", data.color);
const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format);
const bool position = Geometry::has_position(data.format);
const bool normal = Geometry::has_normal(data.format);
@ -1009,15 +1004,17 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
if (position) {
glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format)));
glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format)));
glsafe(::glEnableVertexAttribArray(position_id));
}
if (normal) {
glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format)));
glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format)));
glsafe(::glEnableVertexAttribArray(normal_id));
}
shader->set_uniform("uniform_color", data.color);
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
glsafe(::glDrawElementsInstanced(mode, indices_count(), index_type, (const void*)0, instances_count));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
@ -1133,6 +1130,7 @@ bool GLModel::send_to_gpu()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
else {
data.index_type = Geometry::EIndexType::UINT;
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}

View File

@ -131,11 +131,7 @@ namespace GUI {
glsafe(::glEnable(GL_LINE_STIPPLE));
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();

View File

@ -35,14 +35,15 @@ std::pair<bool, std::string> GLShadersManager::init()
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_GL_SHADERS_ATTRIBUTES
const std::string prefix = GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 1) ? "140/" : "110/";
// imgui shader
valid &= append_shader("imgui", { "imgui.vs", "imgui.fs" });
valid &= append_shader("imgui", { prefix + "imgui.vs", prefix + "imgui.fs" });
// basic shader, used to render all what was previously rendered using the immediate mode
valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" });
valid &= append_shader("flat", { prefix + "flat.vs", prefix + "flat.fs" });
// basic shader for textures, used to render textures
valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" });
valid &= append_shader("flat_texture", { prefix + "flat_texture.vs", prefix + "flat_texture.fs" });
// used to render 3D scene background
valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" });
valid &= append_shader("background", { prefix + "background.vs", prefix + "background.fs" });
#else
// basic shader, used to render all what was previously rendered using the immediate mode
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
@ -55,16 +56,16 @@ std::pair<bool, std::string> GLShadersManager::init()
#if ENABLE_SHOW_TOOLPATHS_COG
// used to render toolpaths center of gravity
#if ENABLE_GL_SHADERS_ATTRIBUTES
valid &= append_shader("toolpaths_cog_attr", { "toolpaths_cog_attr.vs", "toolpaths_cog.fs" });
valid &= append_shader("toolpaths_cog", { prefix + "toolpaths_cog.vs", prefix + "toolpaths_cog.fs" });
#else
valid &= append_shader("toolpaths_cog", { "toolpaths_cog.vs", "toolpaths_cog.fs" });
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#endif // ENABLE_SHOW_TOOLPATHS_COG
#if ENABLE_GL_SHADERS_ATTRIBUTES
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
valid &= append_shader("gouraud_light_attr", { "gouraud_light_attr.vs", "gouraud_light.fs" });
valid &= append_shader("gouraud_light", { prefix + "gouraud_light.vs", prefix + "gouraud_light.fs" });
// used to render printbed
valid &= append_shader("printbed_attr", { "printbed_attr.vs", "printbed.fs" });
valid &= append_shader("printbed", { prefix + "printbed.vs", prefix + "printbed.fs" });
#else
// used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview
valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" });
@ -74,14 +75,14 @@ std::pair<bool, std::string> GLShadersManager::init()
// used to render options in gcode preview
if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
#if ENABLE_GL_SHADERS_ATTRIBUTES
valid &= append_shader("gouraud_light_instanced_attr", { "gouraud_light_instanced_attr.vs", "gouraud_light_instanced.fs" });
valid &= append_shader("gouraud_light_instanced", { prefix + "gouraud_light_instanced.vs", prefix + "gouraud_light_instanced.fs" });
#else
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
#if ENABLE_GL_SHADERS_ATTRIBUTES
// used to render objects in 3d editor
valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" }
valid &= append_shader("gouraud", { prefix + "gouraud.vs", prefix + "gouraud.fs" }
#else
// used to render extrusion and travel paths as lines in gcode preview
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
@ -94,9 +95,9 @@ std::pair<bool, std::string> GLShadersManager::init()
);
#if ENABLE_GL_SHADERS_ATTRIBUTES
// used to render variable layers heights in 3d editor
valid &= append_shader("variable_layer_height_attr", { "variable_layer_height_attr.vs", "variable_layer_height.fs" });
valid &= append_shader("variable_layer_height", { prefix + "variable_layer_height.vs", prefix + "variable_layer_height.fs" });
// used to render highlight contour around selected triangles inside the multi-material gizmo
valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" });
valid &= append_shader("mm_contour", { prefix + "mm_contour.vs", prefix + "mm_contour.fs" });
#else
// used to render variable layers heights in 3d editor
valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" });
@ -111,9 +112,9 @@ std::pair<bool, std::string> GLShadersManager::init()
// triangle normals inside fragment shader have the right direction.
#if ENABLE_GL_SHADERS_ATTRIBUTES
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" }, { "FLIP_TRIANGLE_NORMALS"sv });
valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv });
else
valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" });
valid &= append_shader("mm_gouraud", { prefix + "mm_gouraud.vs", prefix + "mm_gouraud.fs" });
#else
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});

View File

@ -358,11 +358,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
GLModel model;
model.init_from(std::move(init_data));
#if ENABLE_GL_SHADERS_ATTRIBUTES
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr");
#else
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture");
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GL_SHADERS_ATTRIBUTES

View File

@ -10,6 +10,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/any.hpp>
#include <boost/filesystem.hpp>
#if __APPLE__
#import <IOKit/pwr_mgt/IOPMLib.h>
@ -476,25 +477,36 @@ void about()
void desktop_open_datadir_folder()
{
// Execute command to open a file explorer, platform dependent.
// FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
boost::filesystem::path path(data_dir());
desktop_open_folder(std::move(path));
}
const auto path = data_dir();
void desktop_open_folder(const boost::filesystem::path& path)
{
if (!boost::filesystem::is_directory(path))
return;
// Execute command to open a file explorer, platform dependent.
#ifdef _WIN32
const wxString widepath = from_u8(path);
const wxString widepath = path.wstring();
const wchar_t* argv[] = { L"explorer", widepath.GetData(), nullptr };
::wxExecute(const_cast<wchar_t**>(argv), wxEXEC_ASYNC, nullptr);
#elif __APPLE__
const char *argv[] = { "open", path.data(), nullptr };
const char* argv[] = { "open", path.string().c_str(), nullptr };
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr);
#else
const char *argv[] = { "xdg-open", path.data(), nullptr };
const char* argv[] = { "xdg-open", path.string().c_str(), nullptr };
desktop_execute(argv);
#endif
}
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
#ifdef __linux__
namespace {
wxExecuteEnv get_appimage_exec_env()
{
// If we're running in an AppImage container, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxEnvVariableHashMap env_vars;
wxGetEnvMap(&env_vars);
@ -513,13 +525,87 @@ void desktop_open_datadir_folder()
// set it as CWD for the child process:
exec_env.cwd = std::move(owd);
}
return exec_env;
}
} // namespace
void desktop_execute(const char* argv[])
{
if (sizeof(argv) == 0)
return;
// Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxExecuteEnv exec_env = get_appimage_exec_env();
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
} else {
}
else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, nullptr);
}
#endif
}
void desktop_execute_get_result(wxString command, wxArrayString& output)
{
output.Clear();
//Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
// because they may mess up the environment expected by the file manager.
// Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
if (wxGetEnv("APPIMAGE", nullptr)) {
// We're running from AppImage
wxExecuteEnv exec_env = get_appimage_exec_env();
::wxExecute(command, output, 0, &exec_env);
} else {
// Looks like we're NOT running from AppImage, we'll make no changes to the environment.
::wxExecute(command, output);
}
}
#endif // __linux__
} }
#ifdef _WIN32
bool create_process(const boost::filesystem::path& path, const std::wstring& cmd_opt, std::string& error_msg)
{
// find updater exe
if (boost::filesystem::exists(path)) {
// Using quoted string as mentioned in CreateProcessW docs.
std::wstring wcmd = L"\"" + path.wstring() + L"\"";
if (!cmd_opt.empty())
wcmd += L" " + cmd_opt;
// additional information
STARTUPINFOW si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// start the program up
if (CreateProcessW(NULL, // the path
wcmd.data(), // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
)) {
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
else
error_msg = "CreateProcessW failed to create process " + boost::nowide::narrow(path.wstring());
}
else
error_msg = "Executable doesn't exists. Path: " + boost::nowide::narrow(path.wstring());
return false;
}
#endif //_WIN32
} } // namespaces GUI / Slic3r

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