This commit is contained in:
Vojtech Bubnik 2020-11-20 13:40:40 +01:00
commit d5e6b17d70
67 changed files with 21006 additions and 16685 deletions

File diff suppressed because it is too large Load diff

View file

@ -5,21 +5,13 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Poedit 2.4.1\n"
"X-Generator: Poedit 2.4.2\n"
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: Oleksandra Iushchenko <yusanka@gmail.com>\n"
"Last-Translator: \n"
"Language-Team: \n"
#: src/slic3r/GUI/MainFrame.cpp:166
msgid " - Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"
msgstr "- Nezapomeňte zkontrolovat aktualizace na https://github.com/prusa3d/PrusaSlicer/releases"
#: src/slic3r/GUI/MainFrame.cpp:1573
msgid " was successfully sliced."
msgstr " byl úspěšně slicován."
#: src/slic3r/GUI/Tab.cpp:4124
msgid ""
"\"%1%\" is disabled because \"%2%\" is on in \"%3%\" category.\n"
@ -50,6 +42,10 @@ msgstr "%1% Přednastavení"
msgid "%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."
msgstr "%1% tiskárna byla aktivní v době, kdy byly pořízeny kroky Zpět / Vpřed. Přepnutí na tiskárnu %1% vyžaduje opětovné načtení předvoleb %1%."
#: src/slic3r/GUI/MainFrame.cpp:1585
msgid "%1% was successfully sliced."
msgstr "%1% byl úspěšně naslicován."
#: src/libslic3r/Print.cpp:1400
msgid "%1%=%2% mm is too low to be printable at a layer height %3% mm"
msgstr "%1%=%2% mm je příliš nízké na to, aby bylo možné tisknout ve výšce vrstvy %3% mm"
@ -98,6 +94,11 @@ msgstr "%s &Webová stránka"
msgid "%s - BREAKING CHANGE"
msgstr "%s - ZLOMOVÁ ZMĚNA"
#: src/slic3r/GUI/Plater.cpp:1410
#, c-format
msgid "%s - Drop project file"
msgstr "%s - Otevírání projektu"
#: src/slic3r/GUI/UpdateDialogs.cpp:211
#, c-format
msgid "%s configuration is incompatible"
@ -395,7 +396,7 @@ msgstr "Obecným pravidlem je 60 °C pro PLA a 110 °C pro ABS. Zadejte nula, po
#: src/slic3r/GUI/GLCanvas3D.cpp:634
msgid "A toolpath outside the print area was detected."
msgstr "Byla detekována cesta mimo tiskovou oblast"
msgstr "Byla detekována cesta mimo tiskovou oblast."
#: src/slic3r/GUI/AboutDialog.cpp:212 src/slic3r/GUI/AboutDialog.cpp:215
#, c-format
@ -428,6 +429,10 @@ msgstr "Přesnost"
msgid "Accurate"
msgstr "Přesné"
#: src/slic3r/GUI/Plater.cpp:1423
msgid "Action"
msgstr "Akce"
#: src/slic3r/GUI/ConfigSnapshotDialog.cpp:78
msgid "Activate"
msgstr "Aktivovat"
@ -728,10 +733,6 @@ msgstr "Všechna gizma: Rotace - levé talčítko myši; Posun - pravé tlačít
msgid "All installed printers are compatible with the selected filament."
msgstr "Všechny instalované tiskárny jsou kompatibilní s vybraným filamentem."
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:737
msgid "All modified options will be reverted."
msgstr "Všechny upravené možnosti budou vráceny."
#: src/libslic3r/Print.cpp:1245
msgid "All objects are outside of the print volume."
msgstr "Všechny objekty jsou mimo tiskový prostor."
@ -740,6 +741,10 @@ msgstr "Všechny objekty jsou mimo tiskový prostor."
msgid "All objects will be removed, continue?"
msgstr "Všechny objekty budou odebrány, pokračovat?"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:737
msgid "All settings changes will be discarded."
msgstr "Všechny změny v nastavení budou zahozeny."
#: src/slic3r/GUI/ConfigWizard.cpp:307
msgid "All standard"
msgstr "Všechny běžné"
@ -987,6 +992,10 @@ msgstr "Automatické aktualizace"
msgid "Automatically repair an STL file"
msgstr "Automaticky opravit STL soubor"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:129
msgid "Autoset by angle"
msgstr "Automaticky podle úhlu"
#: src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp:233
msgid "Autoset custom supports"
msgstr "Automatické nastavení podpěr"
@ -1749,7 +1758,9 @@ msgstr "Kopírování dočasného G-codu do výstupního G-codu selhalo"
msgid ""
"Copying of the temporary G-code to the output G-code failed. Maybe the SD card is write locked?\n"
"Error message: %1%"
msgstr "Kopírování dočasného G-codu do výstupního G-codu se nezdařilo. Není SD karta chráněná proti zápisu?"
msgstr ""
"Kopírování dočasného G-codu do výstupního G-codu se nezdařilo. Není SD karta chráněná proti zápisu?\n"
"Chybová hláška: %1%"
#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:147
msgid "Copying of the temporary G-code to the output G-code failed. There might be problem with target device, please try exporting again or using different device. The corrupted output G-code is at %1%.tmp."
@ -2394,6 +2405,10 @@ msgstr "Neuspořádávat"
msgid "Don't notify about new releases any more"
msgstr "Neupozorňovat na nové verze"
#: src/slic3r/GUI/Plater.cpp:1431
msgid "Don't show again"
msgstr "Znovu nezobrazovat"
#: src/libslic3r/PrintConfig.cpp:403
msgid "Don't support bridges"
msgstr "Nevytvářet podpěry pod mosty"
@ -2534,6 +2549,10 @@ msgstr "Nadzvednutí objektu je příliš malé. Pomocí funkce „Podložka oko
msgid "Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute intervals into the G-code to let the firmware show accurate remaining time. As of now only the Prusa i3 MK3 firmware recognizes M73. Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode."
msgstr "Vkládání M73 P[počet vytištěných procent] R[zbývající čas v minutách] v 1 minutových intervalech do G-codu, aby firmware ukázal přesný zbývající čas. M73 nyní rozpoznává pouze firmware tiskárny Prusa i3 MK3. Firmware i3 MK3 také podporuje M73 Qxx Sxx pro tichý režim."
#: src/libslic3r/PrintConfig.cpp:1217
msgid "Emit to G-code"
msgstr "Emitivat do G-codu"
#: src/libslic3r/GCode.cpp:622
msgid "Empty layers detected, the output would not be printable."
msgstr "Byly detekovány prázdné vrstvy, model by nebylo možné vytisknout."
@ -2565,7 +2584,7 @@ msgstr "Zapnout ironing"
#: src/libslic3r/PrintConfig.cpp:1125
msgid "Enable ironing of the top layers with the hot print head for smooth surface"
msgstr "Pro hladké vrchní vrstvy povolte ironing pomocí ohřáté tiskové hlavy."
msgstr "Pro hladké vrchní vrstvy povolte ironing pomocí ohřáté tiskové hlavy"
#: src/libslic3r/PrintConfig.cpp:2009
msgid "Enable support material generation."
@ -2975,10 +2994,6 @@ msgstr "Exportovat vybrané objekty jako STL soubor"
msgid "Export to SD card / Flash drive"
msgstr "Export na SD kartu / Flash disk"
#: src/slic3r/GUI/Plater.cpp:755
msgid "Export to SD card / Flash drive "
msgstr "Export na SD kartu / Flash disk"
#: src/slic3r/GUI/MainFrame.cpp:1090 src/slic3r/GUI/MainFrame.cpp:1395
msgid "Export toolpaths as OBJ"
msgstr "Exportovat trasy extruderu jako OBJ"
@ -3188,7 +3203,7 @@ msgstr "Typ"
#: src/slic3r/GUI/GUI_Preview.cpp:293 src/slic3r/GUI/GUI_Preview.cpp:295
#: src/slic3r/GUI/GUI_Preview.cpp:316
msgid "Feature types"
msgstr "Typy extruzí"
msgstr "Typy extrudování"
#: src/slic3r/GUI/ConfigWizard.cpp:1926
msgid "FFF Technology Printers"
@ -3983,7 +3998,7 @@ msgstr "Pokud je tato volba povolena, bude 3D scéna vykreslena v rozlišení Re
#: src/slic3r/GUI/Preferences.cpp:215
msgid "If enabled, the button for the collapse sidebar will be appeared in top right corner of the 3D Scene"
msgstr "Pokud je povoleno, bude v pravém horním rohu 3D scény zobrazeno tlačítko pro ovládání bočního panelu."
msgstr "Pokud je povoleno, bude v pravém horním rohu 3D scény zobrazeno tlačítko pro ovládání bočního panelu"
#: src/libslic3r/PrintConfig.cpp:3698
msgid "If enabled, the command line arguments are sent to an existing instance of GUI PrusaSlicer, or an existing PrusaSlicer window is activated. Overrides the \"single_instance\" configuration value from application preferences."
@ -4073,6 +4088,10 @@ msgstr "Pokud firmware nezpracovává umístění extruderu správně, potřebuj
msgid "If your firmware requires relative E values, check this, otherwise leave it unchecked. Most firmwares use absolute values."
msgstr "Pokud váš firmware vyžaduje relativní hodnoty E, zaškrtněte toto, jinak nechte nezaškrtnuté. Většina firmwarů používá absolutní hodnoty."
#: src/libslic3r/PrintConfig.cpp:1219
msgid "Ignore"
msgstr "Ignorovat"
#: src/libslic3r/PrintConfig.cpp:3684
msgid "Ignore non-existent config files"
msgstr "Ignorovat neexistující konfigurační soubory"
@ -4098,9 +4117,17 @@ msgstr "Načíst konfiguraci z &projektu"
msgid "Import Config from ini/amf/3mf/gcode"
msgstr "Načíst konfiguraci ze souboru ini/amf/3mf/gcode"
#: src/slic3r/GUI/Plater.cpp:1419
msgid "Import config only"
msgstr "Importovat pouze konfiguraci"
#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:39
msgid "Import file: "
msgstr "Importovat soubor:"
msgid "Import file"
msgstr "Importovat soubor"
#: src/slic3r/GUI/Plater.cpp:1418
msgid "Import geometry only"
msgstr "Importovat pouze modely"
#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:46
msgid "Import model and profile"
@ -4566,10 +4593,6 @@ msgstr "Vrchních"
msgid "Layout Options"
msgstr "Možnosti rozložení"
#: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:233
msgid "Least supports"
msgstr "Nejméně podpěr"
#: src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:48
msgid "Leaving Paint-on supports"
msgstr "Opuštění Malování podpěr"
@ -4670,14 +4693,6 @@ msgstr "Načíst konfiguraci ze zadaného souboru. Může být použito vícekr
msgid "Load exported configuration file"
msgstr "Načíst exportovaný konfigurační soubor"
#: src/slic3r/GUI/Plater.cpp:1436
msgid "Load File"
msgstr "Načtení souboru"
#: src/slic3r/GUI/Plater.cpp:1440
msgid "Load Files"
msgstr "Naštení souborů"
#: src/slic3r/GUI/GUI_ObjectList.cpp:2038
msgid "Load Part"
msgstr "Přidání části"
@ -4710,9 +4725,9 @@ msgstr "Načteno"
msgid "Loading"
msgstr "Načítání"
#: src/slic3r/GUI/GUI_App.cpp:759
msgid "Loading configuration..."
msgstr "Načítání konfigurace ..."
#: src/slic3r/GUI/GUI_App.cpp:797
msgid "Loading configuration"
msgstr "Načítání konfigurace"
#: src/slic3r/GUI/Plater.cpp:2226
msgid "Loading file"
@ -5690,7 +5705,7 @@ msgstr "Teplota trysky"
#: src/libslic3r/PrintConfig.cpp:2198
msgid "Nozzle temperature for layers after the first one. Set this to zero to disable temperature control commands in the output G-code."
msgstr "Teplota trysky pro od druhé vrstvy dále. Nastavte tuto hodnotu na nulu, abyste zakázali příkazy pro řízení teploty ve výstupním G-codu."
msgstr "Teplota trysky od druhé vrstvy dále. Nastavte tuto hodnotu na nulu, abyste zakázali příkazy pro řízení teploty ve výstupním G-codu."
#: src/libslic3r/PrintConfig.cpp:961
msgid "Nozzle temperature for the first layer. If you want to control temperature manually during print, set this to zero to disable temperature control commands in the output G-code."
@ -5882,6 +5897,10 @@ msgstr "Otevře novou instanci PrusaSliceru"
msgid "Open a project file"
msgstr "Otevřít soubor s projektem"
#: src/slic3r/GUI/Plater.cpp:1417
msgid "Open as project"
msgstr "Otevřít jako projekt"
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:330
msgid "Open CA certificate file"
msgstr "Otevřít soubor s certifikátem CA"
@ -6338,9 +6357,9 @@ msgstr "Preferovaný směr švu - rozkmit"
msgid "Preparing infill"
msgstr "Příprava výplně"
#: src/slic3r/GUI/GUI_App.cpp:895
msgid "Preparing settings tabs..."
msgstr "Příprava karet s nastavením..."
#: src/slic3r/GUI/GUI_App.cpp:855
msgid "Preparing settings tabs"
msgstr "Příprava karet s nastavením"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1009
msgid "Preset \"%1%\" has the following unsaved changes:"
@ -6662,10 +6681,6 @@ msgstr "Kvalita (pomalejší slicing)"
msgid "Quality / Speed"
msgstr "Kvalita / Rychlost"
#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:56
msgid "Quality: "
msgstr "Kvalita:"
#: src/slic3r/GUI/Jobs/SLAImportJob.cpp:61
msgid "Quick"
msgstr "Rychlé"
@ -6693,7 +6708,7 @@ msgstr "Ukončit %s"
#: src/slic3r/GUI/GUI_App.cpp:396
msgid "Quit, I will move my data now"
msgstr "Zavřít aplikaci, přesunu si svá data."
msgstr "Zavřít aplikaci, přesunu si svá data"
#: src/slic3r/GUI/GLCanvas3D.cpp:280 src/libslic3r/PrintConfig.cpp:547
msgid "Radius"
@ -6880,6 +6895,10 @@ msgstr "Zapamatovat moji volbu"
msgid "Remember output directory"
msgstr "Pamatovat si výstupní složku"
#: src/slic3r/GUI/MainFrame.cpp:166
msgid "Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"
msgstr "Nezapomeňte zkontrolovat aktualizace na https://github.com/prusa3d/PrusaSlicer/releases"
#: src/slic3r/GUI/Tab.cpp:3386
msgid "remove"
msgstr "odebrat"
@ -7345,7 +7364,7 @@ msgstr "Uložit SL1 soubor jako:"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:744
msgid "Save the selected options to preset \"%1%\"."
msgstr "Uložte vybraná nastaneví do přednastavení \"%1%\"."
msgstr "Uloží vybraná nastaneví do přednastavení \"%1%\"."
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:740
msgid "Save the selected options."
@ -7470,6 +7489,10 @@ msgstr "Vybrat všechny body"
msgid "Select all standard printers"
msgstr "Vybrat všechny standardní tiskárny"
#: src/slic3r/GUI/Plater.cpp:1422
msgid "Select an action to apply to the file"
msgstr "Vyberte jak chcete na soubor otevřít"
#: src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp:1215
msgid "Select by rectangle"
msgstr "Označit obdélníkovým výběrem myši"
@ -7616,10 +7639,6 @@ msgstr "Odeslat k tisku stávající plochu jako G-code"
msgid "Send to printer"
msgstr "Odeslat do tiskárny"
#: src/slic3r/GUI/Plater.cpp:753
msgid "Send to printer "
msgstr "Odeslat do tiskárny"
#: src/slic3r/GUI/GLCanvas3D.cpp:1312
msgid "Seq."
msgstr "Sekv."
@ -7861,6 +7880,10 @@ msgstr "Zobrazit okno o Slic3ru"
msgid "Show advanced settings"
msgstr "Zobrazit rozšířená nastavení"
#: src/slic3r/GUI/Preferences.cpp:120
msgid "Show drop project dialog"
msgstr "Zobrazit dialogové okno při přetažení projektu"
#: src/slic3r/GUI/PrintHostDialogs.cpp:157
msgid "Show error message"
msgstr "Zobrazit chybovou hlášku"
@ -8522,10 +8545,6 @@ msgstr "Úspěch!"
msgid "Successfully unmounted. The device %s(%s) can now be safely removed from the computer."
msgstr "Odpojení proběhlo úspěšné. Zařízení %s(%s) lze nyní bezpečně odebrat z počítače."
#: src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp:234
msgid "Suface quality"
msgstr "Kvalita povrchu"
#: src/slic3r/GUI/PresetHints.cpp:202
msgid "support"
msgstr "podpěry"
@ -9159,9 +9178,9 @@ msgstr "Čistící věž je podporována pouze v případě, že všechny extrud
msgid "The Wipe tower is only supported if all objects have the same variable layer height"
msgstr "Čistící věž je podporována pouze v případě, že všechny objekty mají stejnou variabilní výšku vrstvy"
#: src/slic3r/GUI/Plater.cpp:3543
msgid "There are active warnings concerning sliced models:\n"
msgstr "Varování týkající se slicovaných modelů:\n"
#: src/slic3r/GUI/Plater.cpp:3563
msgid "There are active warnings concerning sliced models:"
msgstr "Varování týkající se slicovaných modelů:"
#: src/libslic3r/SLAPrintSteps.cpp:619
msgid "There are unprintable objects. Try to adjust support settings to make the objects printable."
@ -9246,7 +9265,7 @@ msgstr "Toto experimentální nastavení používá příkazy G10 a G11, aby si
#: src/libslic3r/PrintConfig.cpp:2319
msgid "This experimental setting uses outputs the E values in cubic millimeters instead of linear millimeters. If your firmware doesn't already know filament diameter(s), you can put commands like 'M200 D[filament_diameter_0] T0' in your start G-code in order to turn volumetric mode on and use the filament diameter associated to the filament selected in Slic3r. This is only supported in recent Marlin."
msgstr "Toto experimentální nastavení používá výstupní hodnoty E v kubických milimetrech místo lineárních milimetrů. Pokud firmware dosud nezná průměr (průměry) filamentu, můžete v počátečním G-code zadat příkazy jako “M200 D [filament_diameter_0] T0”, pro zapnutí volumetrického režimu a použití průměru filamentu přidruženého k vybranému filamentu ve Slic3ru. Toto je podporováno pouze v posledních verzích firmwaru Marlin.\n"
msgstr "Toto experimentální nastavení používá výstupní hodnoty E v kubických milimetrech místo lineárních milimetrů. Pokud firmware dosud nezná průměr (průměry) filamentu, můžete v počátečním G-code zadat příkazy jako “M200 D [filament_diameter_0] T0”, pro zapnutí volumetrického režimu a použití průměru filamentu přidruženého k vybranému filamentu ve Slic3ru. Toto je podporováno pouze v posledních verzích firmwaru Marlin."
#: src/slic3r/GUI/GUI_ObjectList.cpp:4459
msgid "This extruder will be set for selected items"
@ -9324,7 +9343,7 @@ msgstr "Toto nastavení přemístí trysku při retrakci, aby se minimalizovalo
#: src/libslic3r/PrintConfig.cpp:1961
msgid "This G-code will be used as a code for the color change"
msgstr "Tento G-code bude použit jako kód pro změnu barvy."
msgstr "Tento G-code bude použit jako kód pro změnu barvy"
#: src/libslic3r/PrintConfig.cpp:1970
msgid "This G-code will be used as a code for the pause print"
@ -9888,6 +9907,10 @@ msgstr "Použít retrakce z firmwaru"
msgid "Use for search"
msgstr "Použit pro vyhledávání"
#: src/libslic3r/PrintConfig.cpp:1218
msgid "Use for time estimate"
msgstr "Použít pro odhad času"
#: src/slic3r/GUI/PrintHostDialogs.cpp:42
msgid "Use forward slashes ( / ) as a directory separator if needed."
msgstr "Pokud je to nutné, použijte pro oddělení složek lomítko ( / )."
@ -10133,6 +10156,10 @@ msgstr "Co chcete udělat s přednastavením „% 1%“ po uložení?"
msgid "When checked, the print and filament presets are shown in the preset editor even if they are marked as incompatible with the active printer"
msgstr "Pokud je zaškrtnuto, přednastavení tisku a filamentu se zobrazují v editoru přednastavení, i když jsou označeny jako nekompatibilní s aktivní tiskárnou"
#: src/slic3r/GUI/Preferences.cpp:122
msgid "When checked, whenever dragging and dropping a project file on the application, shows a dialog asking to select the action to take on the file to load."
msgstr "Je-li zaškrtnuto, při každém přetažení souboru s projektem do aplikace se zobrazí dialogové okno s výzvou k výběru akce, kterou se má soubor načíst."
#: src/slic3r/GUI/Preferences.cpp:156
msgid "When closing the application, always ask for unsaved changes"
msgstr "Při zavírání aplikace vždy ptát na neuložené změny"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -666,14 +666,14 @@ deretract_speed = 40
retract_before_wipe = 70%
default_print_profile = 0.16mm OPTIMAL @CREALITY
default_filament_profile = Creality PLA @CREALITY
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0.0\nG1 Y190 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)} F600{endif} ; Move print head up\nG1 X5 Y170 F3000 ; present print\n{if layer_z < max_print_height-10}G1 Z{z_offset+min(layer_z+70, max_print_height-10)} F600{endif} ; Move print head up\nM84 X Y E ; disable motors
[printer:*fastabl*]
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0.0\nG1 Y190 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
[printer:*slowabl*]
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0.0\nG1 Y190 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S150 ; set extruder temp for auto bed leveling\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nG28 ; home all\nG29 ; auto bed levelling\nG1 Z50 F240\nG1 X2 Y10 F3000\nM104 S[first_layer_temperature] ; set extruder temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG1 Z0.28 F240\nG92 E0\nG1 Y190 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
[printer:*invertedz*]
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)} F600{endif} ; Move print bed down\nG1 X50 Y50 F3000 ; present print\n{if layer_z < max_print_height-10}G1 Z{z_offset+max_print_height-10} F600{endif} ; Move print bed down\nM84 X Y E ; disable motors
@ -706,7 +706,7 @@ bed_shape = 0x0,150x0,150x150,0x150
printer_model = ENDER2
printer_notes = Don't remove the following keywords! These keywords are used in the "compatible printer" condition of the print and filament profiles to link the particular print and filament profiles to this printer profile.\nPRINTER_VENDOR_CREALITY\nPRINTER_MODEL_ENDER2\nPRINTER_HAS_BOWDEN
max_print_height = 200
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0.0\nG1 X15 Y135 E15.0 F1500.0 ; intro line\nG1 X2.3 F5000\nG1 Y10 E15.0 F1200.0 ; intro line\nG92 E0.0
start_gcode = G90 ; use absolute coordinates\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all\nG1 Z2 F240\nG1 X2 Y10 F3000\nG1 Z0.28 F240\nG92 E0\nG1 X15 Y135 E15 F1500 ; intro line\nG1 X2.3 F5000\nG92 E0\nG1 Y10 E15 F1200 ; intro line\nG92 E0
end_gcode = M104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+5, max_print_height)} F600{endif} ; Move print head up\nG1 X5 Y140 F3000 ; present print\n{if layer_z < max_print_height}G1 Z{z_offset+min(layer_z+30, max_print_height)} F600{endif} ; Move print head up\nM84 X Y E ; disable motors
[printer:Creality CR-10 Mini]

View file

@ -7,6 +7,7 @@
#include <libnest2d/optimizers/nlopt/subplex.hpp>
#include <libnest2d/placers/nfpplacer.hpp>
#include <libnest2d/selections/firstfit.hpp>
#include <libnest2d/utils/rotcalipers.hpp>
#include <numeric>
#include <ClipperUtils.hpp>
@ -83,7 +84,7 @@ const double BIG_ITEM_TRESHOLD = 0.02;
// Fill in the placer algorithm configuration with values carefully chosen for
// Slic3r.
template<class PConf>
void fill_config(PConf& pcfg) {
void fill_config(PConf& pcfg, const ArrangeParams &params) {
// Align the arranged pile into the center of the bin
pcfg.alignment = PConf::Alignment::CENTER;
@ -93,14 +94,17 @@ void fill_config(PConf& pcfg) {
// TODO cannot use rotations until multiple objects of same geometry can
// handle different rotations.
pcfg.rotations = { 0.0 };
if (params.allow_rotations)
pcfg.rotations = {0., PI / 2., PI, 3. * PI / 2. };
else
pcfg.rotations = {0.};
// The accuracy of optimization.
// Goes from 0.0 to 1.0 and scales performance as well
pcfg.accuracy = 0.65f;
pcfg.accuracy = params.accuracy;
// Allow parallel execution.
pcfg.parallel = true;
pcfg.parallel = params.parallel;
}
// Apply penalty to object function result. This is used only when alignment
@ -277,10 +281,10 @@ protected:
if (result.empty())
score = 0.50 * dist + 0.50 * density;
else
score = R * 0.60 * dist +
(1.0 - R) * 0.20 * density +
0.20 * alignment_score;
// Let the density matter more when fewer objects remain
score = 0.50 * dist + (1.0 - R) * 0.20 * density +
0.30 * alignment_score;
break;
}
case LAST_BIG_ITEM: {
@ -304,15 +308,15 @@ protected:
public:
AutoArranger(const TBin & bin,
Distance dist,
const ArrangeParams &params,
std::function<void(unsigned)> progressind,
std::function<bool(void)> stopcond)
: m_pck(bin, dist)
: m_pck(bin, params.min_obj_distance)
, m_bin(bin)
, m_bin_area(sl::area(bin))
, m_norm(std::sqrt(m_bin_area))
{
fill_config(m_pconf);
fill_config(m_pconf, params);
// Set up a callback that is called just before arranging starts
// This functionality is provided by the Nester class (m_pack).
@ -349,12 +353,6 @@ public:
m_pck.configure(m_pconf);
}
AutoArranger(const TBin & bin,
std::function<void(unsigned)> progressind,
std::function<bool(void)> stopcond)
: AutoArranger{bin, 0 /* no min distance */, progressind, stopcond}
{}
template<class It> inline void operator()(It from, It to) {
m_rtree.clear();
@ -452,12 +450,18 @@ template<class Bin> void remove_large_items(std::vector<Item> &items, Bin &&bin)
++it : it = items.erase(it);
}
template<class S> Radians min_area_boundingbox_rotation(const S &sh)
{
return minAreaBoundingBox<S, TCompute<S>, boost::rational<LargeInt>>(sh)
.angleToX();
}
template<class BinT> // Arrange for arbitrary bin type
void _arrange(
std::vector<Item> & shapes,
std::vector<Item> & excludes,
const BinT & bin,
const ArrangeParams & params,
const ArrangeParams &params,
std::function<void(unsigned)> progressfn,
std::function<bool()> stopfn)
{
@ -467,11 +471,10 @@ void _arrange(
auto corrected_bin = bin;
sl::offset(corrected_bin, md);
AutoArranger<BinT> arranger{corrected_bin, progressfn, stopfn};
arranger.config().accuracy = params.accuracy;
arranger.config().parallel = params.parallel;
ArrangeParams mod_params = params;
mod_params.min_obj_distance = 0;
AutoArranger<BinT> arranger{corrected_bin, mod_params, progressfn, stopfn};
auto infl = coord_t(std::ceil(params.min_obj_distance / 2.0));
for (Item& itm : shapes) itm.inflate(infl);
@ -487,6 +490,13 @@ void _arrange(
for (auto &itm : shapes ) inp.emplace_back(itm);
for (auto &itm : excludes) inp.emplace_back(itm);
// Use the minimum bounding box rotation as a starting point.
// TODO: This only works for convex hull. If we ever switch to concave
// polygon nesting, a convex hull needs to be calculated.
if (params.allow_rotations)
for (auto &itm : shapes)
itm.rotation(min_area_boundingbox_rotation(itm.rawShape()));
arranger(inp.begin(), inp.end());
for (Item &itm : inp) itm.inflate(-infl);
}
@ -556,28 +566,35 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
outp.back().priority(arrpoly.priority);
}
template<class Fn> auto call_with_bed(const Points &bed, Fn &&fn)
{
if (bed.empty())
return fn(InfiniteBed{});
else if (bed.size() == 1)
return fn(InfiniteBed{bed.front()});
else {
auto bb = BoundingBox(bed);
CircleBed circ = to_circle(bb.center(), bed);
auto parea = poly_area(bed);
if ((1.0 - parea / area(bb)) < 1e-3)
return fn(bb);
else if (!std::isnan(circ.radius()))
return fn(circ);
else
return fn(Polygon(bed));
}
}
template<>
void arrange(ArrangePolygons & items,
const ArrangePolygons &excludes,
const Points & bed,
const ArrangeParams & params)
{
if (bed.empty())
arrange(items, excludes, InfiniteBed{}, params);
else if (bed.size() == 1)
arrange(items, excludes, InfiniteBed{bed.front()}, params);
else {
auto bb = BoundingBox(bed);
CircleBed circ = to_circle(bb.center(), bed);
auto parea = poly_area(bed);
if ((1.0 - parea / area(bb)) < 1e-3)
arrange(items, excludes, bb, params);
else if (!std::isnan(circ.radius()))
arrange(items, excludes, circ, params);
else
arrange(items, excludes, Polygon(bed), params);
}
call_with_bed(bed, [&](const auto &bin) {
arrange(items, excludes, bin, params);
});
}
template<class BedT>

View file

@ -78,6 +78,8 @@ struct ArrangeParams {
/// Allow parallel execution.
bool parallel = true;
bool allow_rotations = false;
/// Progress indicator callback called when an object gets packed.
/// The unsigned argument is the number of items remaining to pack.

View file

@ -1858,7 +1858,7 @@ void GCode::process_layer(
std::string gcode;
// add tag for processor
gcode += "; " + GCodeProcessor::Layer_Change_Tag + "\n";
gcode += ";" + GCodeProcessor::Layer_Change_Tag + "\n";
// export layer z
char buf[64];
sprintf(buf, ";Z:%g\n", print_z);

View file

@ -393,7 +393,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename)
auto is_temporary_decoration = [](const std::string& gcode_line) {
// remove trailing '\n'
std::string line = gcode_line.substr(0, gcode_line.length() - 1);
if (line == "; " + Layer_Change_Tag)
if (line == ";" + Layer_Change_Tag)
return true;
else
return false;
@ -817,6 +817,10 @@ void GCodeProcessor::process_file(const std::string& filename, bool apply_postpr
update_estimated_times_stats();
// ensure at least one (default) color is defined
if (m_result.extruder_colors.empty())
m_result.extruder_colors.push_back("#FF8000");
// post-process to add M73 lines into the gcode
if (apply_postprocess)
m_time_processor.post_process(filename);

View file

@ -1840,8 +1840,11 @@ namespace PresetUtils {
{
std::string out;
const VendorProfile::PrinterModel* pm = PresetUtils::system_printer_model(preset);
if (pm != nullptr && !pm->bed_model.empty())
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_model;
if (pm != nullptr && !pm->bed_model.empty()) {
out = Slic3r::data_dir() + "/vendor/" + preset.vendor->id + "/" + pm->bed_model;
if (!boost::filesystem::exists(boost::filesystem::path(out)))
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_model;
}
return out;
}
@ -1849,8 +1852,11 @@ namespace PresetUtils {
{
std::string out;
const VendorProfile::PrinterModel* pm = PresetUtils::system_printer_model(preset);
if (pm != nullptr && !pm->bed_texture.empty())
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_texture;
if (pm != nullptr && !pm->bed_texture.empty()) {
out = Slic3r::data_dir() + "/vendor/" + preset.vendor->id + "/" + pm->bed_texture;
if (!boost::filesystem::exists(boost::filesystem::path(out)))
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_texture;
}
return out;
}
} // namespace PresetUtils

View file

@ -350,6 +350,7 @@ struct SLAPrintStatistics
size_t fast_layers_count;
double total_cost;
double total_weight;
std::vector<double> layers_times;
// Config with the filled in print statistics.
DynamicConfig config() const;
@ -366,6 +367,7 @@ struct SLAPrintStatistics
fast_layers_count = 0;
total_cost = 0.;
total_weight = 0.;
layers_times.clear();
}
};

View file

@ -671,6 +671,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
double models_volume(0.0);
double estim_time(0.0);
std::vector<double> layers_times;
layers_times.reserve(printer_input.size());
size_t slow_layers = 0;
size_t fast_layers = 0;
@ -688,7 +690,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
// write vars
&mutex, &models_volume, &supports_volume, &estim_time, &slow_layers,
&fast_layers, &fade_layer_time](size_t sliced_layer_cnt)
&fast_layers, &fade_layer_time, &layers_times](size_t sliced_layer_cnt)
{
PrintLayer &layer = m_print->m_printer_input[sliced_layer_cnt];
@ -775,20 +777,21 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
else
slow_layers++;
// Calculation of the printing time
double layer_times = 0.0;
if (sliced_layer_cnt < 3)
estim_time += init_exp_time;
else if (fade_layer_time > exp_time)
{
layer_times += init_exp_time;
else if (fade_layer_time > exp_time) {
fade_layer_time -= delta_fade_time;
estim_time += fade_layer_time;
layer_times += fade_layer_time;
}
else
estim_time += exp_time;
estim_time += tilt_time;
layer_times += exp_time;
layer_times += tilt_time;
layers_times.push_back(layer_times);
estim_time += layer_times;
}
};
@ -804,8 +807,10 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
// A layers count o the highest object
if (printer_input.size() == 0)
print_statistics.estimated_print_time = std::nan("");
else
else {
print_statistics.estimated_print_time = estim_time;
print_statistics.layers_times = layers_times;
}
print_statistics.fast_layers_count = fast_layers;
print_statistics.slow_layers_count = slow_layers;

View file

@ -71,6 +71,7 @@
#define ENABLE_2_3_0_ALPHA4 1
#define ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS (1 && ENABLE_GCODE_VIEWER && ENABLE_2_3_0_ALPHA4)
#define ENABLE_SHOW_OPTION_POINT_LAYERS (1 && ENABLE_GCODE_VIEWER && ENABLE_2_3_0_ALPHA4)
#endif // _prusaslicer_technologies_h_

View file

@ -162,6 +162,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Jobs/ArrangeJob.cpp
GUI/Jobs/RotoptimizeJob.hpp
GUI/Jobs/RotoptimizeJob.cpp
GUI/Jobs/FillBedJob.hpp
GUI/Jobs/FillBedJob.cpp
GUI/Jobs/SLAImportJob.hpp
GUI/Jobs/SLAImportJob.cpp
GUI/Jobs/ProgressIndicator.hpp

View file

@ -5,24 +5,18 @@
#include "libslic3r/Polygon.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/BoundingBox.hpp"
#if ENABLE_GCODE_VIEWER
#include "libslic3r/Geometry.hpp"
#endif // ENABLE_GCODE_VIEWER
#include "GUI_App.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "GLCanvas3D.hpp"
#if ENABLE_GCODE_VIEWER
#include "3DScene.hpp"
#endif // ENABLE_GCODE_VIEWER
#include <GL/glew.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/operations.hpp>
#if ENABLE_GCODE_VIEWER
#include <boost/log/trivial.hpp>
#endif // ENABLE_GCODE_VIEWER
static const float GROUND_Z = -0.02f;
@ -121,43 +115,19 @@ const float* GeometryBuffer::get_vertices_data() const
return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr;
}
#if ENABLE_GCODE_VIEWER
const float Bed3D::Axes::DefaultStemRadius = 0.5f;
const float Bed3D::Axes::DefaultStemLength = 25.0f;
const float Bed3D::Axes::DefaultTipRadius = 2.5f * Bed3D::Axes::DefaultStemRadius;
const float Bed3D::Axes::DefaultTipLength = 5.0f;
#else
const double Bed3D::Axes::Radius = 0.5;
const double Bed3D::Axes::ArrowBaseRadius = 2.5 * Bed3D::Axes::Radius;
const double Bed3D::Axes::ArrowLength = 5.0;
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Bed3D::Axes::set_stem_length(float length)
{
m_stem_length = length;
m_arrow.reset();
}
#else
Bed3D::Axes::Axes()
: origin(Vec3d::Zero())
, length(25.0 * Vec3d::Ones())
{
m_quadric = ::gluNewQuadric();
if (m_quadric != nullptr)
::gluQuadricDrawStyle(m_quadric, GLU_FILL);
}
Bed3D::Axes::~Axes()
{
if (m_quadric != nullptr)
::gluDeleteQuadric(m_quadric);
}
#endif // ENABLE_GCODE_VIEWER
void Bed3D::Axes::render() const
{
#if ENABLE_GCODE_VIEWER
auto render_axis = [this](const Transform3f& transform) {
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(transform.data()));
@ -193,56 +163,8 @@ void Bed3D::Axes::render() const
shader->stop_using();
glsafe(::glDisable(GL_DEPTH_TEST));
#else
if (m_quadric == nullptr)
return;
glsafe(::glEnable(GL_DEPTH_TEST));
glsafe(::glEnable(GL_LIGHTING));
// x axis
glsafe(::glColor3fv(AXES_COLOR[0]));
glsafe(::glPushMatrix());
glsafe(::glTranslated(origin(0), origin(1), origin(2)));
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
render_axis(length(0));
glsafe(::glPopMatrix());
// y axis
glsafe(::glColor3fv(AXES_COLOR[1]));
glsafe(::glPushMatrix());
glsafe(::glTranslated(origin(0), origin(1), origin(2)));
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
render_axis(length(1));
glsafe(::glPopMatrix());
// z axis
glsafe(::glColor3fv(AXES_COLOR[2]));
glsafe(::glPushMatrix());
glsafe(::glTranslated(origin(0), origin(1), origin(2)));
render_axis(length(2));
glsafe(::glPopMatrix());
glsafe(::glDisable(GL_LIGHTING));
glsafe(::glDisable(GL_DEPTH_TEST));
#endif // !ENABLE_GCODE_VIEWER
}
#if !ENABLE_GCODE_VIEWER
void Bed3D::Axes::render_axis(double length) const
{
::gluQuadricOrientation(m_quadric, GLU_OUTSIDE);
::gluCylinder(m_quadric, Radius, Radius, length, 32, 1);
::gluQuadricOrientation(m_quadric, GLU_INSIDE);
::gluDisk(m_quadric, 0.0, Radius, 32, 1);
glsafe(::glTranslated(0.0, 0.0, length));
::gluQuadricOrientation(m_quadric, GLU_OUTSIDE);
::gluCylinder(m_quadric, ArrowBaseRadius, 0.0, ArrowLength, 32, 1);
::gluQuadricOrientation(m_quadric, GLU_INSIDE);
::gluDisk(m_quadric, 0.0, ArrowBaseRadius, 32, 1);
}
#endif // !ENABLE_GCODE_VIEWER
Bed3D::Bed3D()
: m_type(Custom)
, m_vbo_id(0)
@ -308,13 +230,8 @@ bool Bed3D::set_shape(const Pointfs& shape, const std::string& custom_texture, c
m_model.reset();
// Set the origin and size for rendering the coordinate system axes.
#if ENABLE_GCODE_VIEWER
m_axes.set_origin({ 0.0, 0.0, static_cast<double>(GROUND_Z) });
m_axes.set_stem_length(0.1f * static_cast<float>(m_bounding_box.max_size()));
#else
m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z);
m_axes.length = 0.1 * m_bounding_box.max_size() * Vec3d::Ones();
#endif // ENABLE_GCODE_VIEWER
// Let the calee to update the UI.
return true;
@ -360,7 +277,6 @@ void Bed3D::calc_bounding_boxes() const
m_extended_bounding_box = m_bounding_box;
// extend to contain axes
#if ENABLE_GCODE_VIEWER
m_extended_bounding_box.merge(m_axes.get_origin() + m_axes.get_total_length() * Vec3d::Ones());
m_extended_bounding_box.merge(m_extended_bounding_box.min + Vec3d(-Axes::DefaultTipRadius, -Axes::DefaultTipRadius, m_extended_bounding_box.max(2)));
@ -370,12 +286,6 @@ void Bed3D::calc_bounding_boxes() const
model_bb.translate(m_model_offset);
m_extended_bounding_box.merge(model_bb);
}
#else
m_extended_bounding_box.merge(m_axes.length + Axes::ArrowLength * Vec3d::Ones());
// extend to contain model, if any
if (!m_model.get_filename().empty())
m_extended_bounding_box.merge(m_model.get_transformed_bounding_box());
#endif // ENABLE_GCODE_VIEWER
}
void Bed3D::calc_triangles(const ExPolygon& poly)
@ -414,25 +324,6 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
printf("Unable to create bed grid lines\n");
}
#if !ENABLE_GCODE_VIEWER
static std::string system_print_bed_model(const Preset &preset)
{
std::string out;
const VendorProfile::PrinterModel *pm = PresetUtils::system_printer_model(preset);
if (pm != nullptr && ! pm->bed_model.empty())
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_model;
return out;
}
static std::string system_print_bed_texture(const Preset &preset)
{
std::string out;
const VendorProfile::PrinterModel *pm = PresetUtils::system_printer_model(preset);
if (pm != nullptr && ! pm->bed_texture.empty())
out = Slic3r::resources_dir() + "/profiles/" + preset.vendor->id + "/" + pm->bed_texture;
return out;
}
#endif // !ENABLE_GCODE_VIEWER
std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Pointfs& shape) const
{
@ -442,13 +333,8 @@ std::tuple<Bed3D::EType, std::string, std::string> Bed3D::detect_type(const Poin
while (curr != nullptr) {
if (curr->config.has("bed_shape")) {
if (shape == dynamic_cast<const ConfigOptionPoints*>(curr->config.option("bed_shape"))->values) {
#if ENABLE_GCODE_VIEWER
std::string model_filename = PresetUtils::system_printer_bed_model(*curr);
std::string texture_filename = PresetUtils::system_printer_bed_texture(*curr);
#else
std::string model_filename = system_print_bed_model(*curr);
std::string texture_filename = system_print_bed_texture(*curr);
#endif // ENABLE_GCODE_VIEWER
if (!model_filename.empty() && !texture_filename.empty())
return { System, model_filename, texture_filename };
}
@ -614,11 +500,7 @@ void Bed3D::render_model() const
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
Vec3d shift = m_bounding_box.center();
shift(2) = -0.03;
#if ENABLE_GCODE_VIEWER
m_model_offset = shift;
#else
m_model.set_offset(shift);
#endif // ENABLE_GCODE_VIEWER
// update extended bounding box
calc_bounding_boxes();
@ -628,15 +510,11 @@ void Bed3D::render_model() const
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
if (shader != nullptr) {
shader->start_using();
#if ENABLE_GCODE_VIEWER
shader->set_uniform("uniform_color", m_model_color);
::glPushMatrix();
::glTranslated(m_model_offset(0), m_model_offset(1), m_model_offset(2));
#endif // ENABLE_GCODE_VIEWER
m_model.render();
#if ENABLE_GCODE_VIEWER
::glPopMatrix();
#endif // ENABLE_GCODE_VIEWER
shader->stop_using();
}
}
@ -673,11 +551,7 @@ void Bed3D::render_default(bool bottom) const
if (!has_model && !bottom) {
// draw background
glsafe(::glDepthMask(GL_FALSE));
#if ENABLE_GCODE_VIEWER
glsafe(::glColor4fv(m_model_color.data()));
#else
glsafe(::glColor4f(0.35f, 0.35f, 0.35f, 0.4f));
#endif // ENABLE_GCODE_VIEWER
glsafe(::glNormal3d(0.0f, 0.0f, 1.0f));
glsafe(::glVertexPointer(3, GL_FLOAT, m_triangles.get_vertex_data_size(), (GLvoid*)m_triangles.get_vertices_data()));
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount));

View file

@ -3,19 +3,10 @@
#include "GLTexture.hpp"
#include "3DScene.hpp"
#if ENABLE_GCODE_VIEWER
#include "GLModel.hpp"
#endif // ENABLE_GCODE_VIEWER
#include <tuple>
#if ENABLE_GCODE_VIEWER
#include <array>
#endif // ENABLE_GCODE_VIEWER
#if !ENABLE_GCODE_VIEWER
class GLUquadric;
typedef class GLUquadric GLUquadricObj;
#endif // !ENABLE_GCODE_VIEWER
namespace Slic3r {
namespace GUI {
@ -52,7 +43,6 @@ public:
class Bed3D
{
#if ENABLE_GCODE_VIEWER
class Axes
{
public:
@ -62,43 +52,16 @@ class Bed3D
static const float DefaultTipLength;
private:
#else
struct Axes
{
static const double Radius;
static const double ArrowBaseRadius;
static const double ArrowLength;
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
Vec3d m_origin{ Vec3d::Zero() };
float m_stem_length{ DefaultStemLength };
mutable GLModel m_arrow;
public:
#else
Vec3d origin;
Vec3d length;
GLUquadricObj* m_quadric;
#endif // ENABLE_GCODE_VIEWER
#if !ENABLE_GCODE_VIEWER
Axes();
~Axes();
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
const Vec3d& get_origin() const { return m_origin; }
void set_origin(const Vec3d& origin) { m_origin = origin; }
void set_stem_length(float length);
float get_total_length() const { return m_stem_length + DefaultTipLength; }
#endif // ENABLE_GCODE_VIEWER
void render() const;
#if !ENABLE_GCODE_VIEWER
private:
void render_axis(double length) const;
#endif // !ENABLE_GCODE_VIEWER
};
public:
@ -120,13 +83,9 @@ private:
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
mutable GLTexture m_texture;
#if ENABLE_GCODE_VIEWER
mutable GLModel m_model;
mutable Vec3d m_model_offset{ Vec3d::Zero() };
std::array<float, 4> m_model_color{ 0.235f, 0.235f, 0.235f, 1.0f };
#else
mutable GLBed m_model;
#endif // ENABLE_GCODE_VIEWER
// temporary texture shown until the main texture has still no levels compressed
mutable GLTexture m_temp_texture;
mutable unsigned int m_vbo_id;

View file

@ -993,290 +993,6 @@ bool GLVolumeCollection::has_toolpaths_to_export() const
return false;
}
#if !ENABLE_GCODE_VIEWER
void GLVolumeCollection::export_toolpaths_to_obj(const char* filename) const
{
if (filename == nullptr)
return;
if (!has_toolpaths_to_export())
return;
// collect color information to generate materials
typedef std::array<float, 4> Color;
std::set<Color> colors;
for (const GLVolume* volume : this->volumes)
{
if (!can_export_to_obj(*volume))
continue;
Color color;
::memcpy((void*)color.data(), (const void*)volume->color, 4 * sizeof(float));
colors.insert(color);
}
// save materials file
boost::filesystem::path mat_filename(filename);
mat_filename.replace_extension("mtl");
FILE* fp = boost::nowide::fopen(mat_filename.string().c_str(), "w");
if (fp == nullptr) {
BOOST_LOG_TRIVIAL(error) << "GLVolumeCollection::export_toolpaths_to_obj: Couldn't open " << mat_filename.string().c_str() << " for writing";
return;
}
fprintf(fp, "# G-Code Toolpaths Materials\n");
fprintf(fp, "# Generated by %s based on Slic3r\n", SLIC3R_BUILD_ID);
unsigned int colors_count = 1;
for (const Color& color : colors)
{
fprintf(fp, "\nnewmtl material_%d\n", colors_count++);
fprintf(fp, "Ka 1 1 1\n");
fprintf(fp, "Kd %f %f %f\n", color[0], color[1], color[2]);
fprintf(fp, "Ks 0 0 0\n");
}
fclose(fp);
// save geometry file
fp = boost::nowide::fopen(filename, "w");
if (fp == nullptr) {
BOOST_LOG_TRIVIAL(error) << "GLVolumeCollection::export_toolpaths_to_obj: Couldn't open " << filename << " for writing";
return;
}
fprintf(fp, "# G-Code Toolpaths\n");
fprintf(fp, "# Generated by %s based on Slic3r\n", SLIC3R_BUILD_ID);
fprintf(fp, "\nmtllib ./%s\n", mat_filename.filename().string().c_str());
unsigned int vertices_count = 0;
unsigned int normals_count = 0;
unsigned int volumes_count = 0;
for (const GLVolume* volume : this->volumes)
{
if (!can_export_to_obj(*volume))
continue;
std::vector<float> src_vertices_and_normals_interleaved;
std::vector<int> src_triangle_indices;
std::vector<int> src_quad_indices;
if (!volume->indexed_vertex_array.vertices_and_normals_interleaved.empty())
// data are in CPU memory
src_vertices_and_normals_interleaved = volume->indexed_vertex_array.vertices_and_normals_interleaved;
else if ((volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id != 0) && (volume->indexed_vertex_array.vertices_and_normals_interleaved_size != 0))
{
// data are in GPU memory
src_vertices_and_normals_interleaved = std::vector<float>(volume->indexed_vertex_array.vertices_and_normals_interleaved_size, 0.0f);
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id));
glsafe(::glGetBufferSubData(GL_ARRAY_BUFFER, 0, src_vertices_and_normals_interleaved.size() * sizeof(float), src_vertices_and_normals_interleaved.data()));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
else
continue;
if (!volume->indexed_vertex_array.triangle_indices.empty())
{
// data are in CPU memory
size_t size = std::min(volume->indexed_vertex_array.triangle_indices.size(), volume->tverts_range.second - volume->tverts_range.first);
if (size != 0)
{
std::vector<int>::const_iterator it_begin = volume->indexed_vertex_array.triangle_indices.begin() + volume->tverts_range.first;
std::vector<int>::const_iterator it_end = volume->indexed_vertex_array.triangle_indices.begin() + volume->tverts_range.first + size;
std::copy(it_begin, it_end, std::back_inserter(src_triangle_indices));
}
}
else if ((volume->indexed_vertex_array.triangle_indices_VBO_id != 0) && (volume->indexed_vertex_array.triangle_indices_size != 0))
{
// data are in GPU memory
size_t size = std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first);
if (size != 0)
{
src_triangle_indices = std::vector<int>(size, 0);
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, volume->tverts_range.first * sizeof(int), size * sizeof(int), src_triangle_indices.data()));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
}
if (!volume->indexed_vertex_array.quad_indices.empty())
{
// data are in CPU memory
size_t size = std::min(volume->indexed_vertex_array.quad_indices.size(), volume->qverts_range.second - volume->qverts_range.first);
if (size != 0)
{
std::vector<int>::const_iterator it_begin = volume->indexed_vertex_array.quad_indices.begin() + volume->qverts_range.first;
std::vector<int>::const_iterator it_end = volume->indexed_vertex_array.quad_indices.begin() + volume->qverts_range.first + size;
std::copy(it_begin, it_end, std::back_inserter(src_quad_indices));
}
}
else if ((volume->indexed_vertex_array.quad_indices_VBO_id != 0) && (volume->indexed_vertex_array.quad_indices_size != 0))
{
// data are in GPU memory
size_t size = std::min(volume->indexed_vertex_array.quad_indices_size, volume->qverts_range.second - volume->qverts_range.first);
if (size != 0)
{
src_quad_indices = std::vector<int>(size, 0);
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id));
glsafe(::glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, volume->qverts_range.first * sizeof(int), size * sizeof(int), src_quad_indices.data()));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
}
if (src_triangle_indices.empty() && src_quad_indices.empty())
continue;
++volumes_count;
// reduce output size by keeping only used vertices and normals
struct Vector
{
std::array<coord_t, 3> vector;
explicit Vector(float* ptr)
{
vector[0] = scale_(*(ptr + 0));
vector[1] = scale_(*(ptr + 1));
vector[2] = scale_(*(ptr + 2));
}
};
typedef std::vector<Vector> Vectors;
auto vector_less = [](const Vector& v1, const Vector& v2)->bool {
return v1.vector < v2.vector;
};
auto vector_equal = [](const Vector& v1, const Vector& v2)->bool {
return (v1.vector[0] == v2.vector[0]) && (v1.vector[1] == v2.vector[1]) && (v1.vector[2] == v2.vector[2]);
};
// copy used vertices and normals data
Vectors dst_normals;
Vectors dst_vertices;
unsigned int src_triangle_indices_size = (unsigned int)src_triangle_indices.size();
for (unsigned int i = 0; i < src_triangle_indices_size; ++i)
{
float* src_ptr = src_vertices_and_normals_interleaved.data() + src_triangle_indices[i] * 6;
dst_normals.emplace_back(src_ptr + 0);
dst_vertices.emplace_back(src_ptr + 3);
}
unsigned int src_quad_indices_size = (unsigned int)src_quad_indices.size();
for (unsigned int i = 0; i < src_quad_indices_size; ++i)
{
float* src_ptr = src_vertices_and_normals_interleaved.data() + src_quad_indices[i] * 6;
dst_normals.emplace_back(src_ptr + 0);
dst_vertices.emplace_back(src_ptr + 3);
}
// sort vertices and normals
std::sort(dst_normals.begin(), dst_normals.end(), vector_less);
std::sort(dst_vertices.begin(), dst_vertices.end(), vector_less);
// remove duplicated vertices and normals
dst_normals.erase(std::unique(dst_normals.begin(), dst_normals.end(), vector_equal), dst_normals.end());
dst_vertices.erase(std::unique(dst_vertices.begin(), dst_vertices.end(), vector_equal), dst_vertices.end());
// reindex triangles and quads
struct IndicesPair
{
int vertex;
int normal;
IndicesPair(int vertex, int normal) : vertex(vertex), normal(normal) {}
};
typedef std::vector<IndicesPair> Indices;
unsigned int src_vertices_count = (unsigned int)src_vertices_and_normals_interleaved.size() / 6;
std::vector<int> src_dst_vertex_indices_map(src_vertices_count, -1);
std::vector<int> src_dst_normal_indices_map(src_vertices_count, -1);
for (unsigned int i = 0; i < src_vertices_count; ++i)
{
float* src_ptr = src_vertices_and_normals_interleaved.data() + i * 6;
src_dst_normal_indices_map[i] = std::distance(dst_normals.begin(), std::lower_bound(dst_normals.begin(), dst_normals.end(), Vector(src_ptr + 0), vector_less));
src_dst_vertex_indices_map[i] = std::distance(dst_vertices.begin(), std::lower_bound(dst_vertices.begin(), dst_vertices.end(), Vector(src_ptr + 3), vector_less));
}
Indices dst_triangle_indices;
if (src_triangle_indices_size > 0)
dst_triangle_indices.reserve(src_triangle_indices_size);
for (unsigned int i = 0; i < src_triangle_indices_size; ++i)
{
int id = src_triangle_indices[i];
dst_triangle_indices.emplace_back(src_dst_vertex_indices_map[id], src_dst_normal_indices_map[id]);
}
Indices dst_quad_indices;
if (src_quad_indices_size > 0)
dst_quad_indices.reserve(src_quad_indices_size);
for (unsigned int i = 0; i < src_quad_indices_size; ++i)
{
int id = src_quad_indices[i];
dst_quad_indices.emplace_back(src_dst_vertex_indices_map[id], src_dst_normal_indices_map[id]);
}
// save to file
fprintf(fp, "\n# vertices volume %d\n", volumes_count);
for (const Vector& v : dst_vertices)
{
fprintf(fp, "v %g %g %g\n", unscale<float>(v.vector[0]), unscale<float>(v.vector[1]), unscale<float>(v.vector[2]));
}
fprintf(fp, "\n# normals volume %d\n", volumes_count);
for (const Vector& n : dst_normals)
{
fprintf(fp, "vn %g %g %g\n", unscale<float>(n.vector[0]), unscale<float>(n.vector[1]), unscale<float>(n.vector[2]));
}
Color color;
::memcpy((void*)color.data(), (const void*)volume->color, 4 * sizeof(float));
fprintf(fp, "\n# material volume %d\n", volumes_count);
fprintf(fp, "usemtl material_%lld\n", (long long)(1 + std::distance(colors.begin(), colors.find(color))));
int base_vertex_id = vertices_count + 1;
int base_normal_id = normals_count + 1;
if (!dst_triangle_indices.empty())
{
fprintf(fp, "\n# triangular facets volume %d\n", volumes_count);
for (unsigned int i = 0; i < (unsigned int)dst_triangle_indices.size(); i += 3)
{
fprintf(fp, "f %d//%d %d//%d %d//%d\n",
base_vertex_id + dst_triangle_indices[i + 0].vertex, base_normal_id + dst_triangle_indices[i + 0].normal,
base_vertex_id + dst_triangle_indices[i + 1].vertex, base_normal_id + dst_triangle_indices[i + 1].normal,
base_vertex_id + dst_triangle_indices[i + 2].vertex, base_normal_id + dst_triangle_indices[i + 2].normal);
}
}
if (!dst_quad_indices.empty())
{
fprintf(fp, "\n# quadrangular facets volume %d\n", volumes_count);
for (unsigned int i = 0; i < (unsigned int)src_quad_indices.size(); i += 4)
{
fprintf(fp, "f %d//%d %d//%d %d//%d %d//%d\n",
base_vertex_id + dst_quad_indices[i + 0].vertex, base_normal_id + dst_quad_indices[i + 0].normal,
base_vertex_id + dst_quad_indices[i + 1].vertex, base_normal_id + dst_quad_indices[i + 1].normal,
base_vertex_id + dst_quad_indices[i + 2].vertex, base_normal_id + dst_quad_indices[i + 2].normal,
base_vertex_id + dst_quad_indices[i + 3].vertex, base_normal_id + dst_quad_indices[i + 3].normal);
}
}
vertices_count += (unsigned int)dst_vertices.size();
normals_count += (unsigned int)dst_normals.size();
}
fclose(fp);
}
#endif // !ENABLE_GCODE_VIEWER
// caller is responsible for supplying NO lines with zero length
static void thick_lines_to_indexed_vertex_array(
const Lines &lines,
@ -1923,287 +1639,4 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height
thick_point_to_verts(point, width, height, volume);
}
#if !ENABLE_GCODE_VIEWER
GLModel::GLModel()
: m_filename("")
{
m_volume.shader_outside_printer_detection_enabled = false;
}
GLModel::~GLModel()
{
reset();
}
void GLModel::set_color(const float* color, unsigned int size)
{
::memcpy((void*)m_volume.color, (const void*)color, (size_t)(std::min((unsigned int)4, size) * sizeof(float)));
m_volume.set_render_color(color, size);
}
const Vec3d& GLModel::get_offset() const
{
return m_volume.get_volume_offset();
}
void GLModel::set_offset(const Vec3d& offset)
{
m_volume.set_volume_offset(offset);
}
const Vec3d& GLModel::get_rotation() const
{
return m_volume.get_volume_rotation();
}
void GLModel::set_rotation(const Vec3d& rotation)
{
m_volume.set_volume_rotation(rotation);
}
const Vec3d& GLModel::get_scale() const
{
return m_volume.get_volume_scaling_factor();
}
void GLModel::set_scale(const Vec3d& scale)
{
m_volume.set_volume_scaling_factor(scale);
}
void GLModel::reset()
{
m_volume.indexed_vertex_array.release_geometry();
m_filename = "";
}
void GLModel::render() const
{
GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
if (shader == nullptr)
return;
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
glsafe(::glCullFace(GL_BACK));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
shader->set_uniform("uniform_color", m_volume.render_color, 4);
m_volume.render();
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisable(GL_BLEND));
}
bool GLArrow::on_init()
{
Pointf3s vertices;
std::vector<Vec3i> triangles;
// bottom face
vertices.emplace_back(0.5, 0.0, -0.1);
vertices.emplace_back(0.5, 2.0, -0.1);
vertices.emplace_back(1.0, 2.0, -0.1);
vertices.emplace_back(0.0, 3.0, -0.1);
vertices.emplace_back(-1.0, 2.0, -0.1);
vertices.emplace_back(-0.5, 2.0, -0.1);
vertices.emplace_back(-0.5, 0.0, -0.1);
// top face
vertices.emplace_back(0.5, 0.0, 0.1);
vertices.emplace_back(0.5, 2.0, 0.1);
vertices.emplace_back(1.0, 2.0, 0.1);
vertices.emplace_back(0.0, 3.0, 0.1);
vertices.emplace_back(-1.0, 2.0, 0.1);
vertices.emplace_back(-0.5, 2.0, 0.1);
vertices.emplace_back(-0.5, 0.0, 0.1);
// bottom face
triangles.emplace_back(0, 6, 1);
triangles.emplace_back(6, 5, 1);
triangles.emplace_back(5, 4, 3);
triangles.emplace_back(5, 3, 1);
triangles.emplace_back(1, 3, 2);
// top face
triangles.emplace_back(7, 8, 13);
triangles.emplace_back(13, 8, 12);
triangles.emplace_back(12, 10, 11);
triangles.emplace_back(8, 10, 12);
triangles.emplace_back(8, 9, 10);
// side face
triangles.emplace_back(0, 1, 8);
triangles.emplace_back(8, 7, 0);
triangles.emplace_back(1, 2, 9);
triangles.emplace_back(9, 8, 1);
triangles.emplace_back(2, 3, 10);
triangles.emplace_back(10, 9, 2);
triangles.emplace_back(3, 4, 11);
triangles.emplace_back(11, 10, 3);
triangles.emplace_back(4, 5, 12);
triangles.emplace_back(12, 11, 4);
triangles.emplace_back(5, 6, 13);
triangles.emplace_back(13, 12, 5);
triangles.emplace_back(6, 0, 7);
triangles.emplace_back(7, 13, 6);
m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles));
m_volume.indexed_vertex_array.finalize_geometry(true);
return true;
}
GLCurvedArrow::GLCurvedArrow(unsigned int resolution)
: GLModel()
, m_resolution(resolution)
{
if (m_resolution == 0)
m_resolution = 1;
}
bool GLCurvedArrow::on_init()
{
Pointf3s vertices;
std::vector<Vec3i> triangles;
double ext_radius = 2.5;
double int_radius = 1.5;
double step = 0.5 * (double)PI / (double)m_resolution;
unsigned int vertices_per_level = 4 + 2 * m_resolution;
// bottom face
vertices.emplace_back(0.0, 1.5, -0.1);
vertices.emplace_back(0.0, 1.0, -0.1);
vertices.emplace_back(-1.0, 2.0, -0.1);
vertices.emplace_back(0.0, 3.0, -0.1);
vertices.emplace_back(0.0, 2.5, -0.1);
for (unsigned int i = 1; i <= m_resolution; ++i)
{
double angle = (double)i * step;
double x = ext_radius * ::sin(angle);
double y = ext_radius * ::cos(angle);
vertices.emplace_back(x, y, -0.1);
}
for (unsigned int i = 0; i < m_resolution; ++i)
{
double angle = (double)i * step;
double x = int_radius * ::cos(angle);
double y = int_radius * ::sin(angle);
vertices.emplace_back(x, y, -0.1);
}
// top face
vertices.emplace_back(0.0, 1.5, 0.1);
vertices.emplace_back(0.0, 1.0, 0.1);
vertices.emplace_back(-1.0, 2.0, 0.1);
vertices.emplace_back(0.0, 3.0, 0.1);
vertices.emplace_back(0.0, 2.5, 0.1);
for (unsigned int i = 1; i <= m_resolution; ++i)
{
double angle = (double)i * step;
double x = ext_radius * ::sin(angle);
double y = ext_radius * ::cos(angle);
vertices.emplace_back(x, y, 0.1);
}
for (unsigned int i = 0; i < m_resolution; ++i)
{
double angle = (double)i * step;
double x = int_radius * ::cos(angle);
double y = int_radius * ::sin(angle);
vertices.emplace_back(x, y, 0.1);
}
// bottom face
triangles.emplace_back(0, 1, 2);
triangles.emplace_back(0, 2, 4);
triangles.emplace_back(4, 2, 3);
int first_id = 4;
int last_id = (int)vertices_per_level;
triangles.emplace_back(last_id, 0, first_id);
triangles.emplace_back(last_id, first_id, first_id + 1);
for (unsigned int i = 1; i < m_resolution; ++i)
{
triangles.emplace_back(last_id - i, last_id - i + 1, first_id + i);
triangles.emplace_back(last_id - i, first_id + i, first_id + i + 1);
}
// top face
last_id += 1;
triangles.emplace_back(last_id + 0, last_id + 2, last_id + 1);
triangles.emplace_back(last_id + 0, last_id + 4, last_id + 2);
triangles.emplace_back(last_id + 4, last_id + 3, last_id + 2);
first_id = last_id + 4;
last_id = last_id + 4 + 2 * (int)m_resolution;
triangles.emplace_back(last_id, first_id, (int)vertices_per_level + 1);
triangles.emplace_back(last_id, first_id + 1, first_id);
for (unsigned int i = 1; i < m_resolution; ++i)
{
triangles.emplace_back(last_id - i, first_id + i, last_id - i + 1);
triangles.emplace_back(last_id - i, first_id + i + 1, first_id + i);
}
// side face
for (unsigned int i = 0; i < 4 + 2 * (unsigned int)m_resolution; ++i)
{
triangles.emplace_back(i, vertices_per_level + 2 + i, i + 1);
triangles.emplace_back(i, vertices_per_level + 1 + i, vertices_per_level + 2 + i);
}
triangles.emplace_back(vertices_per_level, vertices_per_level + 1, 0);
triangles.emplace_back(vertices_per_level, 2 * vertices_per_level + 1, vertices_per_level + 1);
m_volume.indexed_vertex_array.load_mesh(TriangleMesh(vertices, triangles));
m_volume.indexed_vertex_array.finalize_geometry(true);
return true;
}
bool GLBed::on_init_from_file(const std::string& filename)
{
reset();
if (!boost::filesystem::exists(filename))
return false;
if (!boost::algorithm::iends_with(filename, ".stl"))
return false;
Model model;
try
{
model = Model::read_from_file(filename);
}
catch (std::exception & /* ex */)
{
return false;
}
m_filename = filename;
m_volume.indexed_vertex_array.load_mesh(model.mesh());
m_volume.indexed_vertex_array.finalize_geometry(true);
float color[4] = { 0.235f, 0.235f, 0.235f, 1.0f };
set_color(color, 4);
return true;
}
#endif // !ENABLE_GCODE_VIEWER
} // namespace Slic3r

View file

@ -588,10 +588,6 @@ public:
std::string log_memory_info() const;
bool has_toolpaths_to_export() const;
#if !ENABLE_GCODE_VIEWER
// Export the geometry of the GLVolumes toolpaths of this collection into the file with the given path, in obj format
void export_toolpaths_to_obj(const char* filename) const;
#endif // !ENABLE_GCODE_VIEWER
private:
GLVolumeCollection(const GLVolumeCollection &other);
@ -600,68 +596,6 @@ private:
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function<bool(const GLVolume&)> filter_func = nullptr);
#if !ENABLE_GCODE_VIEWER
class GLModel
{
protected:
GLVolume m_volume;
std::string m_filename;
public:
GLModel();
virtual ~GLModel();
// init() / init_from_file() shall be called with the OpenGL context active!
bool init() { return on_init(); }
bool init_from_file(const std::string& filename) { return on_init_from_file(filename); }
void center_around(const Vec3d& center) { m_volume.set_volume_offset(center - m_volume.bounding_box().center()); }
void set_color(const float* color, unsigned int size);
const Vec3d& get_offset() const;
void set_offset(const Vec3d& offset);
const Vec3d& get_rotation() const;
void set_rotation(const Vec3d& rotation);
const Vec3d& get_scale() const;
void set_scale(const Vec3d& scale);
const std::string& get_filename() const { return m_filename; }
const BoundingBoxf3& get_bounding_box() const { return m_volume.bounding_box(); }
const BoundingBoxf3& get_transformed_bounding_box() const { return m_volume.transformed_bounding_box(); }
void reset();
void render() const;
protected:
virtual bool on_init() { return false; }
virtual bool on_init_from_file(const std::string& filename) { return false; }
};
class GLArrow : public GLModel
{
protected:
bool on_init() override;
};
class GLCurvedArrow : public GLModel
{
unsigned int m_resolution;
public:
explicit GLCurvedArrow(unsigned int resolution);
protected:
bool on_init() override;
};
class GLBed : public GLModel
{
protected:
bool on_init_from_file(const std::string& filename) override;
};
#endif // !ENABLE_GCODE_VIEWER
struct _3DScene
{
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);

View file

@ -37,17 +37,10 @@ void AboutDialogLogo::onRepaint(wxEvent &event)
// CopyrightsDialog
// -----------------------------------------
CopyrightsDialog::CopyrightsDialog()
#if ENABLE_GCODE_VIEWER
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, from_u8((boost::format("%1% - %2%")
% (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME)
% _utf8(L("Portions copyright"))).str()),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
#else
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, from_u8((boost::format("%1% - %2%")
% SLIC3R_APP_NAME
% _utf8(L("Portions copyright"))).str()),
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
#endif // ENABLE_GCODE_VIEWER
{
this->SetFont(wxGetApp().normal_font());
this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
@ -208,13 +201,8 @@ void CopyrightsDialog::onCloseDialog(wxEvent &)
}
AboutDialog::AboutDialog()
#if ENABLE_GCODE_VIEWER
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, from_u8((boost::format(_utf8(L("About %s"))) % (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME)).str()), wxDefaultPosition,
wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
#else
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, from_u8((boost::format(_utf8(L("About %s"))) % SLIC3R_APP_NAME).str()), wxDefaultPosition,
wxDefaultSize, /*wxCAPTION*/wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
#endif // ENABLE_GCODE_VIEWER
{
SetFont(wxGetApp().normal_font());
@ -226,11 +214,7 @@ AboutDialog::AboutDialog()
main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20);
// logo
#if ENABLE_GCODE_VIEWER
m_logo_bitmap = ScalableBitmap(this, wxGetApp().is_editor() ? "PrusaSlicer_192px.png" : "PrusaSlicer-gcodeviewer_192px.png", 192);
#else
m_logo_bitmap = ScalableBitmap(this, "PrusaSlicer_192px.png", 192);
#endif // ENABLE_GCODE_VIEWER
m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bitmap.bmp());
hsizer->Add(m_logo, 1, wxALIGN_CENTER_VERTICAL);
@ -239,11 +223,7 @@ AboutDialog::AboutDialog()
// title
{
#if ENABLE_GCODE_VIEWER
wxStaticText* title = new wxStaticText(this, wxID_ANY, wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME, wxDefaultPosition, wxDefaultSize);
#else
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
#endif // ENABLE_GCODE_VIEWER
wxFont title_font = GUI::wxGetApp().bold_font();
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(24);
@ -253,7 +233,7 @@ AboutDialog::AboutDialog()
// version
{
auto version_string = _L("Version")+ " " + std::string(SLIC3R_VERSION);
auto version_string = _L("Version") + " " + std::string(SLIC3R_VERSION);
wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
wxFont version_font = GetFont();
#ifdef __WXMSW__

View file

@ -141,11 +141,7 @@ void BackgroundSlicingProcess::process_fff()
// Passing the timestamp
evt.SetInt((int)(m_fff_print->step_state_with_timestamp(PrintStep::psSlicingFinished).timestamp));
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, evt.Clone());
#if ENABLE_GCODE_VIEWER
m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, m_thumbnail_cb);
#else
m_fff_print->export_gcode(m_temp_output_path, m_gcode_preview_data, m_thumbnail_cb);
#endif // ENABLE_GCODE_VIEWER
if (this->set_step_started(bspsGCodeFinalize)) {
if (! m_export_path.empty()) {
wxQueueEvent(GUI::wxGetApp().mainframe->m_plater, new wxCommandEvent(m_event_export_began_id));
@ -433,25 +429,14 @@ Print::ApplyStatus BackgroundSlicingProcess::apply(const Model &model, const Dyn
assert(m_print != nullptr);
assert(config.opt_enum<PrinterTechnology>("printer_technology") == m_print->technology());
Print::ApplyStatus invalidated = m_print->apply(model, config);
#if ENABLE_GCODE_VIEWER
if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF &&
!this->m_fff_print->is_step_done(psGCodeExport))
{
!this->m_fff_print->is_step_done(psGCodeExport)) {
// Some FFF status was invalidated, and the G-code was not exported yet.
// Let the G-code preview UI know that the final G-code preview is not valid.
// In addition, this early memory deallocation reduces memory footprint.
if (m_gcode_result != nullptr)
m_gcode_result->reset();
}
#else
if ((invalidated & PrintBase::APPLY_STATUS_INVALIDATED) != 0 && m_print->technology() == ptFFF &&
m_gcode_preview_data != nullptr && ! this->m_fff_print->is_step_done(psGCodeExport)) {
// Some FFF status was invalidated, and the G-code was not exported yet.
// Let the G-code preview UI know that the final G-code preview is not valid.
// In addition, this early memory deallocation reduces memory footprint.
m_gcode_preview_data->reset();
}
#endif // ENABLE_GCODE_VIEWER
return invalidated;
}

View file

@ -11,9 +11,7 @@
#include "libslic3r/GCode/ThumbnailData.hpp"
#include "libslic3r/Format/SL1.hpp"
#include "slic3r/Utils/PrintHost.hpp"
#if ENABLE_GCODE_VIEWER
#include "libslic3r/GCode/GCodeProcessor.hpp"
#endif // ENABLE_GCODE_VIEWER
namespace boost { namespace filesystem { class path; } }
@ -21,9 +19,6 @@ namespace boost { namespace filesystem { class path; } }
namespace Slic3r {
class DynamicPrintConfig;
#if !ENABLE_GCODE_VIEWER
class GCodePreviewData;
#endif // !ENABLE_GCODE_VIEWER
class Model;
class SLAPrint;
@ -88,11 +83,7 @@ public:
void set_fff_print(Print *print) { m_fff_print = print; }
void set_sla_print(SLAPrint *print) { m_sla_print = print; m_sla_print->set_printer(&m_sla_archive); }
void set_thumbnail_cb(ThumbnailsGeneratorCallback cb) { m_thumbnail_cb = cb; }
#if ENABLE_GCODE_VIEWER
void set_gcode_result(GCodeProcessor::Result* result) { m_gcode_result = result; }
#else
void set_gcode_preview_data(GCodePreviewData* gpd) { m_gcode_preview_data = gpd; }
#endif // ENABLE_GCODE_VIEWER
// The following wxCommandEvent will be sent to the UI thread / Plater window, when the slicing is finished
// and the background processing will transition into G-code export.
@ -198,13 +189,8 @@ private:
// Non-owned pointers to Print instances.
Print *m_fff_print = nullptr;
SLAPrint *m_sla_print = nullptr;
#if ENABLE_GCODE_VIEWER
// Data structure, to which the G-code export writes its annotations.
GCodeProcessor::Result *m_gcode_result = nullptr;
#else
// Data structure, to which the G-code export writes its annotations.
GCodePreviewData *m_gcode_preview_data = nullptr;
#endif // ENABLE_GCODE_VIEWER
// Callback function, used to write thumbnails into gcode.
ThumbnailsGeneratorCallback m_thumbnail_cb = nullptr;
SL1Archive m_sla_archive;

View file

@ -3,9 +3,7 @@
#include "libslic3r/Utils.hpp"
#include "../Utils/MacDarkMode.hpp"
#include "GUI.hpp"
#if ENABLE_GCODE_VIEWER
#include "GUI_Utils.hpp"
#endif // ENABLE_GCODE_VIEWER
#include <boost/filesystem.hpp>
@ -357,17 +355,6 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
return wxImage_to_wxBitmap_with_alpha(std::move(image), scale);
}
#if !ENABLE_GCODE_VIEWER
static inline int hex_digit_to_int(const char c)
{
return
(c >= '0' && c <= '9') ? int(c - '0') :
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
}
#endif // !ENABLE_GCODE_VIEWER
bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out)
{
rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;

View file

@ -192,26 +192,23 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
wxBitmap bitmap;
int bitmap_width = 0;
int bitmap_height = 0;
const wxString bitmap_file = GUI::from_u8(Slic3r::resources_dir() + "/profiles/" + vendor.id + "/" + model.id + "_thumbnail.png");
if (wxFileExists(bitmap_file)) {
bitmap.LoadFile(bitmap_file, wxBITMAP_TYPE_PNG);
bitmap_width = bitmap.GetWidth();
bitmap_height = bitmap.GetHeight();
} else {
BOOST_LOG_TRIVIAL(warning) << boost::format("Can't find bitmap file `%1%` for vendor `%2%`, printer `%3%`, using placeholder icon instead")
% bitmap_file
% vendor.id
% model.id;
const wxString placeholder_file = GUI::from_u8(Slic3r::var(PRINTER_PLACEHOLDER));
if (wxFileExists(placeholder_file)) {
bitmap.LoadFile(placeholder_file, wxBITMAP_TYPE_PNG);
auto load_bitmap = [](const wxString& bitmap_file, wxBitmap& bitmap, int& bitmap_width)->bool {
if (wxFileExists(bitmap_file)) {
bitmap.LoadFile(bitmap_file, wxBITMAP_TYPE_PNG);
bitmap_width = bitmap.GetWidth();
bitmap_height = bitmap.GetHeight();
return true;
}
return false;
};
if (!load_bitmap(GUI::from_u8(Slic3r::data_dir() + "/vendor/" + vendor.id + "/" + model.id + "_thumbnail.png"), bitmap, bitmap_width)) {
if (!load_bitmap(GUI::from_u8(Slic3r::resources_dir() + "/profiles/" + vendor.id + "/" + model.id + "_thumbnail.png"), bitmap, bitmap_width)) {
BOOST_LOG_TRIVIAL(warning) << boost::format("Can't find bitmap file `%1%` for vendor `%2%`, printer `%3%`, using placeholder icon instead")
% (Slic3r::resources_dir() + "/profiles/" + vendor.id + "/" + model.id + "_thumbnail.png")
% vendor.id
% model.id;
load_bitmap(Slic3r::var(PRINTER_PLACEHOLDER), bitmap, bitmap_width);
}
}
auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
title->SetFont(font_name);
const int wrap_width = std::max((int)MODEL_MIN_WRAP, bitmap_width);

View file

@ -565,9 +565,7 @@ struct ConfigWizard::priv
priv(ConfigWizard *q)
: q(q)
#if ENABLE_GCODE_VIEWER
, appconfig_new(AppConfig::EAppMode::Editor)
#endif // ENABLE_GCODE_VIEWER
, filaments(T_FFF)
, sla_materials(T_SLA)
{}

View file

@ -4,6 +4,7 @@
#include "libslic3r/GCode.hpp"
#else
#include "wxExtensions.hpp"
#include "libslic3r/GCode/PreviewData.hpp"
#endif // ENABLE_GCODE_VIEWER
#include "GUI.hpp"
#include "GUI_App.hpp"
@ -12,6 +13,7 @@
#include "ExtruderSequenceDialog.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/AppConfig.hpp"
#include "GUI_Utils.hpp"
#include <wx/button.h>
#include <wx/dialog.h>
@ -68,7 +70,8 @@ Control::Control( wxWindow *parent,
m_higher_value (higherValue),
m_min_value(minValue),
m_max_value(maxValue),
m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL)
m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL),
m_extra_style(style == wxSL_VERTICAL ? wxSL_AUTOTICKS | wxSL_VALUE_LABEL : 0)
{
#ifdef __WXOSX__
is_osx = true;
@ -240,6 +243,12 @@ void Control::SetMaxValue(const int max_value)
Update();
}
void Control::SetSliderValues(const std::vector<double>& values)
{
m_values = values;
m_ruler.count = std::count(m_values.begin(), m_values.end(), m_values.front());
}
void Control::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos)
{
int width;
@ -371,6 +380,24 @@ void Control::SetTicksValues(const Info& custom_gcode_per_print_z)
Update();
}
void Control::SetLayersTimes(const std::vector<float>& layers_times)
{
m_layers_times.clear();
if (layers_times.empty())
return;
m_layers_times.resize(layers_times.size(), 0.0);
m_layers_times[0] = layers_times[0];
for (size_t i = 1; i < layers_times.size(); i++)
m_layers_times[i] = m_layers_times[i - 1] + layers_times[i];
}
void Control::SetLayersTimes(const std::vector<double>& layers_times)
{
m_layers_times = layers_times;
for (size_t i = 1; i < m_layers_times.size(); i++)
m_layers_times[i] += m_layers_times[i - 1];
}
void Control::SetDrawMode(bool is_sla_print, bool is_sequential_print)
{
m_draw_mode = is_sla_print ? dmSlaPrint :
@ -443,6 +470,9 @@ void Control::render()
// and only in a case of no-empty m_values
draw_colored_band(dc);
if (m_extra_style & wxSL_AUTOTICKS)
draw_ruler(dc);
if (!m_render_as_disabled) {
// draw line
draw_scroll_line(dc, lower_pos, higher_pos);
@ -560,7 +590,7 @@ void Control::draw_tick_on_mouse_position(wxDC& dc)
}
tick = get_value_from_position(m_moving_pos);
if (tick >= m_max_value || tick <= m_min_value || tick == m_higher_value || tick == m_lower_value)
if (tick > m_max_value || tick < m_min_value || tick == m_higher_value || tick == m_lower_value)
return;
wxCoord new_pos = get_position_from_value(tick);
@ -569,9 +599,57 @@ void Control::draw_tick_on_mouse_position(wxDC& dc)
//draw info line
dc.SetPen(LIGHT_GREY_PEN);
draw_ticks(dc, pos);
if (m_extra_style & wxSL_VALUE_LABEL) {
wxColour old_clr = dc.GetTextForeground();
dc.SetTextForeground(LIGHT_GREY_PEN.GetColour());
draw_tick_text(dc, pos, tick, ltEstimatedTime, false);
dc.SetTextForeground(old_clr);
}
}
wxString Control::get_label(int tick) const
static std::string short_and_splitted_time(const std::string& time)
{
// Parse the dhms time format.
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
if (time.find('d') != std::string::npos)
::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds);
else if (time.find('h') != std::string::npos)
::sscanf(time.c_str(), "%dh %dm %ds", &hours, &minutes, &seconds);
else if (time.find('m') != std::string::npos)
::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds);
else if (time.find('s') != std::string::npos)
::sscanf(time.c_str(), "%ds", &seconds);
// Format the dhm time.
char buffer[64];
if (days > 0)
::sprintf(buffer, "%dd%dh\n%dm", days, hours, minutes);
else if (hours > 0) {
if (hours < 10 && minutes < 10 && seconds < 10)
::sprintf(buffer, "%dh%dm%ds", hours, minutes, seconds);
else if (hours > 10 && minutes > 10 && seconds > 10)
::sprintf(buffer, "%dh\n%dm\n%ds", hours, minutes, seconds);
else if (minutes < 10 && seconds > 10 || minutes > 10 && seconds < 10)
::sprintf(buffer, "%dh\n%dm%ds", hours, minutes, seconds);
else
::sprintf(buffer, "%dh%dm\n%ds", hours, minutes, seconds);
}
else if (minutes > 0) {
if (minutes > 10 && seconds > 10)
::sprintf(buffer, "%dm\n%ds", minutes, seconds);
else
::sprintf(buffer, "%dm%ds", minutes, seconds);
}
else
::sprintf(buffer, "%ds", seconds);
return buffer;
}
wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer*/) const
{
const int value = tick;
@ -584,23 +662,35 @@ wxString Control::get_label(int tick) const
if (m_draw_mode == dmSequentialGCodeView)
return wxString::Format("%d", static_cast<unsigned int>(m_values[value]));
else {
const wxString str = m_values.empty() ?
if (label_type == ltEstimatedTime) {
if (m_values.size() != m_layers_times.size())
return "time";
return short_and_splitted_time(get_time_dhms(m_layers_times[value]));
}
wxString str = m_values.empty() ?
wxString::Format("%.*f", 2, m_label_koef * value) :
wxString::Format("%.*f", 2, m_values[value]);
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
if (label_type == ltHeight)
return str;
if (label_type == ltHeightWithLayer)
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
}
#else
const wxString str = m_values.empty() ?
wxNumberFormatter::ToString(m_label_koef * value, 2, wxNumberFormatter::Style_None) :
wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None);
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
if (label_type == ltHeight)
return str;
if (label_type == ltHeightWithLayer)
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
#endif // ENABLE_GCODE_VIEWER
return wxEmptyString;
}
void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const
void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType label_type/* = ltHeight*/, bool right_side/*=true*/) const
{
wxCoord text_width, text_height;
const wxString label = get_label(tick);
const wxString label = get_label(tick, label_type);
dc.GetMultiLineTextExtent(label, &text_width, &text_height);
wxPoint text_pos;
if (right_side) {
@ -615,9 +705,6 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_
}
else
text_pos = wxPoint(pos.x + m_thumb_size.x + 1, pos.y - 0.5 * text_height - 1);
// update text rectangle
m_rect_lower_thumb_text = wxRect(text_pos, wxSize(text_width, text_height));
}
else {
if (is_horizontal()) {
@ -627,17 +714,17 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_
}
else
text_pos = wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5 * text_height + 1);
// update text rectangle
m_rect_higher_thumb_text = wxRect(text_pos, wxSize(text_width, text_height));
}
dc.DrawText(label, text_pos);
if (label_type == ltEstimatedTime)
dc.DrawLabel(label, wxRect(text_pos, wxSize(text_width, text_height)), wxALIGN_RIGHT);
else
dc.DrawText(label, text_pos);
}
void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
{
draw_tick_text(dc, pos, selection == ssLower ? m_lower_value : m_higher_value, selection == ssLower);
draw_tick_text(dc, pos, selection == ssLower ? m_lower_value : m_higher_value, ltHeightWithLayer, selection == ssLower);
}
void Control::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection)
@ -715,6 +802,15 @@ void Control::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& hig
draw_thumb_text(dc, pos_l, ssLower);
}
void Control::draw_ticks_pair(wxDC& dc, wxCoord pos, wxCoord mid, int tick_len)
{
int mid_space = 9;
is_horizontal() ? dc.DrawLine(pos, mid - (mid_space + tick_len), pos, mid - mid_space) :
dc.DrawLine(mid - (mid_space + tick_len), pos, mid - mid_space, pos);
is_horizontal() ? dc.DrawLine(pos, mid + (mid_space + tick_len), pos, mid + mid_space) :
dc.DrawLine(mid + (mid_space + tick_len), pos, mid + mid_space, pos);
};
void Control::draw_ticks(wxDC& dc)
{
if (m_draw_mode == dmSlaPrint)
@ -726,11 +822,7 @@ void Control::draw_ticks(wxDC& dc)
const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width;
for (auto tick : m_ticks.ticks) {
const wxCoord pos = get_position_from_value(tick.tick);
is_horizontal() ? dc.DrawLine(pos, mid-14, pos, mid-9) :
dc.DrawLine(mid - 14, pos/* - 1*/, mid - 9, pos/* - 1*/);
is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) :
dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/);
draw_ticks_pair(dc, pos, mid, 7);
// if current tick if focused, we should to use a specific "focused" icon
bool focused_tick = m_moving_pos != wxDefaultPosition && tick.tick == get_tick_near_point(m_moving_pos);
@ -866,6 +958,118 @@ void Control::draw_colored_band(wxDC& dc)
}
}
void Control::Ruler::update(wxWindow* win, const std::vector<double>& values, double scroll_step)
{
int DPI = GUI::get_dpi_for_window(win);
int pixels_per_sm = lround((double)(DPI) * 5.0/25.4);
int pow = -2;
int step = 0;
auto end_it = count == 1 ? values.end() : values.begin() + lround(values.size() / count);
while (pow < 3) {
int tick = 0;
for (int istep : {1, 2, 5}) {
double val = (double)istep * std::pow(10,pow);
auto val_it = std::lower_bound(values.begin(), end_it, val - epsilon());
if (val_it == values.end())
break;
int tick = val_it - values.begin();
if (lround(tick * scroll_step) > pixels_per_sm) {
step = istep;
// find next tick with istep
val *= 2;
val_it = std::lower_bound(values.begin(), end_it, val - epsilon());
// count of short ticks between ticks
int short_ticks_cnt = val_it == values.end() ? tick : val_it - values.begin() - tick;
// there couldn't be more then 10 short ticks between thicks
short_step = 0.1 * short_ticks_cnt;
break;
}
}
if (step > 0)
break;
pow++;
}
long_step = step == 0 ? -1.0 : (double)step* std::pow(10, pow);
}
void Control::draw_ruler(wxDC& dc)
{
m_ruler.update(this->GetParent(), m_values, get_scroll_step());
if (!m_ruler.is_ok())
return;
int height, width;
get_size(&width, &height);
const wxCoord mid = is_horizontal() ? 0.5 * height : 0.5 * width;
auto draw_short_ticks = [this, mid](wxDC& dc, double& current_tick, int max_tick) {
while (current_tick < max_tick) {
wxCoord pos = get_position_from_value(lround(current_tick));
draw_ticks_pair(dc, pos, mid, 2);
current_tick += m_ruler.short_step;
if (current_tick > m_max_value)
break;
}
};
dc.SetPen(LIGHT_GREY_PEN);
wxColour old_clr = dc.GetTextForeground();
dc.SetTextForeground(LIGHT_GREY_PEN.GetColour());
double short_tick;
int tick = 0;
double value = 0.0;
int sequence = 0;
while (tick <= m_max_value) {
value += m_ruler.long_step;
if (value > m_values.back() && sequence < m_ruler.count) {
value = m_ruler.long_step;
for (tick; tick < m_values.size(); tick++)
if (m_values[tick] < value)
break;
// short ticks from the last tick to the end of current sequence
draw_short_ticks(dc, short_tick, tick);
sequence++;
}
short_tick = tick;
for (tick; tick < m_values.size(); tick++) {
if (m_values[tick] == value)
break;
if (m_values[tick] > value) {
if (tick > 0)
tick--;
break;
}
}
if (tick > m_max_value)
break;
wxCoord pos = get_position_from_value(tick);
draw_ticks_pair(dc, pos, mid, 5);
draw_tick_text(dc, wxPoint(mid, pos), tick);
draw_short_ticks(dc, short_tick, tick);
if (value == m_values.back() && sequence < m_ruler.count) {
value = 0.0;
sequence++;
tick++;
}
}
// short ticks from the last tick to the end
draw_short_ticks(dc, short_tick, m_max_value);
dc.SetTextForeground(old_clr);
}
void Control::draw_one_layer_icon(wxDC& dc)
{
#if ENABLE_GCODE_VIEWER
@ -1083,9 +1287,9 @@ wxString Control::get_tooltip(int tick/*=-1*/)
else
#endif // ENABLE_GCODE_VIEWER
return m_mode == MultiAsSingle ?
GUI::from_u8((boost::format(_u8L("Jump to height %s or "
"Set extruder sequence for the entire print")) % " (Shift + G)\n").str()) :
_L("Jump to height") + " (Shift + G)";
GUI::from_u8((boost::format(_u8L("Jump to height %s Set ruler mode\n or "
"Set extruder sequence for the entire print")) % " (Shift + G)\n").str()) :
GUI::from_u8((boost::format(_u8L("Jump to height %s or Set ruler mode")) % " (Shift + G)\n").str());
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
@ -1339,14 +1543,7 @@ void Control::OnLeftUp(wxMouseEvent& event)
add_current_tick();
break;
case maCogIconClick :
if (m_mode == MultiAsSingle && m_draw_mode == dmRegular)
show_cog_icon_context_menu();
else
#if ENABLE_GCODE_VIEWER
jump_to_value();
#else
jump_to_print_z();
#endif // ENABLE_GCODE_VIEWER
show_cog_icon_context_menu();
break;
case maOneLayerIconClick:
switch_one_layer_mode();
@ -1736,8 +1933,27 @@ void Control::show_cog_icon_context_menu()
[this](wxCommandEvent&) { jump_to_print_z(); }, "", &menu);
#endif // ENABLE_GCODE_VIEWER
append_menu_item(&menu, wxID_ANY, _L("Set extruder sequence for the entire print"), "",
[this](wxCommandEvent&) { edit_extruder_sequence(); }, "", &menu);
wxMenu* ruler_mode_menu = new wxMenu();
if (ruler_mode_menu) {
append_menu_check_item(ruler_mode_menu, wxID_ANY, _L("None"), _L("Supprese show the ruler"),
[this](wxCommandEvent&) { if (m_extra_style != 0) m_extra_style = 0; }, ruler_mode_menu,
[]() { return true; }, [this]() { return m_extra_style == 0; }, GUI::wxGetApp().plater());
append_menu_check_item(ruler_mode_menu, wxID_ANY, _L("Show object height"), _L("Show object height on the ruler"),
[this](wxCommandEvent&) { m_extra_style & wxSL_AUTOTICKS ? m_extra_style &= wxSL_AUTOTICKS : m_extra_style |= wxSL_AUTOTICKS; }, ruler_mode_menu,
[]() { return true; }, [this]() { return m_extra_style & wxSL_AUTOTICKS; }, GUI::wxGetApp().plater());
append_menu_check_item(ruler_mode_menu, wxID_ANY, _L("Show estimated print time"), _L("Show estimated print time on the ruler"),
[this](wxCommandEvent&) { m_extra_style & wxSL_VALUE_LABEL ? m_extra_style &= wxSL_VALUE_LABEL : m_extra_style |= wxSL_VALUE_LABEL; }, ruler_mode_menu,
[]() { return true; }, [this]() { return m_extra_style & wxSL_VALUE_LABEL; }, GUI::wxGetApp().plater());
append_submenu(&menu, ruler_mode_menu, wxID_ANY, _L("Ruler mode"), _L("Set ruler mode"), "",
[this]() { return true; }, this);
}
if (m_mode == MultiAsSingle && m_draw_mode == dmRegular)
append_menu_item(&menu, wxID_ANY, _L("Set extruder sequence for the entire print"), "",
[this](wxCommandEvent&) { edit_extruder_sequence(); }, "", &menu);
GUI::wxGetApp().plater()->PopupMenu(&menu);
}

View file

@ -84,6 +84,13 @@ enum DrawMode
#endif // ENABLE_GCODE_VIEWER
};
enum LabelType
{
ltHeightWithLayer,
ltHeight,
ltEstimatedTime,
};
struct TickCode
{
bool operator<(const TickCode& other) const { return other.tick > this->tick; }
@ -212,11 +219,13 @@ public:
void SetMaxValue(const int max_value);
void SetKoefForLabels(const double koef) { m_label_koef = koef; }
void SetSliderValues(const std::vector<double>& values) { m_values = values; }
void SetSliderValues(const std::vector<double>& values);
void ChangeOneLayerLock();
Info GetTicksValues() const;
void SetTicksValues(const Info &custom_gcode_per_print_z);
Info GetTicksValues() const;
void SetTicksValues(const Info &custom_gcode_per_print_z);
void SetLayersTimes(const std::vector<float>& layers_times);
void SetLayersTimes(const std::vector<double>& layers_times);
void SetDrawMode(bool is_sla_print, bool is_sequential_print);
#if ENABLE_GCODE_VIEWER
@ -281,15 +290,17 @@ protected:
void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos);
void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection);
void draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos);
void draw_ticks_pair(wxDC& dc, wxCoord pos, wxCoord mid, int tick_len);
void draw_ticks(wxDC& dc);
void draw_colored_band(wxDC& dc);
void draw_ruler(wxDC& dc);
void draw_one_layer_icon(wxDC& dc);
void draw_revert_icon(wxDC& dc);
void draw_cog_icon(wxDC &dc);
void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection);
void draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, SelectedSlider selection);
void draw_tick_on_mouse_position(wxDC &dc);
void draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side = true) const;
void draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType label_type = ltHeight, bool right_side = true) const;
void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const;
void update_thumb_rect(const wxCoord begin_x, const wxCoord begin_y, const SelectedSlider& selection);
@ -306,7 +317,7 @@ private:
int get_tick_near_point(const wxPoint& pt);
double get_scroll_step();
wxString get_label(int tick) const;
wxString get_label(int tick, LabelType label_type = ltHeightWithLayer) const;
void get_lower_and_higher_position(int& lower_pos, int& higher_pos);
int get_value_from_position(const wxCoord x, const wxCoord y);
int get_value_from_position(const wxPoint pos) { return get_value_from_position(pos.x, pos.y); }
@ -387,10 +398,12 @@ private:
int m_revert_icon_dim;
int m_cog_icon_dim;
long m_style;
long m_extra_style;
float m_label_koef = 1.0;
std::vector<double> m_values;
TickCodeInfo m_ticks;
std::vector<double> m_layers_times;
std::vector<std::string> m_extruder_colors;
@ -407,6 +420,15 @@ private:
std::vector<wxPen*> m_line_pens;
std::vector<wxPen*> m_segm_pens;
struct Ruler {
double long_step;
double short_step;
int count { 1 }; // > 1 for sequential print
void update(wxWindow* win, const std::vector<double>& values, double scroll_step);
bool is_ok() { return long_step > 0 && short_step > 0; }
} m_ruler;
};
} // DoubleSlider;

View file

@ -1197,6 +1197,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
prev_up = up;
prev_length = length;
};
auto add_indices_as_solid = [](const GCodeProcessor::MoveVertex& prev, const GCodeProcessor::MoveVertex& curr, TBuffer& buffer,
size_t& buffer_vertices_size, unsigned int index_buffer_id, IndexBuffer& buffer_indices, size_t move_id) {
static Vec3f prev_dir;
@ -1339,6 +1340,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
// the data are deleted as soon as they are sent to the gpu.
std::vector<std::vector<float>> vertices(m_buffers.size());
std::vector<MultiIndexBuffer> indices(m_buffers.size());
#if ENABLE_SHOW_OPTION_POINT_LAYERS
std::vector<float> options_zs;
#endif // ENABLE_SHOW_OPTION_POINT_LAYERS
// toolpaths data -> extract vertices from result
for (size_t i = 0; i < m_moves_count; ++i) {
@ -1363,22 +1367,29 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
switch (buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point:
{
case TBuffer::ERenderPrimitiveType::Point: {
add_vertices_as_point(curr, buffer_vertices);
break;
}
case TBuffer::ERenderPrimitiveType::Line:
{
case TBuffer::ERenderPrimitiveType::Line: {
add_vertices_as_line(prev, curr, buffer, buffer_vertices);
break;
}
case TBuffer::ERenderPrimitiveType::Triangle:
{
case TBuffer::ERenderPrimitiveType::Triangle: {
add_vertices_as_solid(prev, curr, buffer, buffer_vertices, i);
break;
}
}
#if ENABLE_SHOW_OPTION_POINT_LAYERS
EMoveType type = buffer_type(id);
if (type == EMoveType::Pause_Print || type == EMoveType::Custom_GCode) {
const float* const last_z = options_zs.empty() ? nullptr : &options_zs.back();
float z = static_cast<double>(curr.position[2]);
if (last_z == nullptr || z < *last_z - EPSILON || *last_z + EPSILON < z)
options_zs.emplace_back(curr.position[2]);
}
#endif // ENABLE_SHOW_OPTION_POINT_LAYERS
}
log_memory_usage("Loaded G-code generated vertex buffers, ", vertices, indices);
@ -1464,18 +1475,15 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
switch (buffer.render_primitive_type)
{
case TBuffer::ERenderPrimitiveType::Point:
{
case TBuffer::ERenderPrimitiveType::Point: {
add_indices_as_point(curr, buffer, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
break;
}
case TBuffer::ERenderPrimitiveType::Line:
{
case TBuffer::ERenderPrimitiveType::Line: {
add_indices_as_line(prev, curr, buffer, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
break;
}
case TBuffer::ERenderPrimitiveType::Triangle:
{
case TBuffer::ERenderPrimitiveType::Triangle: {
add_indices_as_solid(prev, curr, buffer, curr_buffer_vertices_size, static_cast<unsigned int>(buffer_indices.size()) - 1, buffer_indices.back(), i);
break;
}
@ -1558,9 +1566,20 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
}
// set layers z range
if (!m_layers.empty()) {
if (!m_layers.empty())
m_layers_z_range = { 0, static_cast<unsigned int>(m_layers.size() - 1) };
#if ENABLE_SHOW_OPTION_POINT_LAYERS
// change color of paths whose layer contains option points
if (!options_zs.empty()) {
TBuffer& extrude_buffer = m_buffers[buffer_id(EMoveType::Extrude)];
for (Path& path : extrude_buffer.paths) {
float z = path.first.position[2];
if (std::find_if(options_zs.begin(), options_zs.end(), [z](float f) { return f - EPSILON <= z && z <= f + EPSILON; }) != options_zs.end())
path.cp_color_id = 255 - path.cp_color_id;
}
}
#endif // ENABLE_SHOW_OPTION_POINT_LAYERS
// roles -> remove duplicates
std::sort(m_roles.begin(), m_roles.end());
@ -1657,9 +1676,25 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; }
case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; }
case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; }
#if ENABLE_SHOW_OPTION_POINT_LAYERS
case EViewType::ColorPrint: {
if (path.cp_color_id >= static_cast<unsigned char>(m_tool_colors.size())) {
color = { 0.5f, 0.5f, 0.5f };
// // complementary color
// color = m_tool_colors[255 - path.cp_color_id];
// color = { 1.0f - color[0], 1.0f - color[1], 1.0f - color[2] };
}
else
color = m_tool_colors[path.cp_color_id];
break;
}
#else
case EViewType::ColorPrint: { color = m_tool_colors[path.cp_color_id]; break; }
#endif // ENABLE_SHOW_OPTION_POINT_LAYERS
default: { color = { 1.0f, 1.0f, 1.0f }; break; }
}
return color;
};

File diff suppressed because it is too large Load diff

View file

@ -12,10 +12,8 @@
#include "GUI_ObjectLayers.hpp"
#include "GLSelectionRectangle.hpp"
#include "MeshUtils.hpp"
#if ENABLE_GCODE_VIEWER
#include "libslic3r/GCode/GCodeProcessor.hpp"
#include "GCodeViewer.hpp"
#endif // ENABLE_GCODE_VIEWER
#include "libslic3r/Slicing.hpp"
@ -39,9 +37,6 @@ namespace Slic3r {
struct Camera;
class BackgroundSlicingProcess;
#if !ENABLE_GCODE_VIEWER
class GCodePreviewData;
#endif // !ENABLE_GCODE_VIEWER
struct ThumbnailData;
class ModelObject;
class ModelInstance;
@ -108,11 +103,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_BED_SHAPE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_TAB, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RESETGIZMOS, SimpleEvent);
#if ENABLE_GCODE_VIEWER
wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, wxKeyEvent);
#else
wxDECLARE_EVENT(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, wxKeyEvent);
#endif // ENABLE_GCODE_VIEWER
wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_JUMP_TO, wxKeyEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
@ -127,37 +118,6 @@ class GLCanvas3D
{
static const double DefaultCameraZoomToBoxMarginFactor;
public:
#if !ENABLE_GCODE_VIEWER
struct GCodePreviewVolumeIndex
{
enum EType
{
Extrusion,
Travel,
Retraction,
Unretraction,
Shell,
Num_Geometry_Types
};
struct FirstVolume
{
EType type;
unsigned int flag;
// Index of the first volume in a GLVolumeCollection.
unsigned int id;
FirstVolume(EType type, unsigned int flag, unsigned int id) : type(type), flag(flag), id(id) {}
};
std::vector<FirstVolume> first_volumes;
void reset() { first_volumes.clear(); }
};
#endif // !ENABLE_GCODE_VIEWER
private:
class LayersEditing
{
public:
@ -355,35 +315,6 @@ private:
bool generate(const std::string& msg, const GLCanvas3D& canvas, bool compress, bool red_colored = false);
};
#if !ENABLE_GCODE_VIEWER
class LegendTexture : public GUI::GLTexture
{
static const int Px_Title_Offset = 5;
static const int Px_Text_Offset = 5;
static const int Px_Square = 20;
static const int Px_Square_Contour = 1;
static const int Px_Border = Px_Square / 2;
static const unsigned char Squares_Border_Color[3];
static const unsigned char Default_Background_Color[3];
static const unsigned char Error_Background_Color[3];
static const unsigned char Opacity;
int m_original_width;
int m_original_height;
public:
LegendTexture();
void fill_color_print_legend_items(const GLCanvas3D& canvas,
const std::vector<float>& colors_in,
std::vector<float>& colors,
std::vector<std::string>& cp_legend_items);
bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool compress);
void render(const GLCanvas3D& canvas) const;
};
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_RENDER_STATISTICS
struct RenderStats
{
@ -450,6 +381,13 @@ public:
Cross
};
struct ArrangeSettings
{
float distance = 6.;
float accuracy = 0.65f;
bool enable_rotation = false;
};
private:
wxGLCanvas* m_canvas;
wxGLContext* m_context;
@ -457,9 +395,6 @@ private:
std::unique_ptr<RetinaHelper> m_retina_helper;
#endif
bool m_in_render;
#if !ENABLE_GCODE_VIEWER
LegendTexture m_legend_texture;
#endif // !ENABLE_GCODE_VIEWER
WarningTexture m_warning_texture;
wxTimer m_timer;
LayersEditing m_layers_editing;
@ -478,9 +413,7 @@ private:
bool m_event_handlers_bound{ false };
mutable GLVolumeCollection m_volumes;
#if ENABLE_GCODE_VIEWER
GCodeViewer m_gcode_viewer;
#endif // ENABLE_GCODE_VIEWER
Selection m_selection;
const DynamicPrintConfig* m_config;
@ -492,9 +425,6 @@ private:
bool m_initialized;
bool m_apply_zoom_to_volumes_filter;
mutable std::vector<int> m_hover_volume_idxs;
#if !ENABLE_GCODE_VIEWER
bool m_legend_texture_enabled;
#endif // !ENABLE_GCODE_VIEWER
bool m_picking_enabled;
bool m_moving_enabled;
bool m_dynamic_background_enabled;
@ -512,10 +442,6 @@ private:
bool m_reload_delayed;
#if !ENABLE_GCODE_VIEWER
GCodePreviewVolumeIndex m_gcode_preview_volume_index;
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_RENDER_PICKING_PASS
bool m_show_picking_texture;
#endif // ENABLE_RENDER_PICKING_PASS
@ -533,6 +459,8 @@ private:
mutable bool m_tooltip_enabled{ true };
Slope m_slope;
ArrangeSettings m_arrange_settings;
public:
explicit GLCanvas3D(wxGLCanvas* canvas);
~GLCanvas3D();
@ -554,11 +482,9 @@ public:
void reset_volumes();
int check_volumes_outside_state() const;
#if ENABLE_GCODE_VIEWER
void reset_gcode_toolpaths() { m_gcode_viewer.reset(); }
const GCodeViewer::SequentialView& get_gcode_sequential_view() const { return m_gcode_viewer.get_sequential_view(); }
void update_gcode_sequential_view_current(unsigned int first, unsigned int last) { m_gcode_viewer.update_sequential_view_current(first, last); }
#endif // ENABLE_GCODE_VIEWER
void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1);
@ -622,9 +548,7 @@ public:
void zoom_to_bed();
void zoom_to_volumes();
void zoom_to_selection();
#if ENABLE_GCODE_VIEWER
void zoom_to_gcode();
#endif // ENABLE_GCODE_VIEWER
void select_view(const std::string& direction);
void update_volumes_colors_by_extruder();
@ -641,7 +565,6 @@ public:
void delete_selected();
void ensure_on_bed(unsigned int object_idx);
#if ENABLE_GCODE_VIEWER
bool is_gcode_legend_enabled() const { return m_gcode_viewer.is_legend_enabled(); }
GCodeViewer::EViewType get_gcode_view_type() const { return m_gcode_viewer.get_view_type(); }
const std::vector<double>& get_gcode_layers_zs() const;
@ -653,9 +576,6 @@ public:
void set_toolpath_view_type(GCodeViewer::EViewType type);
void set_volumes_z_range(const std::array<double, 2>& range);
void set_toolpaths_z_range(const std::array<unsigned int, 2>& range);
#else
std::vector<double> get_current_print_zs(bool active_only) const;
#endif // ENABLE_GCODE_VIEWER
void set_toolpaths_range(double low, double high);
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
@ -665,14 +585,10 @@ public:
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
#if ENABLE_GCODE_VIEWER
void load_gcode_preview(const GCodeProcessor::Result& gcode_result);
void refresh_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors);
void set_gcode_view_preview_type(GCodeViewer::EViewType type) { return m_gcode_viewer.set_view_type(type); }
GCodeViewer::EViewType get_gcode_view_preview_type() const { return m_gcode_viewer.get_view_type(); }
#else
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
#endif // ENABLE_GCODE_VIEWER
void load_sla_preview();
void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<CustomGCode::Item>& color_print_values);
void bind_event_handlers();
@ -691,10 +607,6 @@ public:
Size get_canvas_size() const;
Vec2d get_local_mouse_position() const;
#if !ENABLE_GCODE_VIEWER
void reset_legend_texture();
#endif // !ENABLE_GCODE_VIEWER
void set_tooltip(const std::string& tooltip) const;
// the following methods add a snapshot to the undo/redo stack, unless the given string is empty
@ -768,6 +680,8 @@ public:
void use_slope(bool use) { m_slope.use(use); }
void set_slope_normal_angle(float angle_in_deg) { m_slope.set_normal_angle(angle_in_deg); }
const ArrangeSettings& get_arrange_settings() const { return m_arrange_settings; }
private:
bool _is_shown_on_screen() const;
@ -792,9 +706,7 @@ private:
void _render_background() const;
void _render_bed(bool bottom, bool show_axes) const;
void _render_objects() const;
#if ENABLE_GCODE_VIEWER
void _render_gcode() const;
#endif // ENABLE_GCODE_VIEWER
void _render_selection() const;
#if ENABLE_RENDER_SELECTION_CENTER
void _render_selection_center() const;
@ -802,9 +714,6 @@ private:
void _check_and_update_toolbar_icon_scale() const;
void _render_overlays() const;
void _render_warning_texture() const;
#if !ENABLE_GCODE_VIEWER
void _render_legend_texture() const;
#endif // !ENABLE_GCODE_VIEWER
void _render_volumes_for_picking() const;
void _render_current_gizmo() const;
void _render_gizmos_overlay() const;
@ -819,6 +728,7 @@ private:
void _render_selection_sidebar_hints() const;
bool _render_undo_redo_stack(const bool is_undo, float pos_x) const;
bool _render_search_list(float pos_x) const;
void _render_arrange_popup();
void _render_thumbnail_internal(ThumbnailData& thumbnail_data, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
// render thumbnail using an off-screen framebuffer
void _render_thumbnail_framebuffer(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) const;
@ -852,29 +762,12 @@ private:
// Create 3D thick extrusion lines for wipe tower extrusions
void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
#if !ENABLE_GCODE_VIEWER
// generates gcode extrusion paths geometry
void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates gcode travel paths geometry
void _load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates objects and wipe tower geometry
void _load_fff_shells();
#endif // !ENABLE_GCODE_VIEWER
// Load SLA objects and support structures for objects, for which the slaposSliceSupports step has been finished.
void _load_sla_shells();
#if !ENABLE_GCODE_VIEWER
// sets gcode geometry visibility according to user selection
void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data);
#endif // !ENABLE_GCODE_VIEWER
void _update_toolpath_volumes_outside_state();
void _update_sla_shells_outside_state();
void _show_warning_texture_if_needed(WarningTexture::Warning warning);
#if !ENABLE_GCODE_VIEWER
// generates the legend texture in dependence of the current shown view type
void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
#endif // !ENABLE_GCODE_VIEWER
// generates a warning texture containing the given message
void _set_warning_texture(WarningTexture::Warning warning, bool state);

View file

@ -177,11 +177,7 @@ public:
// load bitmap for logo
BitmapCache bmp_cache;
int logo_size = lround(width * 0.25);
#if ENABLE_GCODE_VIEWER
wxBitmap logo_bmp = *bmp_cache.load_svg(wxGetApp().is_editor() ? "prusa_slicer_logo" : "add_gcode", logo_size, logo_size);
#else
wxBitmap logo_bmp = *bmp_cache.load_svg("prusa_slicer_logo", logo_size, logo_size);
#endif // ENABLE_GCODE_VIEWER
wxCoord margin = int(m_scale * 20);
@ -229,11 +225,7 @@ private:
void init(wxFont init_font)
{
// title
#if ENABLE_GCODE_VIEWER
title = wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME;
#else
title = SLIC3R_APP_NAME;
#endif // ENABLE_GCODE_VIEWER
// dynamically get the version to display
version = _L("Version") + " " + std::string(SLIC3R_VERSION);
@ -601,13 +593,11 @@ void GUI_App::post_init()
if (! this->initialized())
throw Slic3r::RuntimeError("Calling post_init() while not yet initialized");
#if ENABLE_GCODE_VIEWER
if (this->init_params->start_as_gcodeviewer) {
if (! this->init_params->input_files.empty())
this->plater()->load_gcode(wxString::FromUTF8(this->init_params->input_files[0].c_str()));
}
else {
#endif // ENABLE_GCODE_VIEWER_AS
#if 0
// Load the cummulative config over the currently active profiles.
//FIXME if multiple configs are loaded, only the last one will have an effect.
@ -626,22 +616,14 @@ void GUI_App::post_init()
this->plater()->load_files(this->init_params->input_files, true, true);
if (! this->init_params->extra_config.empty())
this->mainframe->load_config(this->init_params->extra_config);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
}
IMPLEMENT_APP(GUI_App)
#if ENABLE_GCODE_VIEWER
GUI_App::GUI_App(EAppMode mode)
#else
GUI_App::GUI_App()
#endif // ENABLE_GCODE_VIEWER
: wxApp()
#if ENABLE_GCODE_VIEWER
, m_app_mode(mode)
#endif // ENABLE_GCODE_VIEWER
, m_em_unit(10)
, m_imgui(new ImGuiWrapper())
, m_wizard(nullptr)
@ -705,11 +687,7 @@ void GUI_App::init_app_config()
}
if (!app_config)
#if ENABLE_GCODE_VIEWER
app_config = new AppConfig(is_editor() ? AppConfig::EAppMode::Editor : AppConfig::EAppMode::GCodeViewer);
#else
app_config = new AppConfig();
#endif // ENABLE_GCODE_VIEWER
// load settings
m_app_conf_exists = app_config->exists();
@ -717,7 +695,6 @@ void GUI_App::init_app_config()
std::string error = app_config->load();
if (!error.empty()) {
// Error while parsing config file. We'll customize the error message and rethrow to be displayed.
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
throw Slic3r::RuntimeError(
_u8L("Error parsing PrusaSlicer config file, it is probably corrupted. "
@ -725,14 +702,11 @@ void GUI_App::init_app_config()
"\n\n" + app_config->config_path() + "\n\n" + error);
}
else {
#endif // ENABLE_GCODE_VIEWER
throw Slic3r::RuntimeError(
_u8L("Error parsing PrusaGCodeViewer config file, it is probably corrupted. "
"Try to manually delete the file to recover from the error.") +
"\n\n" + app_config->config_path() + "\n\n" + error);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
}
}
}
@ -775,9 +749,7 @@ bool GUI_App::on_init_inner()
// Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
#endif // ENABLE_GCODE_VIEWER
std::string msg = Http::tls_global_init();
std::string ssl_cert_store = app_config->get("tls_accepted_cert_store_location");
bool ssl_accept = app_config->get("tls_cert_store_accepted") == "yes" && ssl_cert_store == Http::tls_system_cert_store();
@ -795,9 +767,7 @@ bool GUI_App::on_init_inner()
app_config->set("tls_accepted_cert_store_location",
dlg.IsCheckBoxChecked() ? Http::tls_system_cert_store() : "");
}
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
app_config->set("version", SLIC3R_VERSION);
app_config->save();
@ -807,11 +777,7 @@ bool GUI_App::on_init_inner()
SplashScreen* scrn = nullptr;
if (app_config->get("show_splash_screen") == "1") {
// make a bitmap with dark grey banner on the left side
#if ENABLE_GCODE_VIEWER
wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var(is_editor() ? "splashscreen.jpg" : "splashscreen-gcodepreview.jpg")), wxBITMAP_TYPE_JPEG));
#else
wxBitmap bmp = SplashScreen::MakeBitmap(wxBitmap(from_u8(var("splashscreen.jpg")), wxBITMAP_TYPE_JPEG));
#endif // ENABLE_GCODE_VIEWER
// Detect position (display) to show the splash screen
// Now this position is equal to the mainframe position
@ -825,8 +791,10 @@ bool GUI_App::on_init_inner()
// create splash screen with updated bmp
scrn = new SplashScreen(bmp.IsOk() ? bmp : create_scaled_bitmap("prusa_slicer_logo", nullptr, 400),
wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, 4000, splashscreen_pos);
#ifndef __linux__
wxYield();
scrn->SetText(_L("Loading configuration..."));
#endif
scrn->SetText(_L("Loading configuration")+ dots);
}
preset_bundle = new PresetBundle();
@ -835,9 +803,7 @@ bool GUI_App::on_init_inner()
// supplied as argument to --datadir; in that case we should still run the wizard
preset_bundle->setup_directories();
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
#endif // ENABLE_GCODE_VIEWER
#ifdef __WXMSW__
associate_3mf_files();
#endif // __WXMSW__
@ -852,14 +818,12 @@ bool GUI_App::on_init_inner()
}
}
});
#if ENABLE_GCODE_VIEWER
}
else {
#ifdef __WXMSW__
associate_gcode_files();
#endif // __WXMSW__
}
#endif // ENABLE_GCODE_VIEWER
// initialize label colors and fonts
init_label_colours();
@ -887,18 +851,12 @@ bool GUI_App::on_init_inner()
Slic3r::I18N::set_translate_callback(libslic3r_translate_callback);
// application frame
#if ENABLE_GCODE_VIEWER
if (scrn && is_editor())
#else
if (scrn)
#endif // ENABLE_GCODE_VIEWER
scrn->SetText(_L("Preparing settings tabs..."));
scrn->SetText(_L("Preparing settings tabs") + dots);
mainframe = new MainFrame();
// hide settings tabs after first Layout
#if ENABLE_GCODE_VIEWER
if (is_editor())
#endif // ENABLE_GCODE_VIEWER
mainframe->select_tab(size_t(0));
sidebar().obj_list()->init_objects(); // propagate model objects to object list
@ -939,9 +897,7 @@ bool GUI_App::on_init_inner()
if (once) {
once = false;
#if ENABLE_GCODE_VIEWER
if (preset_updater != nullptr) {
#endif // ENABLE_GCODE_VIEWER
check_updates(false);
CallAfter([this] {
@ -949,9 +905,7 @@ bool GUI_App::on_init_inner()
preset_updater->slic3r_update_notify();
preset_updater->sync(preset_bundle);
});
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
#ifdef _WIN32
//sets window property to mainframe so other instances can indentify it
@ -960,7 +914,6 @@ bool GUI_App::on_init_inner()
}
});
#if ENABLE_GCODE_VIEWER
if (is_gcode_viewer()) {
mainframe->update_layout();
if (plater_ != nullptr)
@ -968,7 +921,6 @@ bool GUI_App::on_init_inner()
plater_->set_printer_technology(ptFFF);
}
else
#endif // ENABLE_GCODE_VIEWER
load_current_presets();
mainframe->Show(true);
@ -1161,9 +1113,7 @@ void GUI_App::check_printer_presets()
void GUI_App::recreate_GUI(const wxString& msg_name)
{
#if ENABLE_GCODE_VIEWER
m_is_recreating_gui = true;
#endif // ENABLE_GCODE_VIEWER
mainframe->shutdown();
@ -1173,9 +1123,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
MainFrame *old_main_frame = mainframe;
mainframe = new MainFrame();
#if ENABLE_GCODE_VIEWER
if (is_editor())
#endif // ENABLE_GCODE_VIEWER
// hide settings tabs after first Layout
mainframe->select_tab(size_t(0));
// Propagate model objects to object list.
@ -1208,9 +1156,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
// config_wizard_startup(true);
// });
#if ENABLE_GCODE_VIEWER
m_is_recreating_gui = false;
#endif // ENABLE_GCODE_VIEWER
}
void GUI_App::system_info()
@ -1295,7 +1241,6 @@ void GUI_App::import_model(wxWindow *parent, wxArrayString& input_files) const
dialog.GetPaths(input_files);
}
#if ENABLE_GCODE_VIEWER
void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const
{
input_file.Clear();
@ -1307,7 +1252,6 @@ void GUI_App::load_gcode(wxWindow* parent, wxString& input_file) const
if (dialog.ShowModal() == wxID_OK)
input_file = dialog.GetPath();
}
#endif // ENABLE_GCODE_VIEWER
bool GUI_App::switch_language()
{
@ -1543,17 +1487,13 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
const auto config_wizard_name = _(ConfigWizard::name(true));
const auto config_wizard_tooltip = from_u8((boost::format(_utf8(L("Run %s"))) % config_wizard_name).str());
// Cmd+, is standard on OS X - what about other operating systems?
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
#endif // ENABLE_GCODE_VIEWER
local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip);
local_menu->Append(config_id_base + ConfigMenuSnapshots, _L("&Configuration Snapshots") + dots, _L("Inspect / activate configuration snapshots"));
local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _L("Take Configuration &Snapshot"), _L("Capture a configuration snapshot"));
local_menu->Append(config_id_base + ConfigMenuUpdate, _L("Check for updates"), _L("Check for configuration updates"));
local_menu->AppendSeparator();
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
local_menu->Append(config_id_base + ConfigMenuPreferences, _L("&Preferences") + dots +
#ifdef __APPLE__
"\tCtrl+,",
@ -1561,16 +1501,10 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
"\tCtrl+P",
#endif
_L("Application preferences"));
#if ENABLE_GCODE_VIEWER
wxMenu* mode_menu = nullptr;
if (is_editor()) {
#endif // ENABLE_GCODE_VIEWER
local_menu->AppendSeparator();
#if ENABLE_GCODE_VIEWER
mode_menu = new wxMenu();
#else
auto mode_menu = new wxMenu();
#endif // ENABLE_GCODE_VIEWER
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _L("Simple"), _L("Simple View Mode"));
// mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _L("Advanced"), _L("Advanced View Mode"));
mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _CTX(L_CONTEXT("Advanced", "Mode"), "Mode"), _L("Advanced View Mode"));
@ -1580,21 +1514,15 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comExpert) evt.Check(true); }, config_id_base + ConfigMenuModeExpert);
local_menu->AppendSubMenu(mode_menu, _L("Mode"), wxString::Format(_L("%s View Mode"), SLIC3R_APP_NAME));
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
local_menu->AppendSeparator();
local_menu->Append(config_id_base + ConfigMenuLanguage, _L("&Language"));
#if ENABLE_GCODE_VIEWER
if (is_editor()) {
#endif // ENABLE_GCODE_VIEWER
local_menu->AppendSeparator();
local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _L("Flash printer &firmware"), _L("Upload a firmware image into an Arduino based printer"));
// TODO: for when we're able to flash dictionaries
// local_menu->Append(config_id_base + FirmwareMenuDict, _L("Flash language file"), _L("Upload a language dictionary file into a Prusa printer"));
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
switch (event.GetId() - config_id_base) {
@ -1648,10 +1576,8 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
PreferencesDialog dlg(mainframe);
dlg.ShowModal();
app_layout_changed = dlg.settings_layout_changed();
#if ENABLE_GCODE_VIEWER
if (dlg.seq_top_layer_only_changed())
this->plater_->refresh_print();
#endif // ENABLE_GCODE_VIEWER
}
if (app_layout_changed) {
// hide full main_sizer for mainFrame
@ -1670,19 +1596,13 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// the dialog needs to be destroyed before the call to switch_language()
// or sometimes the application crashes into wxDialogBase() destructor
// so we put it into an inner scope
#if ENABLE_GCODE_VIEWER
wxString title = is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME);
title += " - " + _L("Language selection");
#endif // ENABLE_GCODE_VIEWER
wxMessageDialog dialog(nullptr,
_L("Switching the language will trigger application restart.\n"
"You will lose content of the plater.") + "\n\n" +
_L("Do you want to proceed?"),
#if ENABLE_GCODE_VIEWER
title,
#else
wxString(SLIC3R_APP_NAME) + " - " + _L("Language selection"),
#endif // ENABLE_GCODE_VIEWER
wxICON_QUESTION | wxOK | wxCANCEL);
if (dialog.ShowModal() == wxID_CANCEL)
return;
@ -1701,16 +1621,12 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
using std::placeholders::_1;
#if ENABLE_GCODE_VIEWER
if (mode_menu != nullptr) {
#endif // ENABLE_GCODE_VIEWER
auto modfn = [this](int mode, wxCommandEvent&) { if (get_mode() != mode) save_mode(mode); };
mode_menu->Bind(wxEVT_MENU, std::bind(modfn, comSimple, _1), config_id_base + ConfigMenuModeSimple);
mode_menu->Bind(wxEVT_MENU, std::bind(modfn, comAdvanced, _1), config_id_base + ConfigMenuModeAdvanced);
mode_menu->Bind(wxEVT_MENU, std::bind(modfn, comExpert, _1), config_id_base + ConfigMenuModeExpert);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
menu->Append(local_menu, _L("&Configuration"));
}

View file

@ -97,7 +97,6 @@ static wxString dots("…", wxConvUTF8);
class GUI_App : public wxApp
{
#if ENABLE_GCODE_VIEWER
public:
enum class EAppMode : unsigned char
{
@ -106,14 +105,10 @@ public:
};
private:
#endif // ENABLE_GCODE_VIEWER
bool m_initialized { false };
bool m_app_conf_exists{ false };
#if ENABLE_GCODE_VIEWER
EAppMode m_app_mode{ EAppMode::Editor };
bool m_is_recreating_gui{ false };
#endif // ENABLE_GCODE_VIEWER
wxColour m_color_label_modified;
wxColour m_color_label_sys;
@ -149,19 +144,13 @@ public:
bool OnInit() override;
bool initialized() const { return m_initialized; }
#if ENABLE_GCODE_VIEWER
explicit GUI_App(EAppMode mode = EAppMode::Editor);
#else
GUI_App();
#endif // ENABLE_GCODE_VIEWER
~GUI_App() override;
#if ENABLE_GCODE_VIEWER
EAppMode get_app_mode() const { return m_app_mode; }
bool is_editor() const { return m_app_mode == EAppMode::Editor; }
bool is_gcode_viewer() const { return m_app_mode == EAppMode::GCodeViewer; }
bool is_recreating_gui() const { return m_is_recreating_gui; }
#endif // ENABLE_GCODE_VIEWER
// To be called after the GUI is fully built up.
// Process command line parameters cached in this->init_params,
@ -199,9 +188,7 @@ public:
void keyboard_shortcuts();
void load_project(wxWindow *parent, wxString& input_file) const;
void import_model(wxWindow *parent, wxArrayString& input_files) const;
#if ENABLE_GCODE_VIEWER
void load_gcode(wxWindow* parent, wxString& input_file) const;
#endif // ENABLE_GCODE_VIEWER
static bool catch_error(std::function<void()> cb, const std::string& err);

View file

@ -22,7 +22,6 @@ namespace GUI {
int GUI_Run(GUI_InitParams &params)
{
try {
#if ENABLE_GCODE_VIEWER
GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {
// G-code viewer is currently not performing instance check, a new G-code viewer is started every time.
@ -32,29 +31,20 @@ int GUI_Run(GUI_InitParams &params)
return -1;
}
}
#else
GUI::GUI_App *gui = new GUI::GUI_App();
#endif // ENABLE_GCODE_VIEWER
// gui->autosave = m_config.opt_string("autosave");
GUI::GUI_App::SetInstance(gui);
gui->init_params = &params;
/*
#if ENABLE_GCODE_VIEWER
gui->CallAfter([gui, this, &load_configs, params.start_as_gcodeviewer] {
#else
gui->CallAfter([gui, this, &load_configs] {
#endif // ENABLE_GCODE_VIEWER
if (!gui->initialized()) {
return;
}
#if ENABLE_GCODE_VIEWER
if (params.start_as_gcodeviewer) {
if (!m_input_files.empty())
gui->plater()->load_gcode(wxString::FromUTF8(m_input_files[0].c_str()));
} else {
#endif // ENABLE_GCODE_VIEWER_AS
#if 0
// Load the cummulative config over the currently active profiles.
//FIXME if multiple configs are loaded, only the last one will have an effect.
@ -73,9 +63,7 @@ int GUI_Run(GUI_InitParams &params)
gui->plater()->load_files(m_input_files, true, true);
if (!m_extra_config.empty())
gui->mainframe->load_config(m_extra_config);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
});
*/
int result = wxEntry(params.argc, params.argv);

View file

@ -10,9 +10,7 @@
#include "libslic3r/PresetBundle.hpp"
#include "DoubleSlider.hpp"
#include "Plater.hpp"
#if ENABLE_GCODE_VIEWER
#include "MainFrame.hpp"
#endif // ENABLE_GCODE_VIEWER
#include <wx/notebook.h>
#include <wx/glcanvas.h>
@ -168,62 +166,33 @@ void View3D::render()
m_canvas->set_as_dirty();
}
#if ENABLE_GCODE_VIEWER
Preview::Preview(
wxWindow* parent, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process_func)
#else
Preview::Preview(
wxWindow* parent, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
#endif // ENABLE_GCODE_VIEWER
: m_canvas_widget(nullptr)
, m_canvas(nullptr)
#if ENABLE_GCODE_VIEWER
, m_left_sizer(nullptr)
, m_layers_slider_sizer(nullptr)
, m_bottom_toolbar_panel(nullptr)
#else
, m_double_slider_sizer(nullptr)
#endif // ENABLE_GCODE_VIEWER
, m_label_view_type(nullptr)
, m_choice_view_type(nullptr)
, m_label_show(nullptr)
, m_combochecklist_features(nullptr)
#if ENABLE_GCODE_VIEWER
, m_combochecklist_features_pos(0)
, m_combochecklist_options(nullptr)
#else
, m_checkbox_travel(nullptr)
, m_checkbox_retractions(nullptr)
, m_checkbox_unretractions(nullptr)
, m_checkbox_shells(nullptr)
, m_checkbox_legend(nullptr)
#endif // ENABLE_GCODE_VIEWER
, m_config(config)
, m_process(process)
#if ENABLE_GCODE_VIEWER
, m_gcode_result(gcode_result)
#else
, m_gcode_preview_data(gcode_preview_data)
#endif // ENABLE_GCODE_VIEWER
, m_number_extruders(1)
, m_preferred_color_mode("feature")
, m_loaded(false)
#if !ENABLE_GCODE_VIEWER
, m_enabled(false)
#endif // !ENABLE_GCODE_VIEWER
, m_schedule_background_process(schedule_background_process_func)
#ifdef __linux__
, m_volumes_cleanup_required(false)
#endif // __linux__
{
if (init(parent, model)) {
#if !ENABLE_GCODE_VIEWER
show_hide_ui_elements("none");
#endif // !ENABLE_GCODE_VIEWER
if (init(parent, model))
load_print();
}
}
bool Preview::init(wxWindow* parent, Model* model)
@ -231,14 +200,12 @@ bool Preview::init(wxWindow* parent, Model* model)
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false;
#if ENABLE_GCODE_VIEWER
// to match the background of the sliders
#ifdef _WIN32
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
#else
SetBackgroundColour(GetParent()->GetBackgroundColour());
#endif // _WIN32
#endif // ENABLE_GCODE_VIEWER
m_canvas_widget = OpenGLManager::create_wxglcanvas(*this);
if (m_canvas_widget == nullptr)
@ -253,20 +220,11 @@ bool Preview::init(wxWindow* parent, Model* model)
m_canvas->enable_legend_texture(true);
m_canvas->enable_dynamic_background(true);
#if ENABLE_GCODE_VIEWER
m_layers_slider_sizer = create_layers_slider_sizer();
m_bottom_toolbar_panel = new wxPanel(this);
m_label_view_type = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("View"));
m_choice_view_type = new wxChoice(m_bottom_toolbar_panel, wxID_ANY);
#else
m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL);
create_double_slider();
m_label_view_type = new wxStaticText(this, wxID_ANY, _L("View"));
m_choice_view_type = new wxChoice(this, wxID_ANY);
#endif // ENABLE_GCODE_VIEWER
m_choice_view_type->Append(_L("Feature type"));
m_choice_view_type->Append(_L("Height"));
m_choice_view_type->Append(_L("Width"));
@ -277,22 +235,12 @@ bool Preview::init(wxWindow* parent, Model* model)
m_choice_view_type->Append(_L("Color Print"));
m_choice_view_type->SetSelection(0);
#if ENABLE_GCODE_VIEWER
m_label_show = new wxStaticText(m_bottom_toolbar_panel, wxID_ANY, _L("Show"));
#else
m_label_show = new wxStaticText(this, wxID_ANY, _L("Show"));
#endif // ENABLE_GCODE_VIEWER
m_combochecklist_features = new wxComboCtrl();
#if ENABLE_GCODE_VIEWER
m_combochecklist_features->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
#else
m_combochecklist_features->Create(this, wxID_ANY, _L("Feature types"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
#endif // ENABLE_GCODE_VIEWER
std::string feature_items = GUI::into_u8(
#if ENABLE_GCODE_VIEWER
_L("Unknown") + "|1|" +
#endif // ENABLE_GCODE_VIEWER
_L("Perimeter") + "|1|" +
_L("External perimeter") + "|1|" +
_L("Overhang perimeter") + "|1|" +
@ -310,7 +258,6 @@ bool Preview::init(wxWindow* parent, Model* model)
);
Slic3r::GUI::create_combochecklist(m_combochecklist_features, GUI::into_u8(_L("Feature types")), feature_items);
#if ENABLE_GCODE_VIEWER
m_combochecklist_options = new wxComboCtrl();
m_combochecklist_options->Create(m_bottom_toolbar_panel, wxID_ANY, _L("Options"), wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
std::string options_items = GUI::into_u8(
@ -324,18 +271,9 @@ bool Preview::init(wxWindow* parent, Model* model)
get_option_type_string(OptionType::Shells) + "|0|" +
get_option_type_string(OptionType::ToolMarker) + "|1|" +
get_option_type_string(OptionType::Legend) + "|1"
);
);
Slic3r::GUI::create_combochecklist(m_combochecklist_options, GUI::into_u8(_L("Options")), options_items);
#else
m_checkbox_travel = new wxCheckBox(this, wxID_ANY, _L("Travel"));
m_checkbox_retractions = new wxCheckBox(this, wxID_ANY, _L("Retractions"));
m_checkbox_unretractions = new wxCheckBox(this, wxID_ANY, _L("Deretractions"));
m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _L("Shells"));
m_checkbox_legend = new wxCheckBox(this, wxID_ANY, _L("Legend"));
m_checkbox_legend->SetValue(true);
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
m_left_sizer = new wxBoxSizer(wxVERTICAL);
m_left_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
@ -366,32 +304,6 @@ bool Preview::init(wxWindow* parent, Model* model)
wxBoxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
main_sizer->Add(m_left_sizer, 1, wxALL | wxEXPAND, 0);
main_sizer->Add(right_sizer, 0, wxALL | wxEXPAND, 0);
#else
wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL);
top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0);
wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
bottom_sizer->Add(m_label_view_type, 0, wxALIGN_CENTER_VERTICAL, 5);
bottom_sizer->Add(m_choice_view_type, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(10);
bottom_sizer->Add(m_label_show, 0, wxALIGN_CENTER_VERTICAL, 5);
bottom_sizer->Add(m_combochecklist_features, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(20);
bottom_sizer->Add(m_checkbox_travel, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(10);
bottom_sizer->Add(m_checkbox_retractions, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(10);
bottom_sizer->Add(m_checkbox_unretractions, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(10);
bottom_sizer->Add(m_checkbox_shells, 0, wxEXPAND | wxALL, 5);
bottom_sizer->AddSpacer(20);
bottom_sizer->Add(m_checkbox_legend, 0, wxEXPAND | wxALL, 5);
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(top_sizer, 1, wxALL | wxEXPAND, 0);
main_sizer->Add(bottom_sizer, 0, wxALL | wxEXPAND, 0);
#endif // ENABLE_GCODE_VIEWER
SetSizer(main_sizer);
SetMinSize(GetSize());
@ -399,26 +311,6 @@ bool Preview::init(wxWindow* parent, Model* model)
bind_event_handlers();
#if !ENABLE_GCODE_VIEWER
// sets colors for gcode preview extrusion roles
std::vector<std::string> extrusion_roles_colors = {
"Perimeter", "FFFF66",
"External perimeter", "FFA500",
"Overhang perimeter", "0000FF",
"Internal infill", "B1302A",
"Solid infill", "D732D7",
"Top solid infill", "FF1A1A",
"Bridge infill", "9999FF",
"Gap fill", "FFFFFF",
"Skirt", "845321",
"Support material", "00FF00",
"Support material interface", "008000",
"Wipe tower", "B3E3AB",
"Custom", "28CC94"
};
m_gcode_preview_data->set_extrusion_paths_colors(extrusion_roles_colors);
#endif // !ENABLE_GCODE_VIEWER
return true;
}
@ -441,31 +333,18 @@ void Preview::set_as_dirty()
void Preview::set_number_extruders(unsigned int number_extruders)
{
if (m_number_extruders != number_extruders)
{
if (m_number_extruders != number_extruders) {
m_number_extruders = number_extruders;
int tool_idx = m_choice_view_type->FindString(_(L("Tool")));
int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type
m_choice_view_type->SetSelection(type);
#if ENABLE_GCODE_VIEWER
if ((0 <= type) && (type < static_cast<int>(GCodeViewer::EViewType::Count)))
if (0 <= type && (type < static_cast<int>(GCodeViewer::EViewType::Count)))
m_canvas->set_gcode_view_preview_type(static_cast<GCodeViewer::EViewType>(type));
#else
if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types))
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
#endif // ENABLE_GCODE_VIEWER
m_preferred_color_mode = (type == tool_idx) ? "tool_or_feature" : "feature";
}
}
#if !ENABLE_GCODE_VIEWER
void Preview::set_enabled(bool enabled)
{
m_enabled = enabled;
}
#endif // !ENABLE_GCODE_VIEWER
void Preview::bed_shape_changed()
{
if (m_canvas != nullptr)
@ -491,9 +370,7 @@ void Preview::load_print(bool keep_z_range)
else if (tech == ptSLA)
load_print_as_sla();
#if ENABLE_GCODE_VIEWER
update_bottom_toolbar();
#endif // ENABLE_GCODE_VIEWER
Layout();
}
@ -515,9 +392,6 @@ void Preview::reload_print(bool keep_volumes)
!keep_volumes)
{
m_canvas->reset_volumes();
#if !ENABLE_GCODE_VIEWER
m_canvas->reset_legend_texture();
#endif // !ENABLE_GCODE_VIEWER
m_loaded = false;
#ifdef __linux__
m_volumes_cleanup_required = false;
@ -540,12 +414,8 @@ void Preview::refresh_print()
void Preview::msw_rescale()
{
// rescale slider
#if ENABLE_GCODE_VIEWER
if (m_layers_slider != nullptr) m_layers_slider->msw_rescale();
if (m_moves_slider != nullptr) m_moves_slider->msw_rescale();
#else
if (m_slider) m_slider->msw_rescale();
#endif // ENABLE_GCODE_VIEWER
// rescale warning legend on the canvas
get_canvas3d()->msw_rescale();
@ -556,55 +426,26 @@ void Preview::msw_rescale()
void Preview::jump_layers_slider(wxKeyEvent& evt)
{
#if ENABLE_GCODE_VIEWER
if (m_layers_slider) m_layers_slider->OnChar(evt);
#else
if (m_slider)
m_slider->OnKeyDown(evt);
#endif // ENABLE_GCODE_VIEWER
}
#if ENABLE_GCODE_VIEWER
void Preview::move_layers_slider(wxKeyEvent& evt)
{
if (m_layers_slider != nullptr) m_layers_slider->OnKeyDown(evt);
}
#else
void Preview::move_double_slider(wxKeyEvent& evt)
{
if (m_slider)
m_slider->OnKeyDown(evt);
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Preview::edit_layers_slider(wxKeyEvent& evt)
{
if (m_layers_slider != nullptr) m_layers_slider->OnChar(evt);
}
#else
void Preview::edit_double_slider(wxKeyEvent& evt)
{
if (m_slider)
m_slider->OnChar(evt);
}
#endif // ENABLE_GCODE_VIEWER
void Preview::bind_event_handlers()
{
this->Bind(wxEVT_SIZE, &Preview::on_size, this);
m_choice_view_type->Bind(wxEVT_CHOICE, &Preview::on_choice_view_type, this);
m_combochecklist_features->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
#if ENABLE_GCODE_VIEWER
m_combochecklist_options->Bind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
m_moves_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
#else
m_checkbox_travel->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this);
m_checkbox_retractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this);
m_checkbox_unretractions->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this);
m_checkbox_shells->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this);
m_checkbox_legend->Bind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this);
#endif // ENABLE_GCODE_VIEWER
}
void Preview::unbind_event_handlers()
@ -612,76 +453,15 @@ void Preview::unbind_event_handlers()
this->Unbind(wxEVT_SIZE, &Preview::on_size, this);
m_choice_view_type->Unbind(wxEVT_CHOICE, &Preview::on_choice_view_type, this);
m_combochecklist_features->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_features, this);
#if ENABLE_GCODE_VIEWER
m_combochecklist_options->Unbind(wxEVT_CHECKLISTBOX, &Preview::on_combochecklist_options, this);
m_moves_slider->Unbind(wxEVT_SCROLL_CHANGED, &Preview::on_moves_slider_scroll_changed, this);
#else
m_checkbox_travel->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_travel, this);
m_checkbox_retractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_retractions, this);
m_checkbox_unretractions->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_unretractions, this);
m_checkbox_shells->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_shells, this);
m_checkbox_legend->Unbind(wxEVT_CHECKBOX, &Preview::on_checkbox_legend, this);
#endif // ENABLE_GCODE_VIEWER
}
#if !ENABLE_GCODE_VIEWER
void Preview::show_hide_ui_elements(const std::string& what)
{
bool enable = (what == "full");
m_label_show->Enable(enable);
m_combochecklist_features->Enable(enable);
m_checkbox_travel->Enable(enable);
m_checkbox_retractions->Enable(enable);
m_checkbox_unretractions->Enable(enable);
m_checkbox_shells->Enable(enable);
m_checkbox_legend->Enable(enable);
enable = (what != "none");
m_label_view_type->Enable(enable);
m_choice_view_type->Enable(enable);
bool visible = (what != "none");
m_label_show->Show(visible);
m_combochecklist_features->Show(visible);
m_checkbox_travel->Show(visible);
m_checkbox_retractions->Show(visible);
m_checkbox_unretractions->Show(visible);
m_checkbox_shells->Show(visible);
m_checkbox_legend->Show(visible);
m_label_view_type->Show(visible);
m_choice_view_type->Show(visible);
}
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Preview::hide_layers_slider()
{
m_layers_slider_sizer->Hide((size_t)0);
Layout();
}
#else
void Preview::reset_sliders(bool reset_all)
{
m_enabled = false;
// reset_double_slider();
if (reset_all)
m_double_slider_sizer->Hide((size_t)0);
else
m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide(1);
}
#endif // ENABLE_GCODE_VIEWER
#if !ENABLE_GCODE_VIEWER
void Preview::update_sliders(const std::vector<double>& layers_z, bool keep_z_range)
{
m_enabled = true;
update_double_slider(layers_z, keep_z_range);
m_double_slider_sizer->Show((size_t)0);
Layout();
}
#endif // !ENABLE_GCODE_VIEWER
void Preview::on_size(wxSizeEvent& evt)
{
@ -693,31 +473,19 @@ void Preview::on_choice_view_type(wxCommandEvent& evt)
{
m_preferred_color_mode = (m_choice_view_type->GetStringSelection() == L("Tool")) ? "tool" : "feature";
int selection = m_choice_view_type->GetCurrentSelection();
#if ENABLE_GCODE_VIEWER
if (0 <= selection && selection < static_cast<int>(GCodeViewer::EViewType::Count))
m_canvas->set_toolpath_view_type(static_cast<GCodeViewer::EViewType>(selection));
refresh_print();
#else
if ((0 <= selection) && (selection < (int)GCodePreviewData::Extrusion::Num_View_Types))
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)selection;
reload_print();
#endif // ENABLE_GCODE_VIEWER
}
void Preview::on_combochecklist_features(wxCommandEvent& evt)
{
unsigned int flags = Slic3r::GUI::combochecklist_get_flags(m_combochecklist_features);
#if ENABLE_GCODE_VIEWER
m_canvas->set_toolpath_role_visibility_flags(flags);
#else
m_gcode_preview_data->extrusion.role_flags = flags;
#endif // ENABLE_GCODE_VIEWER
refresh_print();
}
#if ENABLE_GCODE_VIEWER
void Preview::on_combochecklist_options(wxCommandEvent& evt)
{
auto xored = [](unsigned int flags1, unsigned int flags2, unsigned int flag) {
@ -742,39 +510,6 @@ void Preview::on_combochecklist_options(wxCommandEvent& evt)
else
m_canvas->set_as_dirty();
}
#else
void Preview::on_checkbox_travel(wxCommandEvent& evt)
{
m_gcode_preview_data->travel.is_visible = m_checkbox_travel->IsChecked();
m_gcode_preview_data->ranges.feedrate.set_mode(GCodePreviewData::FeedrateKind::TRAVEL, m_gcode_preview_data->travel.is_visible);
// Rather than refresh, reload print so that speed color ranges get recomputed (affected by travel visibility)
reload_print();
}
void Preview::on_checkbox_retractions(wxCommandEvent& evt)
{
m_gcode_preview_data->retraction.is_visible = m_checkbox_retractions->IsChecked();
refresh_print();
}
void Preview::on_checkbox_unretractions(wxCommandEvent& evt)
{
m_gcode_preview_data->unretraction.is_visible = m_checkbox_unretractions->IsChecked();
refresh_print();
}
void Preview::on_checkbox_shells(wxCommandEvent& evt)
{
m_gcode_preview_data->shell.is_visible = m_checkbox_shells->IsChecked();
refresh_print();
}
void Preview::on_checkbox_legend(wxCommandEvent& evt)
{
m_canvas->enable_legend_texture(m_checkbox_legend->IsChecked());
m_canvas_widget->Refresh();
}
#endif // ENABLE_GCODE_VIEWER
void Preview::update_view_type(bool keep_volumes)
{
@ -790,49 +525,34 @@ void Preview::update_view_type(bool keep_volumes)
int type = m_choice_view_type->FindString(choice);
if (m_choice_view_type->GetSelection() != type) {
m_choice_view_type->SetSelection(type);
#if ENABLE_GCODE_VIEWER
if ((0 <= type) && (type < static_cast<int>(GCodeViewer::EViewType::Count)))
if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count))
m_canvas->set_gcode_view_preview_type(static_cast<GCodeViewer::EViewType>(type));
#else
if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types)
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
#endif // ENABLE_GCODE_VIEWER
m_preferred_color_mode = "feature";
}
#if ENABLE_GCODE_VIEWER
reload_print(keep_volumes);
#else
reload_print();
#endif // ENABLE_GCODE_VIEWER
}
#if ENABLE_GCODE_VIEWER
void Preview::update_bottom_toolbar()
{
combochecklist_set_flags(m_combochecklist_features, m_canvas->get_toolpath_role_visibility_flags());
combochecklist_set_flags(m_combochecklist_options, m_canvas->get_gcode_options_visibility_flags());
// updates visibility of features combobox
if (m_bottom_toolbar_panel->IsShown())
{
if (m_bottom_toolbar_panel->IsShown()) {
wxSizer* sizer = m_bottom_toolbar_panel->GetSizer();
bool show = !m_canvas->is_gcode_legend_enabled() || m_canvas->get_gcode_view_type() != GCodeViewer::EViewType::FeatureType;
if (show)
{
if (sizer->GetItem(m_combochecklist_features) == nullptr)
{
if (show) {
if (sizer->GetItem(m_combochecklist_features) == nullptr) {
sizer->Insert(m_combochecklist_features_pos, m_combochecklist_features, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5);
sizer->Show(m_combochecklist_features);
sizer->Layout();
Refresh();
}
}
else
{
if (sizer->GetItem(m_combochecklist_features) != nullptr)
{
else {
if (sizer->GetItem(m_combochecklist_features) != nullptr) {
sizer->Hide(m_combochecklist_features);
sizer->Detach(m_combochecklist_features);
sizer->Layout();
@ -841,9 +561,7 @@ void Preview::update_bottom_toolbar()
}
}
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
wxBoxSizer* Preview::create_layers_slider_sizer()
{
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
@ -875,37 +593,6 @@ wxBoxSizer* Preview::create_layers_slider_sizer()
return sizer;
}
#else
void Preview::create_double_slider()
{
m_slider = new DoubleSlider::Control(this, wxID_ANY, 0, 0, 0, 100);
bool sla_print_technology = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology() == ptSLA;
bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects");
m_slider->SetDrawMode(sla_print_technology, sequential_print);
m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0);
// sizer, m_canvas_widget
m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this);
m_canvas_widget->Bind(wxEVT_KEY_UP, [this](wxKeyEvent& event) {
if (event.GetKeyCode() == WXK_SHIFT)
m_slider->UseDefaultColors(true);
event.Skip();
});
m_slider->Bind(wxEVT_SCROLL_CHANGED, &Preview::on_sliders_scroll_changed, this);
Bind(DoubleSlider::wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) {
Model& model = wxGetApp().plater()->model();
model.custom_gcode_per_print_z = m_slider->GetTicksValues();
m_schedule_background_process();
update_view_type(false);
});
}
#endif // ENABLE_GCODE_VIEWER
// Find an index of a value in a sorted vector, which is in <z-eps, z+eps>.
// Returns -1 if there is no such member.
@ -934,12 +621,7 @@ static int find_close_layer_idx(const std::vector<double>& zs, double &z, double
return -1;
}
#if ENABLE_GCODE_VIEWER
void Preview::check_layers_slider_values(std::vector<CustomGCode::Item>& ticks_from_model, const std::vector<double>& layers_z)
#else
void Preview::check_slider_values(std::vector<CustomGCode::Item>& ticks_from_model,
const std::vector<double>& layers_z)
#endif // ENABLE_GCODE_VIEWER
{
// All ticks that would end up outside the slider range should be erased.
// TODO: this should be placed into more appropriate part of code,
@ -956,7 +638,6 @@ void Preview::check_slider_values(std::vector<CustomGCode::Item>& ticks_from_mod
m_schedule_background_process();
}
#if ENABLE_GCODE_VIEWER
void Preview::update_layers_slider(const std::vector<double>& layers_z, bool keep_z_range)
{
// Save the initial slider span.
@ -976,7 +657,8 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
// Detect and set manipulation mode for double slider
update_layers_slider_mode();
CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z;
Plater* plater = wxGetApp().plater();
CustomGCode::Info& ticks_info_from_model = plater->model().custom_gcode_per_print_z;
check_layers_slider_values(ticks_info_from_model.gcodes, layers_z);
m_layers_slider->SetSliderValues(layers_z);
@ -1000,72 +682,20 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
m_layers_slider->SetSelectionSpan(idx_low, idx_high);
m_layers_slider->SetTicksValues(ticks_info_from_model);
bool sla_print_technology = wxGetApp().plater()->printer_technology() == ptSLA;
bool sla_print_technology = plater->printer_technology() == ptSLA;
bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects");
m_layers_slider->SetDrawMode(sla_print_technology, sequential_print);
m_layers_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config());
m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config());
if (sla_print_technology)
m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times);
else
m_layers_slider->SetLayersTimes(m_gcode_result->time_statistics.modes[0].layers_times);
m_layers_slider_sizer->Show((size_t)0);
Layout();
}
#else
void Preview::update_double_slider(const std::vector<double> & layers_z, bool keep_z_range)
{
// Save the initial slider span.
double z_low = m_slider->GetLowerValueD();
double z_high = m_slider->GetHigherValueD();
bool was_empty = m_slider->GetMaxValue() == 0;
bool force_sliders_full_range = was_empty;
if (!keep_z_range)
{
bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_slider->GetMaxValueD()) > DoubleSlider::epsilon()/*1e-6*/;
force_sliders_full_range |= span_changed;
}
bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min();
bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max();
// Detect and set manipulation mode for double slider
update_double_slider_mode();
CustomGCode::Info& ticks_info_from_model = wxGetApp().plater()->model().custom_gcode_per_print_z;
check_slider_values(ticks_info_from_model.gcodes, layers_z);
m_slider->SetSliderValues(layers_z);
assert(m_slider->GetMinValue() == 0);
m_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1);
int idx_low = 0;
int idx_high = m_slider->GetMaxValue();
if (!layers_z.empty()) {
if (!snap_to_min) {
int idx_new = find_close_layer_idx(layers_z, z_low, DoubleSlider::epsilon()/*1e-6*/);
if (idx_new != -1)
idx_low = idx_new;
}
if (!snap_to_max) {
int idx_new = find_close_layer_idx(layers_z, z_high, DoubleSlider::epsilon()/*1e-6*/);
if (idx_new != -1)
idx_high = idx_new;
}
}
m_slider->SetSelectionSpan(idx_low, idx_high);
m_slider->SetTicksValues(ticks_info_from_model);
bool sla_print_technology = wxGetApp().plater()->printer_technology() == ptSLA;
bool sequential_print = wxGetApp().preset_bundle->prints.get_edited_preset().config.opt_bool("complete_objects");
m_slider->SetDrawMode(sla_print_technology, sequential_print);
m_slider->SetExtruderColors(wxGetApp().plater()->get_extruder_colors_from_plater_config());
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Preview::update_layers_slider_mode()
#else
void Preview::update_double_slider_mode()
#endif // ENABLE_GCODE_VIEWER
{
// true -> single-extruder printer profile OR
// multi-extruder printer profile , but whole model is printed by only one extruder
@ -1114,28 +744,15 @@ void Preview::update_double_slider_mode()
}
}
#if ENABLE_GCODE_VIEWER
m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder);
#else
m_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder);
#endif // ENABLE_GCODE_VIEWER
}
#if ENABLE_GCODE_VIEWER
void Preview::reset_layers_slider()
{
m_layers_slider->SetHigherValue(0);
m_layers_slider->SetLowerValue(0);
}
#else
void Preview::reset_double_slider()
{
m_slider->SetHigherValue(0);
m_slider->SetLowerValue(0);
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Preview::update_layers_slider_from_canvas(wxKeyEvent& event)
{
if (event.HasModifiers()) {
@ -1184,42 +801,12 @@ void Preview::enable_moves_slider(bool enable)
m_moves_slider->Refresh();
}
}
#else
void Preview::update_double_slider_from_canvas(wxKeyEvent & event)
{
if (event.HasModifiers()) {
event.Skip();
return;
}
const auto key = event.GetKeyCode();
if (key == 'U' || key == 'D') {
const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1;
m_slider->SetHigherValue(new_pos);
if (event.ShiftDown() || m_slider->is_one_layer()) m_slider->SetLowerValue(m_slider->GetHigherValue());
}
else if (key == 'L') {
m_checkbox_legend->SetValue(!m_checkbox_legend->GetValue());
auto evt = wxCommandEvent();
on_checkbox_legend(evt);
}
else if (key == 'S')
m_slider->ChangeOneLayerLock();
else if (key == WXK_SHIFT)
m_slider->UseDefaultColors(false);
else
event.Skip();
}
#endif // ENABLE_GCODE_VIEWER
void Preview::load_print_as_fff(bool keep_z_range)
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().mainframe == nullptr || wxGetApp().is_recreating_gui())
// avoid processing while mainframe is being constructed
return;
#endif // ENABLE_GCODE_VIEWER
if (m_loaded || m_process->current_printer_technology() != ptFFF)
return;
@ -1244,17 +831,11 @@ void Preview::load_print_as_fff(bool keep_z_range)
}
}
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor() && !has_layers) {
hide_layers_slider();
m_left_sizer->Hide(m_bottom_toolbar_panel);
m_left_sizer->Layout();
Refresh();
#else
if (! has_layers) {
reset_sliders(true);
m_canvas->reset_legend_texture();
#endif // ENABLE_GCODE_VIEWER
m_canvas_widget->Refresh();
return;
}
@ -1266,100 +847,58 @@ void Preview::load_print_as_fff(bool keep_z_range)
int tool_idx = m_choice_view_type->FindString(_L("Tool"));
int type = (number_extruders > 1) ? tool_idx /* color by a tool number */ : 0; // color by a feature type
m_choice_view_type->SetSelection(type);
#if ENABLE_GCODE_VIEWER
if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count))
m_canvas->set_gcode_view_preview_type(static_cast<GCodeViewer::EViewType>(type));
#else
if ((0 <= type) && (type < (int)GCodePreviewData::Extrusion::Num_View_Types))
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
#endif // ENABLE_GCODE_VIEWER
// If the->SetSelection changed the following line, revert it to "decide yourself".
m_preferred_color_mode = "tool_or_feature";
}
#if ENABLE_GCODE_VIEWER
GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type();
bool gcode_preview_data_valid = !m_gcode_result->moves.empty();
#else
bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty();
#endif // ENABLE_GCODE_VIEWER
// Collect colors per extruder.
std::vector<std::string> colors;
std::vector<CustomGCode::Item> color_print_values = {};
// set color print values, if it si selected "ColorPrint" view type
#if ENABLE_GCODE_VIEWER
if (gcode_view_type == GCodeViewer::EViewType::ColorPrint) {
colors = wxGetApp().plater()->get_colors_for_color_print(m_gcode_result);
#else
if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) {
colors = wxGetApp().plater()->get_colors_for_color_print();
colors.push_back("#808080"); // gray color for pause print or custom G-code
#endif // ENABLE_GCODE_VIEWER
if (!gcode_preview_data_valid) {
color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
#if ENABLE_GCODE_VIEWER
colors.push_back("#808080"); // gray color for pause print or custom G-code
#endif // ENABLE_GCODE_VIEWER
}
}
#if ENABLE_GCODE_VIEWER
else if (gcode_preview_data_valid || gcode_view_type == GCodeViewer::EViewType::Tool) {
colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(m_gcode_result);
#else
else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) {
colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
#endif // ENABLE_GCODE_VIEWER
color_print_values.clear();
}
if (IsShown()) {
#if ENABLE_GCODE_VIEWER
std::vector<double> zs;
#endif // ENABLE_GCODE_VIEWER
m_canvas->set_selected_extruder(0);
if (gcode_preview_data_valid) {
// Load the real G-code preview.
#if ENABLE_GCODE_VIEWER
m_canvas->load_gcode_preview(*m_gcode_result);
m_canvas->refresh_gcode_preview(*m_gcode_result, colors);
m_left_sizer->Show(m_bottom_toolbar_panel);
m_left_sizer->Layout();
Refresh();
zs = m_canvas->get_gcode_layers_zs();
#else
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
#endif // ENABLE_GCODE_VIEWER
m_loaded = true;
} else {
// Load the initial preview based on slices, not the final G-code.
m_canvas->load_preview(colors, color_print_values);
#if ENABLE_GCODE_VIEWER
m_left_sizer->Hide(m_bottom_toolbar_panel);
m_left_sizer->Layout();
Refresh();
zs = m_canvas->get_volumes_print_zs(true);
#endif // ENABLE_GCODE_VIEWER
}
#if !ENABLE_GCODE_VIEWER
show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple");
std::vector<double> zs = m_canvas->get_current_print_zs(true);
#endif // !ENABLE_GCODE_VIEWER
if (zs.empty()) {
// all layers filtered out
#if ENABLE_GCODE_VIEWER
hide_layers_slider();
#else
reset_sliders(true);
#endif // ENABLE_GCODE_VIEWER
m_canvas_widget->Refresh();
} else
#if ENABLE_GCODE_VIEWER
update_layers_slider(zs, keep_z_range);
#else
update_sliders(zs, keep_z_range);
#endif // ENABLE_GCODE_VIEWER
}
}
@ -1374,8 +913,7 @@ void Preview::load_print_as_sla()
std::vector<double> zs;
double initial_layer_height = print->material_config().initial_layer_height.value;
for (const SLAPrintObject* obj : print->objects())
if (obj->is_step_done(slaposSliceSupports) && !obj->get_slice_index().empty())
{
if (obj->is_step_done(slaposSliceSupports) && !obj->get_slice_index().empty()) {
auto low_coord = obj->get_slice_index().front().print_level();
for (auto& rec : obj->get_slice_index())
zs.emplace_back(initial_layer_height + (rec.print_level() - low_coord) * SCALING_FACTOR);
@ -1385,74 +923,43 @@ void Preview::load_print_as_sla()
m_canvas->reset_clipping_planes_cache();
n_layers = (unsigned int)zs.size();
if (n_layers == 0)
{
#if ENABLE_GCODE_VIEWER
if (n_layers == 0) {
hide_layers_slider();
#else
reset_sliders(true);
#endif // ENABLE_GCODE_VIEWER
m_canvas_widget->Refresh();
}
if (IsShown())
{
if (IsShown()) {
m_canvas->load_sla_preview();
#if ENABLE_GCODE_VIEWER
m_left_sizer->Hide(m_bottom_toolbar_panel);
m_left_sizer->Hide(m_bottom_toolbar_panel);
m_left_sizer->Layout();
Refresh();
#else
show_hide_ui_elements("none");
#endif // ENABLE_GCODE_VIEWER
if (n_layers > 0)
#if ENABLE_GCODE_VIEWER
update_layers_slider(zs);
#else
update_sliders(zs);
#endif // ENABLE_GCODE_VIEWER
m_loaded = true;
}
}
#if ENABLE_GCODE_VIEWER
void Preview::on_layers_slider_scroll_changed(wxCommandEvent& event)
#else
void Preview::on_sliders_scroll_changed(wxCommandEvent& event)
#endif // ENABLE_GCODE_VIEWER
{
if (IsShown()) {
PrinterTechnology tech = m_process->current_printer_technology();
if (tech == ptFFF) {
#if ENABLE_GCODE_VIEWER
m_canvas->set_volumes_z_range({ m_layers_slider->GetLowerValueD(), m_layers_slider->GetHigherValueD() });
m_canvas->set_toolpaths_z_range({ static_cast<unsigned int>(m_layers_slider->GetLowerValue()), static_cast<unsigned int>(m_layers_slider->GetHigherValue()) });
m_canvas->set_as_dirty();
#else
m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6);
m_canvas->render();
m_canvas->set_use_clipping_planes(false);
#endif // ENABLE_GCODE_VIEWER
}
else if (tech == ptSLA) {
#if ENABLE_GCODE_VIEWER
m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_layers_slider->GetLowerValueD()));
m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_layers_slider->GetHigherValueD()));
m_canvas->set_use_clipping_planes(m_layers_slider->GetHigherValue() != 0);
#else
m_canvas->set_clipping_plane(0, ClippingPlane(Vec3d::UnitZ(), -m_slider->GetLowerValueD()));
m_canvas->set_clipping_plane(1, ClippingPlane(-Vec3d::UnitZ(), m_slider->GetHigherValueD()));
m_canvas->set_use_clipping_planes(m_slider->GetHigherValue() != 0);
#endif // ENABLE_GCODE_VIEWER
m_canvas->render();
}
}
}
#if ENABLE_GCODE_VIEWER
void Preview::on_moves_slider_scroll_changed(wxCommandEvent& event)
{
m_canvas->update_gcode_sequential_view_current(static_cast<unsigned int>(m_moves_slider->GetLowerValueD() - 1.0), static_cast<unsigned int>(m_moves_slider->GetHigherValueD() - 1.0));
@ -1476,7 +983,6 @@ wxString Preview::get_option_type_string(OptionType type) const
default: { return ""; }
}
}
#endif // ENABLE_GCODE_VIEWER
} // namespace GUI
} // namespace Slic3r

View file

@ -7,9 +7,7 @@
#include "libslic3r/CustomGCode.hpp"
#include <string>
#if ENABLE_GCODE_VIEWER
#include "libslic3r/GCode/GCodeProcessor.hpp"
#endif // ENABLE_GCODE_VIEWER
class wxNotebook;
class wxGLCanvas;
@ -25,9 +23,6 @@ namespace Slic3r {
class DynamicPrintConfig;
class Print;
class BackgroundSlicingProcess;
#if !ENABLE_GCODE_VIEWER
class GCodePreviewData;
#endif // !ENABLE_GCODE_VIEWER
class Model;
namespace DoubleSlider {
@ -83,35 +78,19 @@ class Preview : public wxPanel
{
wxGLCanvas* m_canvas_widget;
GLCanvas3D* m_canvas;
#if ENABLE_GCODE_VIEWER
wxBoxSizer* m_left_sizer;
wxBoxSizer* m_layers_slider_sizer;
wxPanel* m_bottom_toolbar_panel;
#else
wxBoxSizer* m_double_slider_sizer;
#endif // ENABLE_GCODE_VIEWER
wxStaticText* m_label_view_type;
wxChoice* m_choice_view_type;
wxStaticText* m_label_show;
wxComboCtrl* m_combochecklist_features;
#if ENABLE_GCODE_VIEWER
size_t m_combochecklist_features_pos;
wxComboCtrl* m_combochecklist_options;
#else
wxCheckBox* m_checkbox_travel;
wxCheckBox* m_checkbox_retractions;
wxCheckBox* m_checkbox_unretractions;
wxCheckBox* m_checkbox_shells;
wxCheckBox* m_checkbox_legend;
#endif // ENABLE_GCODE_VIEWER
DynamicPrintConfig* m_config;
BackgroundSlicingProcess* m_process;
#if ENABLE_GCODE_VIEWER
GCodeProcessor::Result* m_gcode_result;
#else
GCodePreviewData* m_gcode_preview_data;
#endif // ENABLE_GCODE_VIEWER
#ifdef __linux__
// We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
@ -126,19 +105,11 @@ class Preview : public wxPanel
std::string m_preferred_color_mode;
bool m_loaded;
#if !ENABLE_GCODE_VIEWER
bool m_enabled;
#endif // !ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
DoubleSlider::Control* m_layers_slider{ nullptr };
DoubleSlider::Control* m_moves_slider{ nullptr };
#else
DoubleSlider::Control* m_slider {nullptr};
#endif // ENABLE_GCODE_VIEWER
public:
#if ENABLE_GCODE_VIEWER
enum class OptionType : unsigned int
{
Travel,
@ -153,12 +124,8 @@ public:
Legend
};
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
#else
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = []() {});
#endif // ENABLE_GCODE_VIEWER
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
virtual ~Preview();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
@ -167,9 +134,6 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
void set_as_dirty();
void set_number_extruders(unsigned int number_extruders);
#if !ENABLE_GCODE_VIEWER
void set_enabled(bool enabled);
#endif // !ENABLE_GCODE_VIEWER
void bed_shape_changed();
void select_view(const std::string& direction);
void set_drop_target(wxDropTarget* target);
@ -180,24 +144,17 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config,
void msw_rescale();
void jump_layers_slider(wxKeyEvent& evt);
#if ENABLE_GCODE_VIEWER
void move_layers_slider(wxKeyEvent& evt);
void edit_layers_slider(wxKeyEvent& evt);
#else
void move_double_slider(wxKeyEvent& evt);
void edit_double_slider(wxKeyEvent& evt);
#endif // ENABLE_GCODE_VIEWER
void update_view_type(bool keep_volumes);
bool is_loaded() const { return m_loaded; }
#if ENABLE_GCODE_VIEWER
void update_bottom_toolbar();
void update_moves_slider();
void enable_moves_slider(bool enable);
void hide_layers_slider();
#endif // ENABLE_GCODE_VIEWER
private:
bool init(wxWindow* parent, Model* model);
@ -205,27 +162,11 @@ private:
void bind_event_handlers();
void unbind_event_handlers();
#if !ENABLE_GCODE_VIEWER
void show_hide_ui_elements(const std::string& what);
void reset_sliders(bool reset_all);
void update_sliders(const std::vector<double>& layers_z, bool keep_z_range = false);
#endif // !ENABLE_GCODE_VIEWER
void on_size(wxSizeEvent& evt);
void on_choice_view_type(wxCommandEvent& evt);
void on_combochecklist_features(wxCommandEvent& evt);
#if ENABLE_GCODE_VIEWER
void on_combochecklist_options(wxCommandEvent& evt);
#else
void on_checkbox_travel(wxCommandEvent& evt);
void on_checkbox_retractions(wxCommandEvent& evt);
void on_checkbox_unretractions(wxCommandEvent& evt);
void on_checkbox_shells(wxCommandEvent& evt);
void on_checkbox_legend(wxCommandEvent& evt);
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
// Create/Update/Reset double slider on 3dPreview
wxBoxSizer* create_layers_slider_sizer();
void check_layers_slider_values(std::vector<CustomGCode::Item>& ticks_from_model,
@ -235,28 +176,13 @@ private:
void update_layers_slider_mode();
// update vertical DoubleSlider after keyDown in canvas
void update_layers_slider_from_canvas(wxKeyEvent& event);
#else
// Create/Update/Reset double slider on 3dPreview
void create_double_slider();
void check_slider_values(std::vector<CustomGCode::Item>& ticks_from_model,
const std::vector<double>& layers_z);
void reset_double_slider();
void update_double_slider(const std::vector<double>& layers_z, bool keep_z_range = false);
void update_double_slider_mode();
// update DoubleSlider after keyDown in canvas
void update_double_slider_from_canvas(wxKeyEvent& event);
#endif // ENABLE_GCODE_VIEWER
void load_print_as_fff(bool keep_z_range = false);
void load_print_as_sla();
#if ENABLE_GCODE_VIEWER
void on_layers_slider_scroll_changed(wxCommandEvent& event);
void on_moves_slider_scroll_changed(wxCommandEvent& event);
wxString get_option_type_string(OptionType type) const;
#else
void on_sliders_scroll_changed(wxCommandEvent& event);
#endif // ENABLE_GCODE_VIEWER
};
} // namespace GUI

View file

@ -385,7 +385,6 @@ public:
std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics);
#if ENABLE_GCODE_VIEWER
inline int hex_digit_to_int(const char c)
{
return
@ -393,7 +392,6 @@ inline int hex_digit_to_int(const char c)
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
}
#endif // ENABLE_GCODE_VIEWER
class TaskTimer
{

View file

@ -45,7 +45,7 @@ bool GLGizmoFdmSupports::on_init()
m_desc["cursor_type"] = _L("Brush shape") + ": ";
m_desc["enforce_caption"] = _L("Left mouse button") + ": ";
m_desc["enforce"] = _L("Enforce supports");
m_desc["block_caption"] = _L("Right mouse button") + " ";
m_desc["block_caption"] = _L("Right mouse button") + ": ";
m_desc["block"] = _L("Block supports");
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
m_desc["remove"] = _L("Remove selection");

View file

@ -28,7 +28,7 @@ bool GLGizmoSeam::on_init()
m_desc["cursor_type"] = _L("Brush shape") + ": ";
m_desc["enforce_caption"] = _L("Left mouse button") + ": ";
m_desc["enforce"] = _L("Enforce seam");
m_desc["block_caption"] = _L("Right mouse button") + " ";
m_desc["block_caption"] = _L("Right mouse button") + ": ";
m_desc["block"] = _L("Block seam");
m_desc["remove_caption"] = _L("Shift + Left mouse button") + ": ";
m_desc["remove"] = _L("Remove selection");

View file

@ -23,7 +23,7 @@
#include "libslic3r/libslic3r.h"
#include "libslic3r/Utils.hpp"
#include "3DScene.hpp"+
#include "3DScene.hpp"
#include "GUI.hpp"
#include "I18N.hpp"
#include "Search.hpp"

View file

@ -251,11 +251,24 @@ namespace instance_check_internal
bool instance_check(int argc, char** argv, bool app_config_single_instance)
{
#ifndef _WIN32
boost::system::error_code ec;
#endif
std::size_t hashed_path =
#ifdef _WIN32
std::hash<std::string>{}(boost::filesystem::system_complete(argv[0]).string());
#else
std::hash<std::string>{}(boost::filesystem::canonical(boost::filesystem::system_complete(argv[0])).string());
std::hash<std::string>{}(boost::filesystem::canonical(boost::filesystem::system_complete(argv[0]), ec).string());
if(ec.value() > 0) { // canonical was not able to find execitable (can happen with appimage on some systems)
ec.clear();
// Compose path with boost canonical of folder and filename
hashed_path = std::hash<std::string>{}(boost::filesystem::canonical(boost::filesystem::system_complete(argv[0]).parent_path(), ec).string() + "/" + boost::filesystem::system_complete(argv[0]).filename().string());
if(ec.value() > 0) {
// Still not valid, process without canonical
hashed_path = std::hash<std::string>{}(boost::filesystem::system_complete(argv[0]).string());
}
}
#endif // win32
std::string lock_name = std::to_string(hashed_path);

View file

@ -46,7 +46,7 @@ public:
}
};
static WipeTower get_wipe_tower(Plater &plater)
static WipeTower get_wipe_tower(const Plater &plater)
{
return WipeTower{plater.canvas3D()->get_wipe_tower_info()};
}
@ -68,18 +68,13 @@ void ArrangeJob::clear_input()
m_unprintable.reserve(cunprint /* for optional wti */);
}
double ArrangeJob::bed_stride() const {
double bedwidth = m_plater->bed_shape_bb().size().x();
return scaled<double>((1. + LOGICAL_BED_GAP) * bedwidth);
}
void ArrangeJob::prepare_all() {
clear_input();
for (ModelObject *obj: m_plater->model().objects)
for (ModelInstance *mi : obj->instances) {
ArrangePolygons & cont = mi->printable ? m_selected : m_unprintable;
cont.emplace_back(get_arrange_poly(mi));
cont.emplace_back(get_arrange_poly(mi, m_plater));
}
if (auto wti = get_wipe_tower(*m_plater))
@ -90,7 +85,7 @@ void ArrangeJob::prepare_selected() {
clear_input();
Model &model = m_plater->model();
double stride = bed_stride();
double stride = bed_stride(m_plater);
std::vector<const Selection::InstanceIdxsList *>
obj_sel(model.objects.size(), nullptr);
@ -111,7 +106,7 @@ void ArrangeJob::prepare_selected() {
inst_sel[size_t(inst_id)] = true;
for (size_t i = 0; i < inst_sel.size(); ++i) {
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i]);
ArrangePolygon &&ap = get_arrange_poly(mo->instances[i], m_plater);
ArrangePolygons &cont = mo->instances[i]->printable ?
(inst_sel[i] ? m_selected :
@ -123,7 +118,7 @@ void ArrangeJob::prepare_selected() {
}
if (auto wti = get_wipe_tower(*m_plater)) {
ArrangePolygon &&ap = get_arrange_poly(&wti);
ArrangePolygon &&ap = get_arrange_poly(&wti, m_plater);
m_plater->get_selection().is_wipe_tower() ?
m_selected.emplace_back(std::move(ap)) :
@ -147,11 +142,13 @@ void ArrangeJob::prepare()
void ArrangeJob::process()
{
static const auto arrangestr = _(L("Arranging"));
double dist = min_object_distance(*m_plater->config());
GLCanvas3D::ArrangeSettings settings =
m_plater->canvas3D()->get_arrange_settings();
arrangement::ArrangeParams params;
params.min_obj_distance = scaled(dist);
params.min_obj_distance = scaled(settings.distance);
params.allow_rotations = settings.enable_rotation;
auto count = unsigned(m_selected.size() + m_unprintable.size());
Points bedpts = get_bed_shape(*m_plater->config());
@ -211,14 +208,25 @@ void ArrangeJob::finalize() {
Job::finalize();
}
arrangement::ArrangePolygon get_wipe_tower_arrangepoly(Plater &plater)
std::optional<arrangement::ArrangePolygon>
get_wipe_tower_arrangepoly(const Plater &plater)
{
return WipeTower{plater.canvas3D()->get_wipe_tower_info()}.get_arrange_polygon();
if (auto wti = get_wipe_tower(plater))
return wti.get_arrange_polygon();
return {};
}
void apply_wipe_tower_arrangepoly(Plater &plater, const arrangement::ArrangePolygon &ap)
void apply_wipe_tower_arrangepoly(Plater & plater,
const arrangement::ArrangePolygon &ap)
{
WipeTower{plater.canvas3D()->get_wipe_tower_info()}.apply_arrange_result(ap.translation.cast<double>(), ap.rotation);
WipeTower{plater.canvas3D()->get_wipe_tower_info()}
.apply_arrange_result(ap.translation.cast<double>(), ap.rotation);
}
double bed_stride(const Plater *plater) {
double bedwidth = plater->bed_shape_bb().size().x();
return scaled<double>((1. + LOGICAL_BED_GAP) * bedwidth);
}
}} // namespace Slic3r::GUI

View file

@ -14,35 +14,12 @@ class ArrangeJob : public Job
using ArrangePolygon = arrangement::ArrangePolygon;
using ArrangePolygons = arrangement::ArrangePolygons;
// The gap between logical beds in the x axis expressed in ratio of
// the current bed width.
static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
ArrangePolygons m_selected, m_unselected, m_unprintable;
// clear m_selected and m_unselected, reserve space for next usage
void clear_input();
// Stride between logical beds
double bed_stride() const;
// Set up arrange polygon for a ModelInstance and Wipe tower
template<class T> ArrangePolygon get_arrange_poly(T *obj) const
{
ArrangePolygon ap = obj->get_arrange_polygon();
ap.priority = 0;
ap.bed_idx = ap.translation.x() / bed_stride();
ap.setter = [obj, this](const ArrangePolygon &p) {
if (p.is_arranged()) {
Vec2d t = p.translation.cast<double>();
t.x() += p.bed_idx * bed_stride();
obj->apply_arrange_result(t, p.rotation);
}
};
return ap;
}
// Prepare all objects on the bed regardless of the selection
void prepare_all();
@ -69,9 +46,37 @@ public:
void finalize() override;
};
arrangement::ArrangePolygon get_wipe_tower_arrangepoly(Plater &);
std::optional<arrangement::ArrangePolygon> get_wipe_tower_arrangepoly(const Plater &);
void apply_wipe_tower_arrangepoly(Plater &plater, const arrangement::ArrangePolygon &ap);
// The gap between logical beds in the x axis expressed in ratio of
// the current bed width.
static const constexpr double LOGICAL_BED_GAP = 1. / 5.;
// Stride between logical beds
double bed_stride(const Plater *plater);
// Set up arrange polygon for a ModelInstance and Wipe tower
template<class T>
arrangement::ArrangePolygon get_arrange_poly(T *obj, const Plater *plater)
{
using ArrangePolygon = arrangement::ArrangePolygon;
ArrangePolygon ap = obj->get_arrange_polygon();
ap.priority = 0;
ap.bed_idx = ap.translation.x() / bed_stride(plater);
ap.setter = [obj, plater](const ArrangePolygon &p) {
if (p.is_arranged()) {
Vec2d t = p.translation.cast<double>();
t.x() += p.bed_idx * bed_stride(plater);
obj->apply_arrange_result(t, p.rotation);
}
};
return ap;
}
}} // namespace Slic3r::GUI
#endif // ARRANGEJOB_HPP

View file

@ -0,0 +1,139 @@
#include "FillBedJob.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_ObjectList.hpp"
#include <numeric>
namespace Slic3r {
namespace GUI {
void FillBedJob::prepare()
{
m_selected.clear();
m_unselected.clear();
m_bedpts.clear();
m_object_idx = m_plater->get_selected_object_idx();
if (m_object_idx == -1)
return;
ModelObject *model_object = m_plater->model().objects[m_object_idx];
if (model_object->instances.empty()) return;
m_selected.reserve(model_object->instances.size());
for (ModelInstance *inst : model_object->instances)
if (inst->printable) {
ArrangePolygon ap = get_arrange_poly(inst, m_plater);
++ap.priority; // need to be included in the result
m_selected.emplace_back(ap);
}
if (m_selected.empty()) return;
m_bedpts = get_bed_shape(*m_plater->config());
auto &objects = m_plater->model().objects;
for (size_t idx = 0; idx < objects.size(); ++idx)
if (int(idx) != m_object_idx)
for (const ModelInstance *mi : objects[idx]->instances) {
m_unselected.emplace_back(mi->get_arrange_polygon());
m_unselected.back().bed_idx = 0;
}
if (auto wt = get_wipe_tower_arrangepoly(*m_plater))
m_unselected.emplace_back(std::move(*wt));
double sc = scaled<double>(1.) * scaled(1.);
ExPolygon poly = m_selected.front().poly;
double poly_area = poly.area() / sc;
double unsel_area = std::accumulate(m_unselected.begin(),
m_unselected.end(), 0.,
[](double s, const auto &ap) {
return s + ap.poly.area();
}) / sc;
double fixed_area = unsel_area + m_selected.size() * poly_area;
// This is the maximum range, the real number will always be close but less.
double bed_area = Polygon{m_bedpts}.area() / sc;
m_status_range = (bed_area - fixed_area) / poly_area;
ModelInstance *mi = model_object->instances[0];
for (int i = 0; i < m_status_range; ++i) {
ArrangePolygon ap;
ap.poly = m_selected.front().poly;
ap.bed_idx = arrangement::UNARRANGED;
ap.setter = [this, mi](const ArrangePolygon &p) {
ModelObject *mo = m_plater->model().objects[m_object_idx];
ModelInstance *inst = mo->add_instance(*mi);
inst->apply_arrange_result(p.translation.cast<double>(), p.rotation);
};
m_selected.emplace_back(ap);
}
}
void FillBedJob::process()
{
if (m_object_idx == -1 || m_selected.empty()) return;
GLCanvas3D::ArrangeSettings settings =
m_plater->canvas3D()->get_arrange_settings();
arrangement::ArrangeParams params;
params.min_obj_distance = scaled(settings.distance);
params.allow_rotations = settings.enable_rotation;
params.stopcondition = [this]() { return was_canceled(); };
params.progressind = [this](unsigned st) {
if (st > 0)
update_status(int(m_status_range - st), _(L("Filling bed")));
};
arrangement::arrange(m_selected, m_unselected, m_bedpts, params);
// finalize just here.
update_status(m_status_range, was_canceled() ?
_(L("Bed filling canceled.")) :
_(L("Bed filling done.")));
}
void FillBedJob::finalize()
{
if (m_object_idx == -1) return;
ModelObject *model_object = m_plater->model().objects[m_object_idx];
if (model_object->instances.empty()) return;
size_t inst_cnt = model_object->instances.size();
for (ArrangePolygon &ap : m_selected) {
if (ap.priority != 0 || !(ap.bed_idx == arrangement::UNARRANGED || ap.bed_idx > 0))
ap.apply();
}
model_object->ensure_on_bed();
m_plater->update();
int added_cnt = std::accumulate(m_selected.begin(), m_selected.end(), 0,
[](int s, auto &ap) {
return s + int(ap.priority == 0 && ap.bed_idx == 0);
});
// FIXME: somebody explain why this is needed for increase_object_instances
if (inst_cnt == 1) added_cnt++;
if (added_cnt > 0)
m_plater->sidebar()
.obj_list()->increase_object_instances(m_object_idx, size_t(added_cnt));
}
}} // namespace Slic3r::GUI

View file

@ -0,0 +1,46 @@
#ifndef FILLBEDJOB_HPP
#define FILLBEDJOB_HPP
#include "ArrangeJob.hpp"
namespace Slic3r { namespace GUI {
class Plater;
class FillBedJob : public Job
{
Plater *m_plater;
int m_object_idx = -1;
using ArrangePolygon = arrangement::ArrangePolygon;
using ArrangePolygons = arrangement::ArrangePolygons;
ArrangePolygons m_selected;
ArrangePolygons m_unselected;
Points m_bedpts;
int m_status_range = 0;
protected:
void prepare() override;
public:
FillBedJob(std::shared_ptr<ProgressIndicator> pri, Plater *plater)
: Job{std::move(pri)}, m_plater{plater}
{}
int status_range() const override
{
return m_status_range;
}
void process() override;
void finalize() override;
};
}} // namespace Slic3r::GUI
#endif // FILLBEDJOB_HPP

View file

@ -36,7 +36,7 @@ public:
"SL1 archive files (*.sl1, *.zip)|*.sl1;*.SL1;*.zip;*.ZIP",
wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE | wxFD_OPEN | wxFD_FILE_MUST_EXIST);
szfilepck->Add(new wxStaticText(this, wxID_ANY, _(L("Import file: "))), 0, wxALIGN_CENTER);
szfilepck->Add(new wxStaticText(this, wxID_ANY, _L("Import file") + ": "), 0, wxALIGN_CENTER);
szfilepck->Add(m_filepicker, 1);
szvert->Add(szfilepck, 0, wxALL | wxEXPAND, 5);
@ -53,7 +53,7 @@ public:
inp_choices.size(), inp_choices.data(), wxCB_READONLY | wxCB_DROPDOWN);
szchoices->Add(m_import_dropdown);
szchoices->Add(new wxStaticText(this, wxID_ANY, _(L("Quality: "))), 0, wxALIGN_CENTER | wxALL, 5);
szchoices->Add(new wxStaticText(this, wxID_ANY, _L("Quality") + ": "), 0, wxALIGN_CENTER | wxALL, 5);
static const std::vector<wxString> qual_choices = {
_(L("Accurate")),

View file

@ -7,9 +7,7 @@
#include <wx/display.h>
#include "GUI_App.hpp"
#include "wxExtensions.hpp"
#if ENABLE_GCODE_VIEWER
#include "MainFrame.hpp"
#endif // ENABLE_GCODE_VIEWER
#define NOTEBOOK_TOP 1
#define NOTEBOOK_LEFT 2
@ -33,11 +31,7 @@ namespace Slic3r {
namespace GUI {
KBShortcutsDialog::KBShortcutsDialog()
#if ENABLE_GCODE_VIEWER
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, wxString(wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) + " - " + _L("Keyboard Shortcuts"),
#else
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("Keyboard Shortcuts"),
#endif // ENABLE_GCODE_VIEWER
wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
@ -97,9 +91,7 @@ void KBShortcutsDialog::fill_shortcuts()
const std::string& ctrl = GUI::shortkey_ctrl_prefix();
const std::string& alt = GUI::shortkey_alt_prefix();
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
Shortcuts commands_shortcuts = {
// File
{ ctrl + "N", L("New project, clear plater") },
@ -204,9 +196,7 @@ void KBShortcutsDialog::fill_shortcuts()
};
m_full_shortcuts.push_back(std::make_pair(_L("Gizmos"), gizmos_shortcuts));
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
Shortcuts preview_shortcuts = {
{ L("Arrow Up"), L("Upper Layer") },
@ -231,7 +221,6 @@ void KBShortcutsDialog::fill_shortcuts()
m_full_shortcuts.push_back(std::make_pair(_L("Layers Slider"), layers_slider_shortcuts));
#if ENABLE_GCODE_VIEWER
Shortcuts sequential_slider_shortcuts = {
{ L("Arrow Left"), L("Move current slider thumb Left") },
{ L("Arrow Right"), L("Move current slider thumb Right") },
@ -240,7 +229,6 @@ void KBShortcutsDialog::fill_shortcuts()
};
m_full_shortcuts.push_back(std::make_pair(_L("Sequential Slider"), sequential_slider_shortcuts));
#endif // ENABLE_GCODE_VIEWER
}
wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_font)
@ -258,11 +246,7 @@ wxPanel* KBShortcutsDialog::create_header(wxWindow* parent, const wxFont& bold_f
sizer->AddStretchSpacer();
// logo
#if ENABLE_GCODE_VIEWER
m_logo_bmp = ScalableBitmap(this, wxGetApp().is_editor() ? "PrusaSlicer_32px.png" : "PrusaSlicer-gcodeviewer_32px.png", 32);
#else
m_logo_bmp = ScalableBitmap(this, "PrusaSlicer_32px.png", 32);
#endif // ENABLE_GCODE_VIEWER
m_header_bitmap = new wxStaticBitmap(panel, wxID_ANY, m_logo_bmp.bmp());
sizer->Add(m_header_bitmap, 0, wxEXPAND | wxLEFT | wxRIGHT, 10);

View file

@ -31,6 +31,7 @@
#include "GLCanvas3D.hpp"
#include "Plater.hpp"
#include "../Utils/Process.hpp"
#include "format.hpp"
#include <fstream>
#include "GUI_App.hpp"
@ -116,7 +117,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
// Load the icon either from the exe, or from the ico file.
#if _WIN32
{
#if ENABLE_GCODE_VIEWER
wxString src_path;
wxFileName::SplitPath(wxStandardPaths::Get().GetExecutablePath(), &src_path, nullptr, nullptr, wxPATH_NATIVE);
switch (wxGetApp().get_app_mode()) {
@ -127,22 +127,14 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
wxIconLocation icon_location;
icon_location.SetFileName(src_path);
SetIcon(icon_location);
#else
TCHAR szExeFileName[MAX_PATH];
GetModuleFileName(nullptr, szExeFileName, MAX_PATH);
SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO));
#endif // ENABLE_GCODE_VIEWER
}
#else
#if ENABLE_GCODE_VIEWER
switch (wxGetApp().get_app_mode())
{
default:
case GUI_App::EAppMode::Editor:
{
#endif // ENABLE_GCODE_VIEWER
SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG));
#if ENABLE_GCODE_VIEWER
break;
}
case GUI_App::EAppMode::GCodeViewer:
@ -151,23 +143,19 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
break;
}
}
#endif // ENABLE_GCODE_VIEWER
#endif // _WIN32
// initialize status bar
m_statusbar = std::make_shared<ProgressStatusBar>(this);
m_statusbar->set_font(GUI::wxGetApp().normal_font());
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor())
#endif // ENABLE_GCODE_VIEWER
m_statusbar->embed(this);
m_statusbar->set_status_text(_L("Version") + " " +
SLIC3R_VERSION +
_L(" - Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"));
SLIC3R_VERSION + " - " +
_L("Remember to check for updates at https://github.com/prusa3d/PrusaSlicer/releases"));
// initialize tabpanel and menubar
init_tabpanel();
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
init_menubar_as_gcodeviewer();
else
@ -185,9 +173,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
wxAcceleratorTable accel(6, entries);
SetAcceleratorTable(accel);
#endif // _WIN32
#else
init_menubar();
#endif // ENABLE_GCODE_VIEWER
// set default tooltip timer in msec
// SetAutoPop supposedly accepts long integers but some bug doesn't allow for larger values
@ -255,9 +240,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
update_ui_from_settings(); // FIXME (?)
if (m_plater != nullptr) {
#if ENABLE_GCODE_VIEWER
m_plater->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1");
#endif // ENABLE_GCODE_VIEWER
m_plater->show_action_buttons(true);
}
}
@ -300,16 +283,10 @@ void MainFrame::update_layout()
Layout();
};
#if ENABLE_GCODE_VIEWER
ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer :
(wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old :
wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New :
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old);
#else
ESettingsLayout layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old :
wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New :
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old;
#endif // ENABLE_GCODE_VIEWER
if (m_layout == layout)
return;
@ -373,7 +350,6 @@ void MainFrame::update_layout()
m_plater->Show();
break;
}
#if ENABLE_GCODE_VIEWER
case ESettingsLayout::GCodeViewer:
{
m_main_sizer->Add(m_plater, 1, wxEXPAND);
@ -383,7 +359,6 @@ void MainFrame::update_layout()
m_plater->Show();
break;
}
#endif // ENABLE_GCODE_VIEWER
}
#ifdef __WXMSW__
@ -452,7 +427,6 @@ void MainFrame::shutdown()
}
#endif // _WIN32
#if ENABLE_GCODE_VIEWER
if (m_plater != nullptr) {
m_plater->stop_jobs();
@ -465,19 +439,6 @@ void MainFrame::shutdown()
// see: https://github.com/prusa3d/PrusaSlicer/issues/3964
m_plater->reset_canvas_volumes();
}
#else
if (m_plater)
m_plater->stop_jobs();
// Unbinding of wxWidgets event handling in canvases needs to be done here because on MAC,
// when closing the application using Command+Q, a mouse event is triggered after this lambda is completed,
// causing a crash
if (m_plater) m_plater->unbind_canvas_event_handlers();
// Cleanup of canvases' volumes needs to be done here or a crash may happen on some Linux Debian flavours
// see: https://github.com/prusa3d/PrusaSlicer/issues/3964
if (m_plater) m_plater->reset_canvas_volumes();
#endif // ENABLE_GCODE_VIEWER
// Weird things happen as the Paint messages are floating around the windows being destructed.
// Avoid the Paint messages by hiding the main window.
@ -525,11 +486,7 @@ void MainFrame::update_title()
title += (project + " - ");
}
#if ENABLE_GCODE_VIEWER
std::string build_id = wxGetApp().is_editor() ? SLIC3R_BUILD_ID : GCODEVIEWER_BUILD_ID;
#else
std::string build_id = SLIC3R_BUILD_ID;
#endif // ENABLE_GCODE_VIEWER
size_t idx_plus = build_id.find('+');
if (idx_plus != build_id.npos) {
// Parse what is behind the '+'. If there is a number, then it is a build number after the label, and full build ID is shown.
@ -544,13 +501,10 @@ void MainFrame::update_title()
#endif
}
}
#if ENABLE_GCODE_VIEWER
title += wxString(build_id);
if (wxGetApp().is_editor())
title += (" " + _L("based on Slic3r"));
#else
title += (wxString(build_id) + " " + _L("based on Slic3r"));
#endif // ENABLE_GCODE_VIEWER
SetTitle(title);
}
@ -599,9 +553,7 @@ void MainFrame::init_tabpanel()
// or when the preset's "modified" status changes.
Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); // #ys_FIXME_to_delete
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor())
#endif // ENABLE_GCODE_VIEWER
create_preset_tabs();
if (m_plater) {
@ -810,9 +762,7 @@ bool MainFrame::can_change_view() const
int page_id = m_tabpanel->GetSelection();
return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr;
}
#if ENABLE_GCODE_VIEWER
case ESettingsLayout::GCodeViewer: { return true; }
#endif // ENABLE_GCODE_VIEWER
}
}
@ -904,7 +854,6 @@ void MainFrame::on_sys_color_changed()
msw_rescale_menu(menu_bar->GetMenu(id));
}
#if ENABLE_GCODE_VIEWER
#ifdef _MSC_VER
// \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators,
// as the simple numeric accelerators spoil all numeric data entry.
@ -939,17 +888,13 @@ static wxMenu* generate_help_menu()
[](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
append_menu_item(helpMenu, wxID_ANY, _L("Report an I&ssue"), wxString::Format(_L("Report an issue on %s"), SLIC3R_APP_NAME),
[](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/prusa3d/slic3r/issues/new"); });
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor())
#endif // ENABLE_GCODE_VIEWER
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), SLIC3R_APP_NAME), _L("Show about dialog"),
[](wxCommandEvent&) { Slic3r::GUI::about(); });
#if ENABLE_GCODE_VIEWER
else
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
[](wxCommandEvent&) { Slic3r::GUI::about(); });
#endif // ENABLE_GCODE_VIEWER
helpMenu->AppendSeparator();
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
[](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG
@ -984,9 +929,6 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame,
}
void MainFrame::init_menubar_as_editor()
#else
void MainFrame::init_menubar()
#endif // ENABLE_GCODE_VIEWER
{
#ifdef __APPLE__
wxMenuBar::SetAutoWindowMenu(false);
@ -1157,18 +1099,6 @@ void MainFrame::init_menubar()
[this](wxCommandEvent&) { Close(false); }, "exit");
}
#if !ENABLE_GCODE_VIEWER
#ifdef _MSC_VER
// \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators,
// as the simple numeric accelerators spoil all numeric data entry.
wxString sep = "\t\xA0";
wxString sep_space = "\xA0";
#else
wxString sep = " - ";
wxString sep_space = "";
#endif
#endif // !ENABLE_GCODE_VIEWER
// Edit menu
wxMenu* editMenu = nullptr;
if (m_plater != nullptr)
@ -1251,21 +1181,6 @@ void MainFrame::init_menubar()
[this](){return can_change_view(); }, this);
}
#if !ENABLE_GCODE_VIEWER
#if _WIN32
// This is needed on Windows to fake the CTRL+# of the window menu when using the numpad
wxAcceleratorEntry entries[6];
entries[0].Set(wxACCEL_CTRL, WXK_NUMPAD1, wxID_HIGHEST + 1);
entries[1].Set(wxACCEL_CTRL, WXK_NUMPAD2, wxID_HIGHEST + 2);
entries[2].Set(wxACCEL_CTRL, WXK_NUMPAD3, wxID_HIGHEST + 3);
entries[3].Set(wxACCEL_CTRL, WXK_NUMPAD4, wxID_HIGHEST + 4);
entries[4].Set(wxACCEL_CTRL, WXK_NUMPAD5, wxID_HIGHEST + 5);
entries[5].Set(wxACCEL_CTRL, WXK_NUMPAD6, wxID_HIGHEST + 6);
wxAcceleratorTable accel(6, entries);
SetAcceleratorTable(accel);
#endif // _WIN32
#endif // !ENABLE_GCODE_VIEWER
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"),
[this](wxCommandEvent&) { m_printhost_queue_dlg->Show(); }, "upload_queue", nullptr, []() {return true; }, this);
@ -1280,28 +1195,7 @@ void MainFrame::init_menubar()
wxMenu* viewMenu = nullptr;
if (m_plater) {
viewMenu = new wxMenu();
#if ENABLE_GCODE_VIEWER
add_common_view_menu_items(viewMenu, this, std::bind(&MainFrame::can_change_view, this));
#else
// The camera control accelerators are captured by GLCanvas3D::on_char().
append_menu_item(viewMenu, wxID_ANY, _L("Iso") + sep + "&0", _L("Iso View"), [this](wxCommandEvent&) { select_view("iso"); },
"", nullptr, [this](){return can_change_view(); }, this);
viewMenu->AppendSeparator();
//TRN To be shown in the main menu View->Top
append_menu_item(viewMenu, wxID_ANY, _L("Top") + sep + "&1", _L("Top View"), [this](wxCommandEvent&) { select_view("top"); },
"", nullptr, [this](){return can_change_view(); }, this);
//TRN To be shown in the main menu View->Bottom
append_menu_item(viewMenu, wxID_ANY, _L("Bottom") + sep + "&2", _L("Bottom View"), [this](wxCommandEvent&) { select_view("bottom"); },
"", nullptr, [this](){return can_change_view(); }, this);
append_menu_item(viewMenu, wxID_ANY, _L("Front") + sep + "&3", _L("Front View"), [this](wxCommandEvent&) { select_view("front"); },
"", nullptr, [this](){return can_change_view(); }, this);
append_menu_item(viewMenu, wxID_ANY, _L("Rear") + sep + "&4", _L("Rear View"), [this](wxCommandEvent&) { select_view("rear"); },
"", nullptr, [this](){return can_change_view(); }, this);
append_menu_item(viewMenu, wxID_ANY, _L("Left") + sep + "&5", _L("Left View"), [this](wxCommandEvent&) { select_view("left"); },
"", nullptr, [this](){return can_change_view(); }, this);
append_menu_item(viewMenu, wxID_ANY, _L("Right") + sep + "&6", _L("Right View"), [this](wxCommandEvent&) { select_view("right"); },
"", nullptr, [this](){return can_change_view(); }, this);
#endif // ENABLE_GCODE_VIEWER
viewMenu->AppendSeparator();
append_menu_check_item(viewMenu, wxID_ANY, _L("Show &labels") + sep + "E", _L("Show object/instance labels in 3D scene"),
[this](wxCommandEvent&) { m_plater->show_view3D_labels(!m_plater->are_view3D_labels_shown()); }, this,
@ -1312,49 +1206,11 @@ void MainFrame::init_menubar()
}
// Help menu
#if ENABLE_GCODE_VIEWER
auto helpMenu = generate_help_menu();
#else
auto helpMenu = new wxMenu();
{
append_menu_item(helpMenu, wxID_ANY, _L("Prusa 3D &Drivers"), _L("Open the Prusa3D drivers download page in your browser"),
[this](wxCommandEvent&) { wxGetApp().open_web_page_localized("https://www.prusa3d.com/downloads"); });
append_menu_item(helpMenu, wxID_ANY, _L("Software &Releases"), _L("Open the software releases page in your browser"),
[this](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/prusa3d/PrusaSlicer/releases"); });
//# my $versioncheck = $self->_append_menu_item($helpMenu, "Check for &Updates...", "Check for new Slic3r versions", sub{
//# wxTheApp->check_version(1);
//# });
//# $versioncheck->Enable(wxTheApp->have_version_check);
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("%s &Website"), SLIC3R_APP_NAME),
wxString::Format(_L("Open the %s website in your browser"), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { wxGetApp().open_web_page_localized("https://www.prusa3d.com/slicerweb"); });
// append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("%s &Manual"), SLIC3R_APP_NAME),
// wxString::Format(_L("Open the %s manual in your browser"), SLIC3R_APP_NAME),
// [this](wxCommandEvent&) { wxLaunchDefaultBrowser("http://manual.slic3r.org/"); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("System &Info"), _L("Show system information"),
[this](wxCommandEvent&) { wxGetApp().system_info(); });
append_menu_item(helpMenu, wxID_ANY, _L("Show &Configuration Folder"), _L("Show user configuration folder (datadir)"),
[this](wxCommandEvent&) { Slic3r::GUI::desktop_open_datadir_folder(); });
append_menu_item(helpMenu, wxID_ANY, _L("Report an I&ssue"), wxString::Format(_L("Report an issue on %s"), SLIC3R_APP_NAME),
[this](wxCommandEvent&) { wxLaunchDefaultBrowser("https://github.com/prusa3d/slic3r/issues/new"); });
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), SLIC3R_APP_NAME), _L("Show about dialog"),
[this](wxCommandEvent&) { Slic3r::GUI::about(); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
[this](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });
#if ENABLE_THUMBNAIL_GENERATOR_DEBUG
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, "DEBUG gcode thumbnails", "DEBUG ONLY - read the selected gcode file and generates png for the contained thumbnails",
[this](wxCommandEvent&) { wxGetApp().gcode_thumbnails_debug(); });
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG
}
#endif // ENABLE_GCODE_VIEWER
// menubar
// assign menubar to frame after appending items, otherwise special items
// will not be handled correctly
#if ENABLE_GCODE_VIEWER
m_menubar = new wxMenuBar();
m_menubar->Append(fileMenu, _L("&File"));
if (editMenu) m_menubar->Append(editMenu, _L("&Edit"));
@ -1364,26 +1220,11 @@ void MainFrame::init_menubar()
wxGetApp().add_config_menu(m_menubar);
m_menubar->Append(helpMenu, _L("&Help"));
SetMenuBar(m_menubar);
#else
auto menubar = new wxMenuBar();
menubar->Append(fileMenu, _L("&File"));
if (editMenu) menubar->Append(editMenu, _L("&Edit"));
menubar->Append(windowMenu, _L("&Window"));
if (viewMenu) menubar->Append(viewMenu, _L("&View"));
// Add additional menus from C++
wxGetApp().add_config_menu(menubar);
menubar->Append(helpMenu, _L("&Help"));
SetMenuBar(menubar);
#endif // ENABLE_GCODE_VIEWER
#ifdef __APPLE__
// This fixes a bug on Mac OS where the quit command doesn't emit window close events
// wx bug: https://trac.wxwidgets.org/ticket/18328
#if ENABLE_GCODE_VIEWER
wxMenu* apple_menu = m_menubar->OSXGetAppleMenu();
#else
wxMenu *apple_menu = menubar->OSXGetAppleMenu();
#endif // ENABLE_GCODE_VIEWER
if (apple_menu != nullptr) {
apple_menu->Bind(wxEVT_MENU, [this](wxCommandEvent &) {
Close();
@ -1395,7 +1236,6 @@ void MainFrame::init_menubar()
update_menubar();
}
#if ENABLE_GCODE_VIEWER
void MainFrame::init_menubar_as_gcodeviewer()
{
wxMenu* fileMenu = new wxMenu;
@ -1428,10 +1268,8 @@ void MainFrame::init_menubar_as_gcodeviewer()
m_menubar = new wxMenuBar();
m_menubar->Append(fileMenu, _L("&File"));
if (viewMenu != nullptr) m_menubar->Append(viewMenu, _L("&View"));
#if ENABLE_GCODE_VIEWER
// Add additional menus from C++
wxGetApp().add_config_menu(m_menubar);
#endif // ENABLE_GCODE_VIEWER
m_menubar->Append(helpMenu, _L("&Help"));
SetMenuBar(m_menubar);
@ -1446,14 +1284,11 @@ void MainFrame::init_menubar_as_gcodeviewer()
}
#endif // __APPLE__
}
#endif // ENABLE_GCODE_VIEWER
void MainFrame::update_menubar()
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
return;
#endif // ENABLE_GCODE_VIEWER
const bool is_fff = plater()->printer_technology() == ptFFF;
@ -1582,7 +1417,7 @@ void MainFrame::quick_slice(const int qs)
m_progress_dialog->Destroy();
m_progress_dialog = nullptr;
auto message = input_file_basename + _L(" was successfully sliced.");
auto message = format(_L("%1% was successfully sliced."), input_file_basename);
// wxTheApp->notify(message);
wxMessageDialog(this, message, _L("Slicing Done!"), wxOK | wxICON_INFORMATION).ShowModal();
// };
@ -1982,10 +1817,8 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, "settings_dialog"),
m_main_frame(mainframe)
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
return;
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__)
// ys_FIXME! temporary workaround for correct font scaling
@ -2058,10 +1891,8 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
return;
#endif // ENABLE_GCODE_VIEWER
const int& em = em_unit();
const wxSize& size = wxSize(85 * em, 50 * em);

View file

@ -71,9 +71,7 @@ class MainFrame : public DPIFrame
wxString m_qs_last_input_file = wxEmptyString;
wxString m_qs_last_output_file = wxEmptyString;
wxString m_last_config = wxEmptyString;
#if ENABLE_GCODE_VIEWER
wxMenuBar* m_menubar{ nullptr };
#endif // ENABLE_GCODE_VIEWER
#if 0
wxMenuItem* m_menu_item_repeat { nullptr }; // doesn't used now
@ -128,9 +126,7 @@ class MainFrame : public DPIFrame
Old,
New,
Dlg,
#if ENABLE_GCODE_VIEWER
GCodeViewer
#endif // ENABLE_GCODE_VIEWER
};
ESettingsLayout m_layout{ ESettingsLayout::Unknown };
@ -159,12 +155,8 @@ public:
// Register Win32 RawInput callbacks (3DConnexion) and removable media insert / remove callbacks.
// Called from wxEVT_ACTIVATE, as wxEVT_CREATE was not reliable (bug in wxWidgets?).
void register_win32_callbacks();
#if ENABLE_GCODE_VIEWER
void init_menubar_as_editor();
void init_menubar_as_gcodeviewer();
#else
void init_menubar();
#endif // ENABLE_GCODE_VIEWER
void update_menubar();
void update_ui_from_settings(bool apply_free_camera_correction = true);

View file

@ -90,7 +90,7 @@ void OG_CustomCtrl::init_ctrl_lines()
height = m_bmp_blinking_sz.GetHeight() + m_v_gap;
ctrl_lines.emplace_back(CtrlLine(height, this, line, true));
}
else if (opt_group->label_width != 0 && !line.label.IsEmpty())
else if (opt_group->label_width != 0 && (!line.label.IsEmpty() || option_set.front().opt.gui_type == "legend") )
{
wxSize label_sz = GetTextExtent(line.label);
height = label_sz.y * (label_sz.GetWidth() > int(opt_group->label_width * m_em_unit) ? 2 : 1) + m_v_gap;
@ -135,7 +135,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
}
wxString label = line.label;
if (opt_group->label_width != 0 && !label.IsEmpty())
if (opt_group->label_width != 0)
h_pos += opt_group->label_width * m_em_unit + m_h_gap;
int blinking_button_width = m_bmp_blinking_sz.GetWidth() + m_h_gap;
@ -177,10 +177,13 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
GetTextExtent(label, &label_w, &label_h, 0, 0, &m_font);
h_pos += label_w + 1 + m_h_gap;
}
h_pos += 3 * blinking_button_width;
h_pos += (opt.opt.gui_type == "legend" ? 1 : 3) * blinking_button_width;
if (field == field_in)
break;
break;
if (opt.opt.gui_type == "legend")
h_pos += 2 * blinking_button_width;
h_pos += field->getWindow()->GetSize().x;
if (option_set.size() == 1 && option_set.front().opt.full_width)
@ -556,7 +559,8 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_mode_bmp(wxDC& dc, wxCoord v_pos)
wxBitmap bmp = create_scaled_bitmap(bmp_name, ctrl, wxOSX ? 10 : 12);
wxCoord y_draw = v_pos + lround((height - get_bitmap_size(bmp).GetHeight()) / 2);
dc.DrawBitmap(bmp, 0, y_draw);
if (og_line.get_options().front().opt.gui_type != "legend")
dc.DrawBitmap(bmp, 0, y_draw);
return get_bitmap_size(bmp).GetWidth() + ctrl->m_h_gap;
}

View file

@ -106,11 +106,20 @@ OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title,
bool is_tab_opt /* = false */,
column_t extra_clmn /* = nullptr */) :
m_parent(_parent), title(title),
m_show_modified_btns(is_tab_opt),
m_use_custom_ctrl(is_tab_opt),
staticbox(title!=""), extra_column(extra_clmn)
{
}
bool OptionsGroup::is_legend_line()
{
if (m_lines.size() == 1) {
const std::vector<Option>& option_set = m_lines.front().get_options();
return !option_set.empty() && option_set.front().opt.gui_type == "legend";
}
return false;
}
void OptionsGroup::show_field(const t_config_option_key& opt_key, bool show/* = true*/)
{
Field* field = get_field(opt_key);
@ -196,16 +205,20 @@ void OptionsGroup::activate_line(Line& line)
}
}
if (!custom_ctrl && m_show_modified_btns) {
custom_ctrl = new OG_CustomCtrl((wxWindow*)this->stb, this);
sizer->Add(custom_ctrl, 0, wxEXPAND | wxALL, wxOSX || !staticbox ? 0 : 5);
}
auto option_set = line.get_options();
bool is_legend_line = option_set.front().opt.gui_type == "legend";
if (!custom_ctrl && m_use_custom_ctrl) {
custom_ctrl = new OG_CustomCtrl(is_legend_line ? this->parent() : (wxWindow*)this->stb, this);
if (is_legend_line)
sizer->Add(custom_ctrl, 0, wxEXPAND | wxLEFT, wxOSX ? 0 : 10);
else
sizer->Add(custom_ctrl, 0, wxEXPAND | wxALL, wxOSX || !staticbox ? 0 : 5);
}
// Set sidetext width for a better alignment of options in line
// "m_show_modified_btns==true" means that options groups are in tabs
if (option_set.size() > 1 && m_show_modified_btns) {
if (option_set.size() > 1 && m_use_custom_ctrl) {
sidetext_width = Field::def_width_thinner();
}
@ -231,7 +244,7 @@ void OptionsGroup::activate_line(Line& line)
m_use_custom_ctrl_as_parent = true;
// if we have an extra column, build it
if (extra_column && !m_show_modified_btns)
if (extra_column)
{
m_extra_column_item_ptrs.push_back(extra_column(this->ctrl_parent(), line));
grid_sizer->Add(m_extra_column_item_ptrs.back(), 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3);
@ -511,7 +524,7 @@ Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index
std::pair<std::string, int> pair(opt_key, opt_index);
m_opt_map.emplace(opt_id, pair);
if (m_show_modified_btns) // fill group and category values just fro options from Settings Tab
if (m_use_custom_ctrl) // fill group and category values just for options from Settings Tab
wxGetApp().sidebar().get_searcher().add_key(opt_id, title, this->config_category());
return Option(*m_config->def()->get(opt_key), opt_id);

View file

@ -129,7 +129,7 @@ public:
#endif /* __WXGTK__ */
wxWindow* ctrl_parent() const {
return this->stb ? (this->custom_ctrl && m_use_custom_ctrl_as_parent ? (wxWindow*)this->custom_ctrl : (wxWindow*)this->stb) : this->parent();
return this->custom_ctrl && m_use_custom_ctrl_as_parent ? (wxWindow*)this->custom_ctrl : (this->stb ? (wxWindow*)this->stb : this->parent());
}
void append_line(const Line& line);
@ -173,10 +173,6 @@ public:
inline void disable() { for (auto& field : m_fields) field.second->disable(); }
void set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); }
void set_show_modified_btns_val(bool show) {
m_show_modified_btns = show;
}
void clear_fields_except_of(const std::vector<std::string> left_fields);
void hide_labels() { label_width = 0; }
@ -187,6 +183,7 @@ public:
wxGridSizer* get_grid_sizer() { return m_grid_sizer; }
const std::vector<Line>& get_lines() { return m_lines; }
bool is_legend_line();
protected:
std::map<t_config_option_key, Option> m_options;
@ -203,7 +200,7 @@ protected:
bool m_disabled {false};
wxGridSizer* m_grid_sizer {nullptr};
// "true" if option is created in preset tabs
bool m_show_modified_btns{ false };
bool m_use_custom_ctrl{ false };
// "true" if control should be created on custom_ctrl
bool m_use_custom_ctrl_as_parent { false };

View file

@ -63,6 +63,7 @@
#include "Mouse3DController.hpp"
#include "Tab.hpp"
#include "Jobs/ArrangeJob.hpp"
#include "Jobs/FillBedJob.hpp"
#include "Jobs/RotoptimizeJob.hpp"
#include "Jobs/SLAImportJob.hpp"
#include "BackgroundSlicingProcess.hpp"
@ -745,9 +746,9 @@ Sidebar::Sidebar(Plater *parent)
(*btn)->Hide();
};
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _L("Send to printer ") + GUI::shortkey_ctrl_prefix() + "Shift+G");
init_scalable_btn(&p->btn_send_gcode , "export_gcode", _L("Send to printer") + " " +GUI::shortkey_ctrl_prefix() + "Shift+G");
// init_scalable_btn(&p->btn_eject_device, "eject_sd" , _L("Remove device ") + GUI::shortkey_ctrl_prefix() + "T");
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _L("Export to SD card / Flash drive ") + GUI::shortkey_ctrl_prefix() + "U");
init_scalable_btn(&p->btn_export_gcode_removable, "export_to_sd", _L("Export to SD card / Flash drive") + " " + GUI::shortkey_ctrl_prefix() + "U");
// regular buttons "Slice now" and "Export G-code"
@ -1169,7 +1170,6 @@ void Sidebar::update_sliced_info_sizer()
wxString::Format("%.2f", ps.total_cost);
p->sliced_info->SetTextAndShow(siCost, info_text, new_label);
#if ENABLE_GCODE_VIEWER
if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A")
p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A");
else {
@ -1191,56 +1191,6 @@ void Sidebar::update_sliced_info_sizer()
}
p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label);
}
#else
if (ps.estimated_normal_print_time == "N/A" && ps.estimated_silent_print_time == "N/A")
p->sliced_info->SetTextAndShow(siEstimatedTime, "N/A");
else {
new_label = _L("Estimated printing time") + ":";
info_text = "";
wxString str_color = _L("Color");
wxString str_pause = _L("Pause");
auto fill_labels = [str_color, str_pause](const std::vector<std::pair<CustomGCode::Type, std::string>>& times,
wxString& new_label, wxString& info_text)
{
int color_change_count = 0;
for (auto time : times)
if (time.first == CustomGCode::ColorChange)
color_change_count++;
for (int i = (int)times.size() - 1; i >= 0; --i)
{
if (i == 0 || times[i - 1].first == CustomGCode::PausePrint)
new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count);
else if (times[i - 1].first == CustomGCode::ColorChange)
new_label += format_wxstr("\n - %1%%2%", str_color + " ", color_change_count--);
if (i != (int)times.size() - 1 && times[i].first == CustomGCode::PausePrint)
new_label += format_wxstr(" -> %1%", str_pause);
info_text += format_wxstr("\n%1%", times[i].second);
}
};
if (ps.estimated_normal_print_time != "N/A") {
new_label += format_wxstr("\n - %1%", _L("normal mode"));
info_text += format_wxstr("\n%1%", ps.estimated_normal_print_time);
fill_labels(ps.estimated_normal_custom_gcode_print_times, new_label, info_text);
// uncomment next line to not disappear slicing finished notif when colapsing sidebar before time estimate
//if (p->plater->is_sidebar_collapsed())
p->plater->get_notification_manager()->set_slicing_complete_large(p->plater->is_sidebar_collapsed());
p->plater->get_notification_manager()->set_slicing_complete_print_time("Estimated printing time: " + ps.estimated_normal_print_time);
}
if (ps.estimated_silent_print_time != "N/A") {
new_label += format_wxstr("\n - %1%", _L("stealth mode"));
info_text += format_wxstr("\n%1%", ps.estimated_silent_print_time);
fill_labels(ps.estimated_silent_custom_gcode_print_times, new_label, info_text);
}
p->sliced_info->SetTextAndShow(siEstimatedTime, info_text, new_label);
}
#endif // !ENABLE_GCODE_VIEWER
// if there is a wipe tower, insert number of toolchanges info into the array:
p->sliced_info->SetTextAndShow(siWTNumbetOfToolchanges, is_wipe_tower ? wxString::Format("%.d", ps.total_toolchanges) : "N/A");
@ -1333,9 +1283,7 @@ void Sidebar::collapse(bool collapse)
p->plater->Layout();
// save collapsing state to the AppConfig
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor())
#endif // ENABLE_GCODE_VIEWER
wxGetApp().app_config->set("collapsed_sidebar", collapse ? "1" : "0");
}
@ -1375,15 +1323,11 @@ private:
Plater *plater;
static const std::regex pattern_drop;
#if ENABLE_GCODE_VIEWER
static const std::regex pattern_gcode_drop;
#endif // ENABLE_GCODE_VIEWER
};
const std::regex PlaterDropTarget::pattern_drop(".*[.](stl|obj|amf|3mf|prusa)", std::regex::icase);
#if ENABLE_GCODE_VIEWER
const std::regex PlaterDropTarget::pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase);
#endif // ENABLE_GCODE_VIEWER
enum class LoadType : unsigned char
{
@ -1453,7 +1397,6 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
{
std::vector<fs::path> paths;
#if ENABLE_GCODE_VIEWER
#ifdef WIN32
// hides the system icon
this->MSWUpdateDragImageOnLeave();
@ -1478,17 +1421,14 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
}
return false;
}
#endif // ENABLE_GCODE_VIEWER
// editor section
for (const auto &filename : filenames) {
fs::path path(into_path(filename));
if (std::regex_match(path.string(), pattern_drop))
paths.push_back(std::move(path));
#if ENABLE_GCODE_VIEWER
else if (std::regex_match(path.string(), pattern_gcode_drop))
start_new_gcodeviewer(&filename);
#endif // ENABLE_GCODE_VIEWER
else
return false;
}
@ -1496,6 +1436,7 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
// Likely all paths processed were gcodes, for which a G-code viewer instance has hopefully been started.
return false;
// searches for project files
for (std::vector<fs::path>::const_reverse_iterator it = paths.rbegin(); it != paths.rend(); ++it) {
std::string filename = (*it).filename().string();
if (boost::algorithm::iends_with(filename, ".3mf") || boost::algorithm::iends_with(filename, ".amf")) {
@ -1538,10 +1479,31 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi
break;
}
}
break;
return true;
}
}
// other files
wxString snapshot_label;
assert(!paths.empty());
if (paths.size() == 1) {
snapshot_label = _L("Load File");
snapshot_label += ": ";
snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str());
}
else {
snapshot_label = _L("Load Files");
snapshot_label += ": ";
snapshot_label += wxString::FromUTF8(paths.front().filename().string().c_str());
for (size_t i = 1; i < paths.size(); ++i) {
snapshot_label += ", ";
snapshot_label += wxString::FromUTF8(paths[i].filename().string().c_str());
}
}
Plater::TakeSnapshot snapshot(plater, snapshot_label);
plater->load_files(paths);
return true;
}
@ -1583,11 +1545,7 @@ struct Plater::priv
Slic3r::SLAPrint sla_print;
Slic3r::Model model;
PrinterTechnology printer_technology = ptFFF;
#if ENABLE_GCODE_VIEWER
Slic3r::GCodeProcessor::Result gcode_result;
#else
Slic3r::GCodePreviewData gcode_preview_data;
#endif // ENABLE_GCODE_VIEWER
// GUI elements
wxSizer* panel_sizer{ nullptr };
@ -1616,7 +1574,7 @@ struct Plater::priv
class Jobs: public ExclusiveJobGroup
{
priv *m;
size_t m_arrange_id, m_rotoptimize_id, m_sla_import_id;
size_t m_arrange_id, m_fill_bed_id, m_rotoptimize_id, m_sla_import_id;
void before_start() override { m->background_process.stop(); }
@ -1624,6 +1582,7 @@ struct Plater::priv
Jobs(priv *_m) : m(_m)
{
m_arrange_id = add_job(std::make_unique<ArrangeJob>(m->statusbar(), m->q));
m_fill_bed_id = add_job(std::make_unique<FillBedJob>(m->statusbar(), m->q));
m_rotoptimize_id = add_job(std::make_unique<RotoptimizeJob>(m->statusbar(), m->q));
m_sla_import_id = add_job(std::make_unique<SLAImportJob>(m->statusbar(), m->q));
}
@ -1633,6 +1592,12 @@ struct Plater::priv
m->take_snapshot(_(L("Arrange")));
start(m_arrange_id);
}
void fill_bed()
{
m->take_snapshot(_(L("Fill bed")));
start(m_fill_bed_id);
}
void optimize_rotation()
{
@ -1695,13 +1660,11 @@ struct Plater::priv
bool init_view_toolbar();
bool init_collapse_toolbar();
#if ENABLE_GCODE_VIEWER
void update_preview_bottom_toolbar();
void update_preview_moves_slider();
void enable_preview_moves_slider(bool enable);
void reset_gcode_toolpaths();
#endif // ENABLE_GCODE_VIEWER
void reset_all_gizmos();
void update_ui_from_settings(bool apply_free_camera_correction = true);
@ -1923,11 +1886,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
background_process.set_fff_print(&fff_print);
background_process.set_sla_print(&sla_print);
#if ENABLE_GCODE_VIEWER
background_process.set_gcode_result(&gcode_result);
#else
background_process.set_gcode_preview_data(&gcode_preview_data);
#endif // ENABLE_GCODE_VIEWER
background_process.set_thumbnail_cb([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background)
{
std::packaged_task<void(ThumbnailsList&, const Vec2ds&, bool, bool, bool, bool)> task([this](ThumbnailsList& thumbnails, const Vec2ds& sizes, bool printable_only, bool parts_only, bool show_bed, bool transparent_background) {
@ -1952,11 +1911,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
view3D = new View3D(q, &model, config, &background_process);
#if ENABLE_GCODE_VIEWER
preview = new Preview(q, &model, config, &background_process, &gcode_result, [this]() { schedule_background_process(); });
#else
preview = new Preview(q, &model, config, &background_process, &gcode_preview_data, [this]() { schedule_background_process(); });
#endif // ENABLE_GCODE_VIEWER
#ifdef __APPLE__
// set default view_toolbar icons size equal to GLGizmosManager::Default_Icons_Size
@ -1987,22 +1942,16 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// Events:
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
// Preset change event
sidebar->Bind(wxEVT_COMBOBOX, &priv::on_select_preset, this);
sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); });
sidebar->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); });
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
wxGLCanvas* view3D_canvas = view3D->get_wxglcanvas();
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
// 3DScene events:
view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); });
view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
@ -2044,10 +1993,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this);
view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); });
}
view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_BED_SHAPE, [q](SimpleEvent&) { q->set_bed_shape(); });
// Preview events:
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
@ -2055,37 +2002,24 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_TAB, [this](SimpleEvent&) { select_next_view_3D(); });
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); });
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_JUMP_TO, [this](wxKeyEvent& evt) { preview->jump_layers_slider(evt); });
#if ENABLE_GCODE_VIEWER
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_LAYERS_SLIDER, [this](wxKeyEvent& evt) { preview->move_layers_slider(evt); });
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_layers_slider(evt); });
#else
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_MOVE_DOUBLE_SLIDER, [this](wxKeyEvent& evt) { preview->move_double_slider(evt); });
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_EDIT_COLOR_CHANGE, [this](wxKeyEvent& evt) { preview->edit_double_slider(evt); });
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
q->Bind(EVT_SLICING_COMPLETED, &priv::on_slicing_completed, this);
q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this);
q->Bind(EVT_EXPORT_BEGAN, &priv::on_export_began, this);
q->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); });
q->Bind(EVT_GLVIEWTOOLBAR_PREVIEW, [q](SimpleEvent&) { q->select_view_3D("Preview"); });
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
// Drop target:
q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership
q->Layout();
#if ENABLE_GCODE_VIEWER
set_current_panel(wxGetApp().is_editor() ? (wxPanel*)view3D : (wxPanel*)preview);
if (wxGetApp().is_gcode_viewer())
preview->hide_layers_slider();
#else
set_current_panel(view3D);
#endif // ENABLE_GCODE_VIEWER
// updates camera type from .ini file
camera.enable_update_config_on_type_change(true);
@ -2111,15 +2045,14 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
#endif /* _WIN32 */
notification_manager = new NotificationManager(this->q);
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); });
this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); });
this->q->Bind(EVT_PRESET_UPDATE_AVAILABLE_CLICKED, [this](PresetUpdateAvailableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); });
this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this, q](RemovableDriveEjectEvent &evt) {
if (evt.data.second) {
this->show_action_buttons(this->ready_to_slice);
notification_manager->close_notification_of_type(NotificationType::ExportFinished);
notification_manager->push_notification(format(_L("Successfully unmounted. The device %s(%s) can now be safely removed from the computer."),evt.data.first.name, evt.data.first.path),
NotificationManager::NotificationLevel::RegularNotification, *q->get_current_canvas3D());
} else {
@ -2139,9 +2072,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); });
#endif /* _WIN32 */
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
// Initialize the Undo / Redo stack with a first snapshot.
this->take_snapshot(_L("New Project"));
@ -2156,14 +2087,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
wxGetApp().other_instance_message_handler()->init(this->q);
// collapse sidebar according to saved value
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_editor()) {
#endif // ENABLE_GCODE_VIEWER
bool is_collapsed = wxGetApp().app_config->get("collapsed_sidebar") == "1";
sidebar->collapse(is_collapsed);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
}
Plater::priv::~priv()
@ -2212,9 +2139,7 @@ void Plater::priv::select_view_3D(const std::string& name)
else if (name == "Preview")
set_current_panel(preview);
#if ENABLE_GCODE_VIEWER
wxGetApp().update_ui_from_settings(false);
#endif // ENABLE_GCODE_VIEWER
}
void Plater::priv::select_next_view_3D()
@ -2743,11 +2668,6 @@ void Plater::priv::deselect_all()
void Plater::priv::remove(size_t obj_idx)
{
#if !ENABLE_GCODE_VIEWER
// Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false);
#endif // !ENABLE_GCODE_VIEWER
if (view3D->is_layers_editing_enabled())
view3D->enable_layers_editing(false);
@ -2778,18 +2698,11 @@ void Plater::priv::reset()
set_project_filename(wxEmptyString);
#if !ENABLE_GCODE_VIEWER
// Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false);
#endif // !ENABLE_GCODE_VIEWER
if (view3D->is_layers_editing_enabled())
view3D->enable_layers_editing(false);
#if ENABLE_GCODE_VIEWER
reset_gcode_toolpaths();
gcode_result.reset();
#endif // ENABLE_GCODE_VIEWER
// Stop and reset the Print content.
this->background_process.reset();
@ -2826,8 +2739,8 @@ void Plater::find_new_position(const ModelInstancePtrs &instances,
movable.emplace_back(std::move(arrpoly));
}
if (p->view3D->get_canvas3d()->get_wipe_tower_info())
fixed.emplace_back(get_wipe_tower_arrangepoly(*this));
if (auto wt = get_wipe_tower_arrangepoly(*this))
fixed.emplace_back(*wt);
arrangement::arrange(movable, fixed, get_bed_shape(*config()),
arrangement::ArrangeParams{min_d});
@ -2936,19 +2849,12 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
this->sidebar->show_sliced_info_sizer(false);
// Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
// Otherwise they will be just refreshed.
#if ENABLE_GCODE_VIEWER
if (this->preview != nullptr) {
// If the preview is not visible, the following line just invalidates the preview,
// but the G-code paths or SLA preview are calculated first once the preview is made visible.
reset_gcode_toolpaths();
this->preview->reload_print();
}
#else
if (this->preview != nullptr)
// If the preview is not visible, the following line just invalidates the preview,
// but the G-code paths or SLA preview are calculated first once the preview is made visible.
this->preview->reload_print();
#endif // ENABLE_GCODE_VIEWER
// In FDM mode, we need to reload the 3D scene because of the wipe tower preview box.
// In SLA mode, we need to reload the 3D scene every time to show the support structures.
if (this->printer_technology == ptSLA || (this->printer_technology == ptFFF && this->config->opt_bool("wipe_tower")))
@ -3962,6 +3868,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
[this](wxCommandEvent&) { q->decrease_instances(); }, "remove_copies", nullptr, [this]() { return can_decrease_instances(); }, q);
wxMenuItem* item_set_number_of_copies = append_menu_item(menu, wxID_ANY, _L("Set number of instances") + dots, _L("Change the number of instances of the selected object"),
[this](wxCommandEvent&) { q->set_number_of_copies(); }, "number_of_copies", nullptr, [this]() { return can_increase_instances(); }, q);
append_menu_item(menu, wxID_ANY, _L("Fill bed with instances") + dots, _L("Fill the remaining area of bed with instances of the selected object"),
[this](wxCommandEvent&) { q->fill_bed_with_instances(); }, "", nullptr, [this]() { return can_increase_instances(); }, q);
items_increase.push_back(item_increase);
@ -4114,10 +4022,8 @@ void Plater::priv::reset_canvas_volumes()
bool Plater::priv::init_view_toolbar()
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
return true;
#endif // ENABLE_GCODE_VIEWER
if (view_toolbar.get_items_count() > 0)
// already initialized
@ -4164,10 +4070,8 @@ bool Plater::priv::init_view_toolbar()
bool Plater::priv::init_collapse_toolbar()
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer())
return true;
#endif // ENABLE_GCODE_VIEWER
if (collapse_toolbar.get_items_count() > 0)
// already initialized
@ -4208,7 +4112,6 @@ bool Plater::priv::init_collapse_toolbar()
return true;
}
#if ENABLE_GCODE_VIEWER
void Plater::priv::update_preview_bottom_toolbar()
{
preview->update_bottom_toolbar();
@ -4228,7 +4131,6 @@ void Plater::priv::reset_gcode_toolpaths()
{
preview->get_canvas3d()->reset_gcode_toolpaths();
}
#endif // ENABLE_GCODE_VIEWER
bool Plater::priv::can_set_instance_to_object() const
{
@ -4785,7 +4687,6 @@ void Plater::extract_config_from_project()
load_files(input_paths, false, true);
}
#if ENABLE_GCODE_VIEWER
void Plater::load_gcode()
{
// Ask user for a gcode file name.
@ -4836,7 +4737,6 @@ void Plater::refresh_print()
{
p->preview->refresh_print();
}
#endif // ENABLE_GCODE_VIEWER
std::vector<size_t> Plater::load_files(const std::vector<fs::path>& input_files, bool load_model, bool load_config, bool imperial_units /*= false*/) { return p->load_files(input_files, load_model, load_config, imperial_units); }
@ -4974,6 +4874,11 @@ void Plater::set_number_of_copies(/*size_t num*/)
decrease_instances(-diff);
}
void Plater::fill_bed_with_instances()
{
p->m_ui_jobs.fill_bed();
}
bool Plater::is_selection_empty() const
{
return p->get_selection().is_empty() || p->get_selection().is_wipe_tower();
@ -5341,9 +5246,7 @@ void Plater::reslice()
if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0)
return;
#if ENABLE_GCODE_VIEWER
bool clean_gcode_toolpaths = true;
#endif // ENABLE_GCODE_VIEWER
if (p->background_process.running())
{
if (wxGetApp().get_mode() == comSimple)
@ -5356,7 +5259,6 @@ void Plater::reslice()
}
else if (!p->background_process.empty() && !p->background_process.idle())
p->show_action_buttons(true);
#if ENABLE_GCODE_VIEWER
else
clean_gcode_toolpaths = false;
@ -5365,10 +5267,6 @@ void Plater::reslice()
// update type of preview
p->preview->update_view_type(!clean_gcode_toolpaths);
#else
// update type of preview
p->preview->update_view_type(true);
#endif // ENABLE_GCODE_VIEWER
}
void Plater::reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages)
@ -5585,9 +5483,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
// print technology is changed, so we should to update a search list
p->sidebar->update_searcher();
p->sidebar->show_sliced_info_sizer(false);
#if ENABLE_GCODE_VIEWER
p->reset_gcode_toolpaths();
#endif // ENABLE_GCODE_VIEWER
}
else if (opt_key == "bed_shape" || opt_key == "bed_custom_texture" || opt_key == "bed_custom_model") {
bed_shape_changed = true;
@ -5630,23 +5526,15 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
void Plater::set_bed_shape() const
{
#if ENABLE_GCODE_VIEWER
set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values,
p->config->option<ConfigOptionString>("bed_custom_texture")->value,
p->config->option<ConfigOptionString>("bed_custom_model")->value);
#else
p->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values,
p->config->option<ConfigOptionString>("bed_custom_texture")->value,
p->config->option<ConfigOptionString>("bed_custom_model")->value);
#endif // ENABLE_GCODE_VIEWER
}
#if ENABLE_GCODE_VIEWER
void Plater::set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom) const
{
p->set_bed_shape(shape, custom_texture, custom_model, force_as_custom);
}
#endif // ENABLE_GCODE_VIEWER
void Plater::force_filament_colors_update()
{
@ -5702,17 +5590,11 @@ void Plater::on_activate()
}
// Get vector of extruder colors considering filament color, if extruder color is undefined.
#if ENABLE_GCODE_VIEWER
std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GCodeProcessor::Result* const result) const
#else
std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const
#endif // ENABLE_GCODE_VIEWER
{
#if ENABLE_GCODE_VIEWER
if (wxGetApp().is_gcode_viewer() && result != nullptr)
return result->extruder_colors;
else {
#endif // ENABLE_GCODE_VIEWER
const Slic3r::DynamicPrintConfig* config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
std::vector<std::string> extruder_colors;
if (!config->has("extruder_colour")) // in case of a SLA print
@ -5728,23 +5610,15 @@ std::vector<std::string> Plater::get_extruder_colors_from_plater_config() const
extruder_colors[i] = filament_colours[i];
return extruder_colors;
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
}
/* Get vector of colors used for rendering of a Preview scene in "Color print" mode
* It consists of extruder colors and colors, saved in model.custom_gcode_per_print_z
*/
#if ENABLE_GCODE_VIEWER
std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessor::Result* const result) const
{
std::vector<std::string> colors = get_extruder_colors_from_plater_config(result);
#else
std::vector<std::string> Plater::get_colors_for_color_print() const
{
std::vector<std::string> colors = get_extruder_colors_from_plater_config();
#endif // ENABLE_GCODE_VIEWER
colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size());
for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes)
@ -5789,6 +5663,11 @@ GLCanvas3D* Plater::canvas3D()
return p->view3D->get_canvas3d();
}
const GLCanvas3D* Plater::canvas3D() const
{
return p->view3D->get_canvas3d();
}
GLCanvas3D* Plater::get_current_canvas3D()
{
return p->get_current_canvas3D();
@ -5826,23 +5705,13 @@ PrinterTechnology Plater::printer_technology() const
const DynamicPrintConfig * Plater::config() const { return p->config; }
#if ENABLE_GCODE_VIEWER
bool Plater::set_printer_technology(PrinterTechnology printer_technology)
#else
void Plater::set_printer_technology(PrinterTechnology printer_technology)
#endif // ENABLE_GCODE_VIEWER
{
p->printer_technology = printer_technology;
#if ENABLE_GCODE_VIEWER
bool ret = p->background_process.select_technology(printer_technology);
if (ret) {
// Update the active presets.
}
#else
if (p->background_process.select_technology(printer_technology)) {
// Update the active presets.
}
#endif // ENABLE_GCODE_VIEWER
//FIXME for SLA synchronize
//p->background_process.apply(Model)!
@ -5856,9 +5725,7 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology)
p->sidebar->get_searcher().set_printer_technology(printer_technology);
#if ENABLE_GCODE_VIEWER
return ret;
#endif // ENABLE_GCODE_VIEWER
}
void Plater::changed_object(int obj_idx)
@ -6006,24 +5873,20 @@ bool Plater::init_view_toolbar()
return p->init_view_toolbar();
}
#if ENABLE_GCODE_VIEWER
void Plater::enable_view_toolbar(bool enable)
{
p->view_toolbar.set_enabled(enable);
}
#endif // ENABLE_GCODE_VIEWER
bool Plater::init_collapse_toolbar()
{
return p->init_collapse_toolbar();
}
#if ENABLE_GCODE_VIEWER
void Plater::enable_collapse_toolbar(bool enable)
{
p->collapse_toolbar.set_enabled(enable);
}
#endif // ENABLE_GCODE_VIEWER
const Camera& Plater::get_camera() const
{
@ -6078,7 +5941,6 @@ GLToolbar& Plater::get_collapse_toolbar()
return p->collapse_toolbar;
}
#if ENABLE_GCODE_VIEWER
void Plater::update_preview_bottom_toolbar()
{
p->update_preview_bottom_toolbar();
@ -6098,7 +5960,6 @@ void Plater::reset_gcode_toolpaths()
{
p->reset_gcode_toolpaths();
}
#endif // ENABLE_GCODE_VIEWER
const Mouse3DController& Plater::get_mouse3d_controller() const
{
@ -6167,9 +6028,7 @@ bool Plater::can_undo() const { return p->undo_redo_stack().has_undo_snapshot();
bool Plater::can_redo() const { return p->undo_redo_stack().has_redo_snapshot(); }
bool Plater::can_reload_from_disk() const { return p->can_reload_from_disk(); }
const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); }
#if ENABLE_GCODE_VIEWER
void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); }
#endif // ENABLE_GCODE_VIEWER
void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); }
void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); }
bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); }

View file

@ -11,9 +11,7 @@
#include "libslic3r/Preset.hpp"
#include "libslic3r/BoundingBox.hpp"
#if ENABLE_GCODE_VIEWER
#include "libslic3r/GCode/GCodeProcessor.hpp"
#endif // ENABLE_GCODE_VIEWER
#include "Jobs/Job.hpp"
#include "Search.hpp"
@ -144,11 +142,9 @@ public:
void add_model(bool imperial_units = false);
void import_sl1_archive();
void extract_config_from_project();
#if ENABLE_GCODE_VIEWER
void load_gcode();
void load_gcode(const wxString& filename);
void refresh_print();
#endif // ENABLE_GCODE_VIEWER
std::vector<size_t> load_files(const std::vector<boost::filesystem::path>& input_files, bool load_model = true, bool load_config = true, bool imperial_units = false);
// To be called when providing a list of files to the GUI slic3r on command line.
@ -185,6 +181,7 @@ public:
void increase_instances(size_t num = 1);
void decrease_instances(size_t num = 1);
void set_number_of_copies(/*size_t num*/);
void fill_bed_with_instances();
bool is_selection_empty() const;
void scale_selection_to_fit_print_volume();
void convert_unit(bool from_imperial_unit);
@ -223,9 +220,7 @@ public:
bool search_string_getter(int idx, const char** label, const char** tooltip);
// For the memory statistics.
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
#if ENABLE_GCODE_VIEWER
void clear_undo_redo_stack_main();
#endif // ENABLE_GCODE_VIEWER
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
void enter_gizmos_stack();
void leave_gizmos_stack();
@ -236,13 +231,8 @@ public:
void force_print_bed_update();
// On activating the parent window.
void on_activate();
#if ENABLE_GCODE_VIEWER
std::vector<std::string> get_extruder_colors_from_plater_config(const GCodeProcessor::Result* const result = nullptr) const;
std::vector<std::string> get_colors_for_color_print(const GCodeProcessor::Result* const result = nullptr) const;
#else
std::vector<std::string> get_extruder_colors_from_plater_config() const;
std::vector<std::string> get_colors_for_color_print() const;
#endif // ENABLE_GCODE_VIEWER
void update_object_menu();
void show_action_buttons(const bool is_ready_to_slice) const;
@ -256,6 +246,7 @@ public:
int get_selected_object_idx();
bool is_single_full_object_selection() const;
GLCanvas3D* canvas3D();
const GLCanvas3D * canvas3D() const;
GLCanvas3D* get_current_canvas3D();
BoundingBoxf bed_shape_bb() const;
@ -268,11 +259,7 @@ public:
PrinterTechnology printer_technology() const;
const DynamicPrintConfig * config() const;
#if ENABLE_GCODE_VIEWER
bool set_printer_technology(PrinterTechnology printer_technology);
#else
void set_printer_technology(PrinterTechnology printer_technology);
#endif // ENABLE_GCODE_VIEWER
void copy_selection_to_clipboard();
void paste_from_clipboard();
@ -298,13 +285,9 @@ public:
void sys_color_changed();
bool init_view_toolbar();
#if ENABLE_GCODE_VIEWER
void enable_view_toolbar(bool enable);
#endif // ENABLE_GCODE_VIEWER
bool init_collapse_toolbar();
#if ENABLE_GCODE_VIEWER
void enable_collapse_toolbar(bool enable);
#endif // ENABLE_GCODE_VIEWER
const Camera& get_camera() const;
Camera& get_camera();
@ -323,23 +306,19 @@ public:
const GLToolbar& get_collapse_toolbar() const;
GLToolbar& get_collapse_toolbar();
#if ENABLE_GCODE_VIEWER
void update_preview_bottom_toolbar();
void update_preview_moves_slider();
void enable_preview_moves_slider(bool enable);
void reset_gcode_toolpaths();
void reset_last_loaded_gcode() { m_last_loaded_gcode = ""; }
#endif // ENABLE_GCODE_VIEWER
const Mouse3DController& get_mouse3d_controller() const;
Mouse3DController& get_mouse3d_controller();
void set_bed_shape() const;
#if ENABLE_GCODE_VIEWER
void set_bed_shape(const Pointfs& shape, const std::string& custom_texture, const std::string& custom_model, bool force_as_custom = false) const;
#endif // ENABLE_GCODE_VIEWER
const NotificationManager* get_notification_manager() const;
NotificationManager* get_notification_manager();
@ -394,9 +373,7 @@ private:
bool m_tracking_popup_menu = false;
wxString m_tracking_popup_menu_error_message;
#if ENABLE_GCODE_VIEWER
wxString m_last_loaded_gcode;
#endif // ENABLE_GCODE_VIEWER
void suppress_snapshots();
void allow_snapshots();

View file

@ -40,25 +40,17 @@ void PreferencesDialog::build()
// readonly = > !wxTheApp->have_version_check,
// ));
#if ENABLE_GCODE_VIEWER
bool is_editor = wxGetApp().is_editor();
#endif // ENABLE_GCODE_VIEWER
ConfigOptionDef def;
#if ENABLE_GCODE_VIEWER
Option option(def, "");
if (is_editor) {
#endif // ENABLE_GCODE_VIEWER
def.label = L("Remember output directory");
def.type = coBool;
def.tooltip = L("If this is enabled, Slic3r will prompt the last output directory "
"instead of the one containing the input files.");
def.set_default_value(new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path") == "1" : true });
#if ENABLE_GCODE_VIEWER
option = Option(def, "remember_output_path");
#else
Option option(def, "remember_output_path");
#endif // ENABLE_GCODE_VIEWER
m_optgroup_general->append_single_option_line(option);
def.label = L("Auto-center parts");
@ -134,9 +126,7 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->has("single_instance") ? app_config->get("single_instance") == "1" : false });
option = Option(def, "single_instance");
m_optgroup_general->append_single_option_line(option);
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
#if __APPLE__
def.label = L("Use Retina resolution for the 3D scene");
@ -221,9 +211,7 @@ void PreferencesDialog::build()
}
};
#if ENABLE_GCODE_VIEWER
if (is_editor) {
#endif // ENABLE_GCODE_VIEWER
def.label = L("Show sidebar collapse/expand button");
def.type = coBool;
def.tooltip = L("If enabled, the button for the collapse sidebar will be appeared in top right corner of the 3D Scene");
@ -237,7 +225,6 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->get("use_custom_toolbar_size") == "1" });
option = Option(def, "use_custom_toolbar_size");
m_optgroup_gui->append_single_option_line(option);
#if ENABLE_GCODE_VIEWER
}
def.label = L("Sequential slider applied only to top layer");
@ -247,24 +234,17 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->get("seq_top_layer_only") == "1" });
option = Option(def, "seq_top_layer_only");
m_optgroup_gui->append_single_option_line(option);
#endif // ENABLE_GCODE_VIEWER
m_optgroup_gui->activate();
#if ENABLE_GCODE_VIEWER
if (is_editor) {
#endif // ENABLE_GCODE_VIEWER
create_icon_size_slider();
m_icon_size_sizer->ShowItems(app_config->get("use_custom_toolbar_size") == "1");
create_settings_mode_widget();
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
if (is_editor) {
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_ENVIRONMENT_MAP
m_optgroup_render = std::make_shared<ConfigOptionsGroup>(this, _L("Render"));
m_optgroup_render->label_width = 40;
@ -281,18 +261,14 @@ void PreferencesDialog::build()
m_optgroup_render->activate();
#endif // ENABLE_ENVIRONMENT_MAP
#if ENABLE_GCODE_VIEWER
}
#endif // ENABLE_GCODE_VIEWER
auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(m_optgroup_general->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
sizer->Add(m_optgroup_camera->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
sizer->Add(m_optgroup_gui->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
#if ENABLE_ENVIRONMENT_MAP
#if ENABLE_GCODE_VIEWER
if (m_optgroup_render != nullptr)
#endif // ENABLE_GCODE_VIEWER
sizer->Add(m_optgroup_render->sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
#endif // ENABLE_ENVIRONMENT_MAP

View file

@ -81,7 +81,7 @@ void RemovableDriveManager::eject_drive()
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
this->update();
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
BOOST_LOG_TRIVIAL(info) << "Ejecting started";
tbb::mutex::scoped_lock lock(m_drives_mutex);
auto it_drive_data = this->find_last_save_path_drive_data();
if (it_drive_data != m_current_drives.end()) {
@ -90,7 +90,7 @@ void RemovableDriveManager::eject_drive()
mpath = mpath.substr(0, mpath.size() - 1);
HANDLE handle = CreateFileW(boost::nowide::widen(mpath).c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE) {
std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n";
BOOST_LOG_TRIVIAL(error) << "Ejecting " << mpath << " failed (handle == INVALID_HANDLE_VALUE): " << GetLastError();
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
@ -99,19 +99,22 @@ void RemovableDriveManager::eject_drive()
DWORD deviceControlRetVal(0);
//these 3 commands should eject device safely but they dont, the device does disappear from file explorer but the "device was safely remove" notification doesnt trigger.
//sd cards does trigger WM_DEVICECHANGE messege, usb drives dont
DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
BOOL e1 = DeviceIoControl(handle, FSCTL_LOCK_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
BOOST_LOG_TRIVIAL(debug) << "FSCTL_LOCK_VOLUME " << e1 << " ; " << deviceControlRetVal << " ; " << GetLastError();
BOOL e2 = DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
BOOST_LOG_TRIVIAL(debug) << "FSCTL_DISMOUNT_VOLUME " << e2 << " ; " << deviceControlRetVal << " ; " << GetLastError();
// some implemenatations also calls IOCTL_STORAGE_MEDIA_REMOVAL here but it returns error to me
BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
if (error == 0) {
CloseHandle(handle);
BOOST_LOG_TRIVIAL(error) << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";
BOOST_LOG_TRIVIAL(error) << "Ejecting " << mpath << " failed (IOCTL_STORAGE_EJECT_MEDIA)" << deviceControlRetVal << " " << GetLastError();
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));
return;
}
CloseHandle(handle);
BOOST_LOG_TRIVIAL(info) << "Ejecting finished";
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair< DriveData, bool >(std::move(*it_drive_data), true)));
@ -256,6 +259,7 @@ void RemovableDriveManager::eject_drive()
#ifndef REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
this->update();
#endif // REMOVABLE_DRIVE_MANAGER_OS_CALLBACKS
BOOST_LOG_TRIVIAL(info) << "Ejecting started";
tbb::mutex::scoped_lock lock(m_drives_mutex);
auto it_drive_data = this->find_last_save_path_drive_data();
@ -290,7 +294,7 @@ void RemovableDriveManager::eject_drive()
child.wait();
int err = child.exit_code();
if (err) {
BOOST_LOG_TRIVIAL(error) << "Ejecting failed";
BOOST_LOG_TRIVIAL(error) << "Ejecting failed. Exit code: " << err;
assert(m_callback_evt_handler);
if (m_callback_evt_handler)
wxPostEvent(m_callback_evt_handler, RemovableDriveEjectEvent(EVT_REMOVABLE_DRIVE_EJECTED, std::pair<DriveData, bool>(*it_drive_data, false)));

View file

@ -16,9 +16,7 @@
#include <GL/glew.h>
#include <boost/algorithm/string/predicate.hpp>
#if ENABLE_GCODE_VIEWER
#include <boost/log/trivial.hpp>
#endif // ENABLE_GCODE_VIEWER
static const float UNIFORM_SCALE_COLOR[4] = { 0.923f, 0.504f, 0.264f, 1.0f };
@ -113,11 +111,6 @@ Selection::Selection()
, m_valid(false)
, m_scale_factor(1.0f)
{
#if !ENABLE_GCODE_VIEWER
m_arrow.reset(new GLArrow);
m_curved_arrow.reset(new GLCurvedArrow(16));
#endif // !ENABLE_GCODE_VIEWER
this->set_bounding_boxes_dirty();
#if ENABLE_RENDER_SELECTION_CENTER
m_quadric = ::gluNewQuadric();
@ -143,20 +136,8 @@ void Selection::set_volumes(GLVolumePtrs* volumes)
// Init shall be called from the OpenGL render function, so that the OpenGL context is initialized!
bool Selection::init()
{
#if ENABLE_GCODE_VIEWER
m_arrow.init_from(straight_arrow(10.0f, 5.0f, 5.0f, 10.0f, 1.0f));
m_curved_arrow.init_from(circular_arrow(16, 10.0f, 5.0f, 10.0f, 5.0f, 1.0f));
#else
if (!m_arrow->init())
return false;
m_arrow->set_scale(5.0 * Vec3d::Ones());
if (!m_curved_arrow->init())
return false;
m_curved_arrow->set_scale(5.0 * Vec3d::Ones());
#endif //ENABLE_GCODE_VIEWER
return true;
}
@ -1962,7 +1943,6 @@ void Selection::render_bounding_box(const BoundingBoxf3& box, float* color) cons
glsafe(::glEnd());
}
#if ENABLE_GCODE_VIEWER
void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const
{
auto set_color = [](Axis axis) {
@ -1984,25 +1964,7 @@ void Selection::render_sidebar_position_hints(const std::string& sidebar_field)
m_arrow.render();
}
}
#else
void Selection::render_sidebar_position_hints(const std::string& sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x"))
{
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
render_sidebar_position_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
render_sidebar_position_hint(Y);
else if (boost::ends_with(sidebar_field, "z"))
{
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
render_sidebar_position_hint(Z);
}
}
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_GCODE_VIEWER
void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field) const
{
auto set_color = [](Axis axis) {
@ -2030,23 +1992,6 @@ void Selection::render_sidebar_rotation_hints(const std::string& sidebar_field)
render_sidebar_rotation_hint();
}
}
#else
void Selection::render_sidebar_rotation_hints(const std::string & sidebar_field) const
{
if (boost::ends_with(sidebar_field, "x"))
{
glsafe(::glRotated(90.0, 0.0, 1.0, 0.0));
render_sidebar_rotation_hint(X);
}
else if (boost::ends_with(sidebar_field, "y"))
{
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
render_sidebar_rotation_hint(Y);
}
else if (boost::ends_with(sidebar_field, "z"))
render_sidebar_rotation_hint(Z);
}
#endif // ENABLE_GCODE_VIEWER
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) const
{
@ -2058,38 +2003,27 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field) con
shader->set_uniform("uniform_color", uniform_scale ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis], 4);
glsafe(::glTranslated(0.0, 5.0, 0.0));
#if ENABLE_GCODE_VIEWER
m_arrow.render();
#else
m_arrow->render();
#endif // ENABLE_GCODE_VIEWER
glsafe(::glTranslated(0.0, -10.0, 0.0));
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
#if ENABLE_GCODE_VIEWER
m_arrow.render();
#else
m_arrow->render();
#endif // ENABLE_GCODE_VIEWER
};
if (boost::ends_with(sidebar_field, "x") || uniform_scale)
{
if (boost::ends_with(sidebar_field, "x") || uniform_scale) {
glsafe(::glPushMatrix());
glsafe(::glRotated(-90.0, 0.0, 0.0, 1.0));
render_sidebar_scale_hint(X);
glsafe(::glPopMatrix());
}
if (boost::ends_with(sidebar_field, "y") || uniform_scale)
{
if (boost::ends_with(sidebar_field, "y") || uniform_scale) {
glsafe(::glPushMatrix());
render_sidebar_scale_hint(Y);
glsafe(::glPopMatrix());
}
if (boost::ends_with(sidebar_field, "z") || uniform_scale)
{
if (boost::ends_with(sidebar_field, "z") || uniform_scale) {
glsafe(::glPushMatrix());
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
render_sidebar_scale_hint(Z);
@ -2169,35 +2103,6 @@ void Selection::render_sidebar_layers_hints(const std::string& sidebar_field) co
glsafe(::glDisable(GL_BLEND));
}
#if !ENABLE_GCODE_VIEWER
void Selection::render_sidebar_position_hint(Axis axis) const
{
m_arrow->set_color(AXES_COLOR[axis], 3);
m_arrow->render();
}
void Selection::render_sidebar_rotation_hint(Axis axis) const
{
m_curved_arrow->set_color(AXES_COLOR[axis], 3);
m_curved_arrow->render();
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
m_curved_arrow->render();
}
void Selection::render_sidebar_scale_hint(Axis axis) const
{
m_arrow->set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3);
glsafe(::glTranslated(0.0, 5.0, 0.0));
m_arrow->render();
glsafe(::glTranslated(0.0, -10.0, 0.0));
glsafe(::glRotated(180.0, 0.0, 0.0, 1.0));
m_arrow->render();
}
#endif // !ENABLE_GCODE_VIEWER
#ifndef NDEBUG
static bool is_rotation_xy_synchronized(const Vec3d &rot_xyz_from, const Vec3d &rot_xyz_to)
{

View file

@ -3,9 +3,7 @@
#include <set>
#include "libslic3r/Geometry.hpp"
#if ENABLE_GCODE_VIEWER
#include "GLModel.hpp"
#endif // ENABLE_GCODE_VIEWER
#if ENABLE_RENDER_SELECTION_CENTER
class GLUquadric;
@ -221,15 +219,8 @@ private:
GLUquadricObj* m_quadric;
#endif // ENABLE_RENDER_SELECTION_CENTER
#if ENABLE_GCODE_VIEWER
GLModel m_arrow;
GLModel m_curved_arrow;
#else
// Arrows are saved through pointers to avoid including 3DScene.hpp.
// It also allows mutability.
std::unique_ptr<GLArrow> m_arrow;
std::unique_ptr<GLCurvedArrow> m_curved_arrow;
#endif // ENABLE_GCODE_VIEWER
mutable float m_scale_factor;
@ -386,11 +377,6 @@ private:
void render_sidebar_rotation_hints(const std::string& sidebar_field) const;
void render_sidebar_scale_hints(const std::string& sidebar_field) const;
void render_sidebar_layers_hints(const std::string& sidebar_field) const;
#if !ENABLE_GCODE_VIEWER
void render_sidebar_position_hint(Axis axis) const;
void render_sidebar_rotation_hint(Axis axis) const;
void render_sidebar_scale_hint(Axis axis) const;
#endif // !ENABLE_GCODE_VIEWER
public:
enum SyncRotationType {

View file

@ -34,17 +34,9 @@ std::string get_main_info(bool format_as_html)
std::string line_end = format_as_html ? "<br>" : "\n";
if (!format_as_html)
#if ENABLE_GCODE_VIEWER
out << b_start << (wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME) << b_end << line_end;
#else
out << b_start << SLIC3R_APP_NAME << b_end << line_end;
#endif // ENABLE_GCODE_VIEWER
out << b_start << "Version: " << b_end << SLIC3R_VERSION << line_end;
#if ENABLE_GCODE_VIEWER
out << b_start << "Build: " << b_end << (wxGetApp().is_editor() ? SLIC3R_BUILD_ID : GCODEVIEWER_BUILD_ID) << line_end;
#else
out << b_start << "Build: " << b_end << SLIC3R_BUILD_ID << line_end;
#endif // ENABLE_GCODE_VIEWER
out << line_end;
out << b_start << "Operating System: " << b_end << wxPlatformInfo::Get().GetOperatingSystemFamilyName() << line_end;
out << b_start << "System Architecture: " << b_end << wxPlatformInfo::Get().GetArchName() << line_end;
@ -86,11 +78,7 @@ std::string get_mem_info(bool format_as_html)
}
SysInfoDialog::SysInfoDialog()
#if ENABLE_GCODE_VIEWER
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, (wxGetApp().is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME)) + " - " + _L("System Information"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
#else
: DPIDialog((wxWindow*)wxGetApp().mainframe, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _L("System Information"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
#endif // ENABLE_GCODE_VIEWER
{
wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
SetBackgroundColour(bgr_clr);
@ -103,11 +91,7 @@ SysInfoDialog::SysInfoDialog()
main_sizer->Add(hsizer, 1, wxEXPAND | wxALL, 10);
// logo
#if ENABLE_GCODE_VIEWER
m_logo_bmp = ScalableBitmap(this, wxGetApp().is_editor() ? "PrusaSlicer_192px.png" : "PrusaSlicer-gcodeviewer_192px.png", 192);
#else
m_logo_bmp = ScalableBitmap(this, "PrusaSlicer_192px.png", 192);
#endif // ENABLE_GCODE_VIEWER
m_logo = new wxStaticBitmap(this, wxID_ANY, m_logo_bmp.bmp());
hsizer->Add(m_logo, 0, wxALIGN_CENTER_VERTICAL);
@ -116,11 +100,7 @@ SysInfoDialog::SysInfoDialog()
// title
{
#if ENABLE_GCODE_VIEWER
wxStaticText* title = new wxStaticText(this, wxID_ANY, wxGetApp().is_editor() ? SLIC3R_APP_NAME : GCODEVIEWER_APP_NAME, wxDefaultPosition, wxDefaultSize);
#else
wxStaticText* title = new wxStaticText(this, wxID_ANY, SLIC3R_APP_NAME, wxDefaultPosition, wxDefaultSize);
#endif // ENABLE_GCODE_VIEWER
wxFont title_font = wxGetApp().bold_font();
title_font.SetFamily(wxFONTFAMILY_ROMAN);
title_font.SetPointSize(22);

View file

@ -2373,13 +2373,11 @@ PageShp TabPrinter::build_kinematics_page()
if (m_use_silent_mode) {
// Legend for OptionsGroups
auto optgroup = page->new_optgroup("");
optgroup->set_show_modified_btns_val(false);
optgroup->label_width = 23;// 230;
auto line = Line{ "", "" };
ConfigOptionDef def;
def.type = coString;
def.width = 15;
def.width = Field::def_width();
def.gui_type = "legend";
def.mode = comAdvanced;
def.tooltip = L("Values in this column are for Normal mode");
@ -3784,7 +3782,7 @@ void Page::activate(ConfigOptionMode mode, std::function<void()> throw_if_cancel
for (auto group : m_optgroups) {
if (!group->activate(throw_if_canceled))
continue;
m_vsizer->Add(group->sizer, 0, wxEXPAND | wxALL, 10);
m_vsizer->Add(group->sizer, 0, wxEXPAND | (group->is_legend_line() ? (wxLEFT|wxTOP) : wxALL), 10);
group->update_visibility(mode);
group->reload_config();
throw_if_canceled();