diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81b0..0000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/OrcaSlicer.iml b/.idea/OrcaSlicer.iml deleted file mode 100644 index f08604bb65..0000000000 --- a/.idea/OrcaSlicer.iml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index f60388162d..0000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c2b..0000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 79b3c94830..0000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index b80725f1d9..0000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfbb..0000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 991fe0c0fa..c1d7ce992a 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -533,7 +533,7 @@ msgid "Drag" msgstr "Trascina" msgid "Move cut line" -msgstr "" +msgstr "Sposta linea di taglio" msgid "Draw cut line" msgstr "Disegna linea di taglio" @@ -831,7 +831,7 @@ msgid "Embossing actions" msgstr "Azioni di rilievo" msgid "Position on surface" -msgstr "" +msgstr "Posizione sulla superficie" msgid "Emboss" msgstr "Rilievo" @@ -1911,14 +1911,14 @@ msgstr "Aggiornamento dell'informativa sulla riservatezza" #, c-format, boost-format msgid "your Bambu Cloud profile (user ID: \"%s\")" -msgstr "" +msgstr "il tuo profilo Bambu Cloud (ID utente: \"%s\")" msgid "your default profile" -msgstr "" +msgstr "il tuo profilo predefinito" #, c-format, boost-format msgid "a user profile (folder: \"%s\")" -msgstr "" +msgstr "profilo utente (cartella: \"%s\")" #, c-format, boost-format msgid "" @@ -1926,15 +1926,20 @@ msgid "" "Do you want to migrate them to your OrcaCloud profile?\n" "This will copy your presets so they are available under your new account." msgstr "" +"Sono stati trovati dei profili utente in %s.\n" +"Desideri migrarli al tuo profilo OrcaCloud?\n" +"In questo modo verranno copiati e resi disponibili nel tuo nuovo profilo." msgid "Migrate User Presets" -msgstr "" +msgstr "Migra profili utente" #, c-format, boost-format msgid "" "Failed to migrate user presets:\n" "%s" msgstr "" +"Impossibile migrare i profili utente:\n" +"%s" msgid "" "The number of user presets cached in the cloud has exceeded the upper limit, " @@ -1951,29 +1956,33 @@ msgid "" "reduce the preset size by removing custom configurations or use it locally " "only." msgstr "" +"Il contenuto del profilo è troppo grande per essere sincronizzato con il " +"cloud (supera 1 MB). Si prega di ridurre le dimensioni del profilo " +"rimuovendo le configurazioni personalizzate oppure utilizzarlo solo in " +"locale." #, c-format, boost-format msgid "%s updated from %s to %s" -msgstr "" +msgstr "%s aggiornato da %s a %s" #, c-format, boost-format msgid "%s has been downloaded." -msgstr "" +msgstr "%s è stato scaricato." #, c-format, boost-format msgid "Bundle %s is no longer available." -msgstr "" +msgstr "Il pacchetto %s non è più disponibile." #, c-format, boost-format msgid "Bundle %s access is unauthorized." -msgstr "" +msgstr "L'accesso al pacchetto %s non è autorizzato." msgid "Loading user preset" msgstr "Caricamento profili utente" #, c-format, boost-format msgid "%s has been removed." -msgstr "" +msgstr "%s è stato rimosso." msgid "Switching application language" msgstr "Cambio lingua applicazione" @@ -2141,7 +2150,7 @@ msgid "Backspace" msgstr "Backspace" msgid "Load..." -msgstr "Caricamento..." +msgstr "Carica..." msgid "Cube" msgstr "Cubo" @@ -2190,9 +2199,9 @@ msgid "" "No - Do not change these settings for me" msgstr "" "Questo modello presenta una goffratura del testo sulla superficie superiore. " -"Per ottenere risultati ottimali, si consiglia di impostare la 'Soglia di una " -"parete(min_width_top_surface)' su 0 affinché la 'Soglia di una sola parete " -"sulle superfici superiori' funzioni al meglio.\n" +"Per ottenere risultati ottimali, si consiglia di impostare 'Soglia singola " +"parete (min_width_top_surface)' su 0 affinché l'opzione 'Solo una parete su " +"superfici superiori' funzioni al meglio.\n" "Sì - Modificare automaticamente queste impostazioni\n" "No - Non modificare queste impostazioni per me" @@ -2221,7 +2230,7 @@ msgid "Support Enforcer" msgstr "Supporto di rinforzo" msgid "Change part type" -msgstr "" +msgstr "Modifica tipo di parte" msgid "Set as an individual object" msgstr "Imposta come singolo oggetto" @@ -2239,10 +2248,10 @@ msgid "Printable" msgstr "Stampabile" msgid "Auto Drop" -msgstr "" +msgstr "Rilascio automatico" msgid "Automatically drops the selected object to the build plate" -msgstr "" +msgstr "Rilascia automaticamente l'oggetto selezionato sul piano di stampa" msgid "Fix model" msgstr "Correggi il modello" @@ -2427,10 +2436,10 @@ msgid "Select all objects on the current plate" msgstr "Seleziona tutti gli oggetti sul piatto corrente" msgid "Select All Plates" -msgstr "Seleziona tutte le piastre" +msgstr "Seleziona tutti i piatti" msgid "Select all objects on all plates" -msgstr "Seleziona tutti gli oggetti su tutte le piastre" +msgstr "Seleziona tutti gli oggetti su tutti i piatti" msgid "Delete All" msgstr "Elimina tutto" @@ -2493,7 +2502,7 @@ msgid "Simplify Model" msgstr "Semplifica Modello" msgid "Subdivision mesh" -msgstr "Suddivisione mesh" +msgstr "Suddivisione maglia" msgid "(Lost color)" msgstr "(Colore perso)" @@ -2505,7 +2514,7 @@ msgid "Drop" msgstr "Lascia" msgid "Edit Process Settings" -msgstr "Modifica le impostazioni del processo" +msgstr "Modifica impostazioni di processo" msgid "Copy Process Settings" msgstr "Copia impostazioni di processo" @@ -2523,7 +2532,7 @@ msgid "Set Filament for selected items" msgstr "Imposta filamento per gli elementi selezionati" msgid "Automatically snaps the selected object to the build plate" -msgstr "" +msgstr "Aggancia automaticamente l'oggetto selezionato sul piano di stampa" msgid "Unlock" msgstr "Sblocca" @@ -2821,7 +2830,7 @@ msgid "Brim" msgstr "Tesa" msgid "Object/Part Settings" -msgstr "" +msgstr "Impostazioni oggetto/parte" msgid "Reset parameter" msgstr "Ripristina parametro" @@ -3535,6 +3544,14 @@ msgid "" "enhancements. Each project carried the work of its predecessors forward, " "crediting those who came before." msgstr "" +"I programmi di sezionamento a sorgente aperta per l'elaborazione del modelli " +"per la stampa 3D, si fondano su una tradizione di collaborazione e " +"riconoscimento del merito. Slic3r, creato da Alessandro Ranellucci e dalla " +"comunità RepRap, ha gettato le basi. PrusaSlicer di Prusa Research ha " +"sviluppato ulteriormente questo lavoro; Bambu Studio è derivato da " +"PrusaSlicer e SuperSlicer lo ha ampliato con miglioramenti apportati dalla " +"comunità. Ogni progetto ha portato avanti il ​​lavoro dei suoi predecessori, " +"riconoscendo il contributo di chi li ha preceduti." msgid "" "OrcaSlicer began in that same spirit, drawing from PrusaSlicer, BambuStudio, " @@ -3542,12 +3559,20 @@ msgid "" "introducing advanced calibration tools, precise wall and seam control and " "hundreds of other features." msgstr "" +"OrcaSlicer è nato con lo stesso spirito, traendo ispirazione da PrusaSlicer, " +"BambuStudio, SuperSlicer e CuraSlicer. Ma da allora si è evoluto ben oltre " +"le sue origini, introducendo strumenti di calibrazione avanzati, controllo " +"preciso su pareti e cuciture e centinaia di altre funzionalità." msgid "" "Today, OrcaSlicer is the most widely used and actively developed open-source " "slicer in the 3D printing community. Many of its innovations have been " "adopted by other slicers, making it a driving force for the entire industry." msgstr "" +"Oggi, OrcaSlicer è il programma di sezionamento a sorgente aperta più " +"utilizzato e attivamente sviluppato nella comunità della stampa 3D. Molte " +"delle sue innovazioni sono state adottate da altri programmi di stampa, " +"rendendolo un punto di riferimento per l'intero settore." msgid "Version" msgstr "Versione" @@ -4501,7 +4526,7 @@ msgid "Inspecting first layer" msgstr "Ispezione del primo strato" msgid "Identifying build plate type" -msgstr "Identificazione tipo piatto di stampa" +msgstr "Identificazione tipo piano di stampa" msgid "Calibrating Micro Lidar" msgstr "Calibrazione Micro Lidar" @@ -4970,7 +4995,7 @@ msgid "Acceleration" msgstr "Accelerazione" msgid "Jerk" -msgstr "" +msgstr "Scatto" msgid "Fan Speed" msgstr "Velocità ventola" @@ -5120,10 +5145,10 @@ msgid "Color: " msgstr "Colore: " msgid "Acceleration: " -msgstr "" +msgstr "Accelerazione: " msgid "Jerk: " -msgstr "" +msgstr "Scatto: " msgid "PA: " msgstr "PA: " @@ -5156,8 +5181,9 @@ msgid "" "Automatically re-slice according to the optimal filament grouping, and the " "grouping results will be displayed after slicing." msgstr "" -"Ri-slicing automatico secondo il raggruppamento filamenti ottimale; i " -"risultati del raggruppamento verranno visualizzati dopo lo slicing." +"Rielabora automaticamente in base al raggruppamento ottimale dei filamenti; " +"i risultati del raggruppamento verranno visualizzati al termine " +"dell'elaborazione." msgid "Filament Grouping" msgstr "Raggruppamento filamenti" @@ -5258,10 +5284,10 @@ msgid "Actual Speed (mm/s)" msgstr "Velocità effettiva (mm/s)" msgid "Acceleration (mm/s²)" -msgstr "" +msgstr "Accelerazione (mm/s²)" msgid "Jerk (mm/s)" -msgstr "" +msgstr "Scatto (mm/s)" msgid "Fan Speed (%)" msgstr "Velocità ventola (%)" @@ -5294,7 +5320,7 @@ msgid "Filament change times" msgstr "Tempi cambio filamento" msgid "Tool changes" -msgstr "" +msgstr "Cambi testina" msgid "Color change" msgstr "Cambio colore" @@ -5387,10 +5413,10 @@ msgid "Sequence" msgstr "Sequenza" msgid "Object Selection" -msgstr "" +msgstr "Selezione oggetto" msgid "Part Selection" -msgstr "" +msgstr "Selezione parte" msgid "number keys" msgstr "tasti numerici" @@ -5582,7 +5608,7 @@ msgid "Paint Toolbar" msgstr "Barra strumenti di pittura" msgid "part selection" -msgstr "" +msgstr "selezione parte" msgid "Explosion Ratio" msgstr "Rapporto di esplosione" @@ -6136,7 +6162,7 @@ msgid "View" msgstr "Vista" msgid "Preset Bundle" -msgstr "" +msgstr "Pacchetto profili" msgid "Help" msgstr "Aiuto" @@ -6178,7 +6204,7 @@ msgid "VFA" msgstr "VFA" msgid "Calibration Guide" -msgstr "" +msgstr "Guida alla calibrazione" msgid "&Open G-code" msgstr "Apri G-code" @@ -6293,6 +6319,11 @@ msgid "" "2. The Filament presets\n" "3. The Printer presets" msgstr "" +"Desideri sincronizzare i tuoi dati personali da Orca Cloud?\n" +"Contiene le seguenti informazioni:\n" +"1. Profili di processo\n" +"2. Profili di filamento\n" +"3. Profili della stampante" msgid "Synchronization" msgstr "Sincronizzazione" @@ -6314,6 +6345,8 @@ msgid "" "The player is not loaded because the GStreamer GTK video sink is missing or " "failed to initialize." msgstr "" +"Il lettore non è stato caricato perché il ricevitore video GTK di GStreamer " +"è mancante o non è stato inizializzato correttamente." msgid "Please confirm if the printer is connected." msgstr "Verifica che la stampante sia collegata." @@ -7216,10 +7249,10 @@ msgid "Model file downloaded." msgstr "File del modello scaricato." msgid "Shared profiles may be available for this printer." -msgstr "" +msgstr "Per questa stampante potrebbero essere disponibili profili condivisi." msgid "Browse shared profiles" -msgstr "" +msgstr "Esplora i profili condivisi" msgid "Serious warning:" msgstr "Avviso serio:" @@ -7433,7 +7466,7 @@ msgid "Objects" msgstr "Oggetti" msgid "Cycle settings visibility" -msgstr "" +msgstr "Visibilità impostazioni" msgid "Compare presets" msgstr "Confronta i profili" @@ -7718,28 +7751,30 @@ msgid "Load 3MF" msgstr "Carica 3MF" msgid "BambuStudio Project" -msgstr "" +msgstr "Progetto BambuStudio" -#, fuzzy msgid "The 3MF is not supported by OrcaSlicer, loading geometry data only." msgstr "" "Il formato 3MF non è supportato da OrcaSlicer. Saranno caricati solo i dati " "geometrici." -#, fuzzy msgid "" "The 3MF file was generated by an old OrcaSlicer version, loading geometry " "data only." msgstr "" -"Il 3MF è stato generato da una vecchia versione di OrcaSlicer, caricando " -"solo i dati geometrici." +"Il file 3MF è stato generato da una vecchia versione di OrcaSlicer. Saranno " +"caricati solo i dati geometrici." msgid "" "The 3MF file was generated by an older version, loading geometry data only." msgstr "" +"Il file 3MF è stato generato da una versione precedente. Saranno caricati " +"solo i dati geometrici." msgid "The 3MF file was generated by BambuStudio, loading geometry data only." msgstr "" +"Il file 3MF è stato generato da BambuStudio. Saranno caricati solo i dati " +"geometrici." msgid "" "This project was created with an OrcaSlicer 2.3.1-alpha and uses infill " @@ -7782,12 +7817,18 @@ msgid "" "The 3MF was created by BambuStudio (version %s), which is newer than the " "compatible version %s. Found unrecognized settings:" msgstr "" +"Il file 3MF è stato creato da BambuStudio (versione %s), che è più recente " +"della versione compatibile %s. Sono state trovate impostazioni non " +"riconosciute:" #, c-format, boost-format msgid "" "The 3MF was created by BambuStudio (version %s), which is newer than the " "compatible version %s. Some settings may not be fully compatible." msgstr "" +"Il file 3MF è stato creato da BambuStudio (versione %s), che è più recente " +"della versione compatibile %s. Alcune impostazioni potrebbero non essere " +"pienamente compatibili." msgid "" "The 3MF was created by BambuStudio. Some settings may differ from OrcaSlicer." @@ -7804,7 +7845,7 @@ msgstr "Si prega di correggerli nella scheda dei parametri" msgid "" "The 3MF has the following modified G-code in filament or printer presets:" msgstr "" -"Il 3MF ha i seguenti G-code modificati nei profili del filamento o della " +"Il 3MF ha i seguenti G-code modificati nei profili di filamento o della " "stampante:" msgid "" @@ -7883,7 +7924,7 @@ msgid "Object with multiple parts was detected" msgstr "È stato rilevato un oggetto con più parti" msgid "Auto-Drop" -msgstr "" +msgstr "Rilascio automatico" #, c-format, boost-format msgid "" @@ -7958,9 +7999,11 @@ msgstr "L'oggetto selezionato non può essere diviso." msgid "Disable Auto-Drop to preserve z positioning?\n" msgstr "" +"Disabilitare la funzione di Rilascio automatico per preservare il " +"posizionamento sull'asse Z?\n" msgid "Object with floating parts was detected" -msgstr "" +msgstr "È stato rilevato un oggetto con parti fluttuanti" msgid "Another export job is running." msgstr "È in esecuzione un altro processo di esportazione." @@ -8380,7 +8423,7 @@ msgid "Triangles: %1%\n" msgstr "Triangoli: %1%\n" msgid "Use \"Fix Model\" to repair the mesh." -msgstr "" +msgstr "Utilizza \"Correggi modello\" per riparare la maglia poligonale." #, c-format, boost-format msgid "" @@ -8554,15 +8597,17 @@ msgid "Show the splash screen during startup." msgstr "Mostra la schermata iniziale durante l'avvio." msgid "Show shared profiles notification" -msgstr "" +msgstr "Mostra notifica profili condivisi" msgid "" "Show a notification with a link to browse shared profiles when the selected " "printer is changed." msgstr "" +"Quando si cambia la stampante selezionata, viene visualizzata una notifica " +"con un collegamento per esplorare i profili condivisi." msgid "Use window buttons on left side" -msgstr "" +msgstr "Utilizza i pulsanti della finestra sul lato sinistro" msgid "(Requires restart)" msgstr "(Richiede riavvio)" @@ -8638,10 +8683,10 @@ msgstr "" "del filamento/processo per ciascuna stampante." msgid "Group user filament presets" -msgstr "Raggruppa profili filamento utente" +msgstr "Raggruppa profili di filamento utente" msgid "Group user filament presets based on selection" -msgstr "Raggruppa profili filamento utente in base alla selezione" +msgstr "Raggruppa i profili di filamento utente in base alla selezione" msgid "All" msgstr "Tutto" @@ -8716,7 +8761,7 @@ msgid "Auto arrange plate after cloning" msgstr "Disposizione automatica del piatto dopo la clonazione" msgid "Auto slice after changes" -msgstr "Slicing automatico dopo le modifiche" +msgstr "Elaborazione automatica dopo le modifiche" msgid "" "If enabled, OrcaSlicer will re-slice automatically whenever slicing-related " @@ -8835,6 +8880,10 @@ msgid "" "the transmission of data to Bambu's cloud services too. Users who don't use " "BBL machines or use LAN mode only can safely turn on this function." msgstr "" +"Questa opzione disabilita tutti i servizi cloud, ad esempio Orca Cloud e " +"Bambu Cloud. Interrompe anche la trasmissione dei dati ai servizi cloud di " +"Bambu. Gli utenti che non utilizzano macchine BBL o che utilizzano solo la " +"modalità LAN, possono attivare questa opzione in tutta sicurezza." msgid "Network test" msgstr "Test di rete" @@ -8843,15 +8892,18 @@ msgid "Test" msgstr "Prova" msgid "Cloud Providers" -msgstr "" +msgstr "Fornitori di servizi cloud" msgid "Enable Bambu Cloud" -msgstr "" +msgstr "Abilita Bambu Cloud" msgid "" "Allow logging into Bambu Cloud alongside Orca Cloud. When enabled, a Bambu " "login section appears on the homepage." msgstr "" +"Consente l'accesso sia a Bambu Cloud che a Orca Cloud. Quando questa opzione " +"è abilitata, nella pagina iniziale viene visualizzata una sezione per " +"l'accesso a Bambu." msgid "Update & sync" msgstr "Aggiorna e sincronizza" @@ -9133,7 +9185,7 @@ msgid "Project-inside presets" msgstr "Profilo interno al progetto" msgid "Bundle presets" -msgstr "" +msgstr "Pacchetto profili" msgid "System" msgstr "Sistema" @@ -9738,6 +9790,9 @@ msgid "" "type in the slicing file. Please make sure you have installed the correct " "filament in the external spool." msgstr "" +"Il tipo di filamento esterno è sconosciuto o non corrisponde al tipo di " +"filamento specificato nel file di sezionamento. Assicurati di aver " +"installato il filamento corretto nella bobina esterna." msgid "Please refer to Wiki before use->" msgstr "Fare riferimento alla Wiki prima dell'uso ->" @@ -10129,8 +10184,8 @@ msgstr "" msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" -"by right-click the empty position of build plate and choose \"Add Primitive" -"\"->\"Timelapse Wipe Tower\"." +"by right-click the empty position of build plate and choose \"Add " +"Primitive\"->\"Timelapse Wipe Tower\"." msgstr "" "Quando si registra un timelapse senza la testina di stampa, si consiglia di " "aggiungere un \"Timelapse Torre di spurgo\"\n" @@ -10500,7 +10555,7 @@ msgid "Cooling Fan" msgstr "Velocità minima ventola di raffreddamento" msgid "Fan speed-up time" -msgstr "Tempo di accelerazione della ventola" +msgstr "Tempo accelerazione ventola" msgid "Extruder Clearance" msgstr "Spazio libero estrusore" @@ -10554,10 +10609,10 @@ msgid "Normal" msgstr "Normale" msgid "Resonance Compensation" -msgstr "" +msgstr "Compensazione risonanza" msgid "Resonance Avoidance Speed" -msgstr "Velocità evita risonanza" +msgstr "Velocità prevenzione risonanza" msgid "Frequency" msgstr "Frequenza" @@ -10566,12 +10621,15 @@ msgid "" "The frequency of the anti-vibration signal will correspond to the natural " "frequency of the frame." msgstr "" +"La frequenza del segnale antivibrazione corrisponderà alla frequenza " +"naturale del telaio." msgid "Damping" -msgstr "" +msgstr "Smorzamento" msgid "Damping ratio for the input shaping filter." msgstr "" +"Rapporto di smorzamento per il filtro della compensazione della risonanza." msgid "Speed limitation" msgstr "Limitazione velocità" @@ -10696,29 +10754,42 @@ msgid "" " %s first layer %d %s, other layers %d %s\n" " %s max delta %d %s, current delta %d %s\n" msgstr "" +" - %s:\n" +" %s primo strato %d %s, altri strati %d %s\n" +" %s delta massimo %d %s, delta attuale %d %s\n" msgid "" "Some first-layer and other-layer temperature pairs exceed safety limits.\n" msgstr "" +"Alcune coppie di temperature del primo strato e di altri strati superano i " +"limiti di sicurezza.\n" msgid "" "\n" "Invalid pairs:\n" msgstr "" +"\n" +"Coppie non valide:\n" msgid "" "\n" "You can go back to edit values, or continue if this is intentional." msgstr "" +"\n" +"È possibile tornare indietro per modificare i valori, oppure continuare se " +"questa scelta è intenzionale." msgid "" "\n" "\n" "Continue anyway?" msgstr "" +"\n" +"\n" +"Continuare comunque?" msgid "Temperature Safety Check" -msgstr "" +msgstr "Controllo di sicurezza della temperatura" msgid "Continue" msgstr "Continua" @@ -10727,7 +10798,7 @@ msgid "Back" msgstr "Posteriore" msgid "Don't warn again for this preset" -msgstr "" +msgstr "Non inviare più avvisi per questo profilo" #, c-format, boost-format msgid "Left: %s" @@ -11046,7 +11117,7 @@ msgid "" "presets.\n" "Are you sure you want to continue?" msgstr "" -"La sincronizzazione dei filamenti AMS scarterà i profili filamento " +"La sincronizzazione dei filamenti AMS scarterà i profili di filamento " "modificati ma non salvati.\n" "Sei sicuro di voler continuare?" @@ -11148,7 +11219,7 @@ msgid "" "replaced with the mapped filament types and colors. This action cannot be " "undone." msgstr "" -"Dopo la sincronizzazione, i profili filamento e i colori del progetto " +"Dopo la sincronizzazione, i profili di filamento e i colori del progetto " "saranno sostituiti con i tipi e i colori dei filamenti mappati. Questa " "azione non può essere annullata." @@ -11241,15 +11312,15 @@ msgid "" "This is an expert-level setting, incorrect adjustment will likely lead to " "jams, extruder wheel grinding into filament etc." msgstr "" -"Per modellazione del filamento (o Ramming) si intende l'operazione di " -"estrusione effettuata appena prima di un cambio di filamento in una " -"stampante MM con estrusore singolo. Il suo scopo è quello di dare una forma " -"corretta all'estremità del filamento scaricato, in modo che non impedisca " -"l'inserimento del nuovo filamento e possa essere reinserito successivamente. " -"Questa fase è importante e i diversi materiali possono richiedere velocità " -"di estrusione diverse per ottenere una buona forma. Per questo motivo, le " -"velocità di estrusione nella fase di modellazione del filamento sono " -"regolabili.\n" +"Per Spinta del filamento (o Ramming) si intende l'operazione di estrusione " +"effettuata appena prima di un cambio di filamento in una stampante " +"multimateriale con estrusore singolo. Il suo scopo è quello di dare una " +"forma corretta all'estremità del filamento scaricato, in modo che non " +"impedisca l'inserimento del nuovo filamento e possa essere reinserito " +"successivamente. Questa fase è importante e i diversi materiali possono " +"richiedere velocità di estrusione diverse per ottenere una buona forma. Per " +"questo motivo, le velocità di estrusione nella fase di modellazione del " +"filamento sono regolabili.\n" "\n" "Si tratta di un'impostazione per esperti: una regolazione errata potrebbe " "causare inceppamenti, la macinazione del filamento da parte dell'ingranaggio " @@ -11314,11 +11385,16 @@ msgid "" "Native Wayland liveview requires the GStreamer GTK video sink. Please " "install the gtksink plugin for GStreamer, then restart OrcaSlicer." msgstr "" +"La funzione di visualizzazione in tempo reale nativa di Wayland richiede il " +"ricevitore video GTK di GStreamer. Installare il modulo gtksink per " +"GStreamer e riavviare OrcaSlicer." msgid "" "Failed to initialize the native Wayland GStreamer video sink. Please check " "your GStreamer GTK plugin installation." msgstr "" +"Impossibile inizializzare il ricevitore video nativo di Wayland GStreamer. " +"Verificare l'installazione del modulo GTK di GStreamer." msgid "" "Windows Media Player is required for this task! Do you want to enable " @@ -11361,6 +11437,8 @@ msgstr "" msgid "Cloud agent is not available. Please restart OrcaSlicer and try again." msgstr "" +"Il fornitore di servizi cloud non è disponibile. Riavviare OrcaSlicer e " +"riprovare." msgid "Bambu Network plug-in not detected." msgstr "Modulo di rete Bambu non rilevato." @@ -11541,7 +11619,7 @@ msgid "Zoom out" msgstr "Rimpicciolisci" msgid "Toggle printable for object/part" -msgstr "" +msgstr "Attiva/disattiva stampa per oggetto/parte" msgid "Switch between Prepare/Preview" msgstr "Passa tra Prepara e Anteprima" @@ -11635,7 +11713,7 @@ msgid "New version of Orca Slicer" msgstr "Nuova versione di OrcaSlicer" msgid "Check on Github" -msgstr "" +msgstr "Visualizza su GitHub" msgid "Skip this Version" msgstr "Salta questa versione" @@ -11787,8 +11865,8 @@ msgid "" msgstr "" "È stato rilevato un aggiornamento importante che deve essere eseguito prima " "che la stampa possa continuare. Si desidera aggiornare ora? È possibile " -"effettuare l'aggiornamento anche in un secondo momento da \"Aggiorna firmware" -"\"." +"effettuare l'aggiornamento anche in un secondo momento da \"Aggiorna " +"firmware\"." msgid "" "The firmware version is abnormal. Repairing and updating are required before " @@ -11805,13 +11883,13 @@ msgstr "Scheda di estensione" #, boost-format msgid "Split into %1% parts" -msgstr "" +msgstr "Dividere in %1% parti" msgid "Repair finished" msgstr "Riparazione completata" msgid "Repair failed" -msgstr "" +msgstr "Riparazione fallita" msgid "Repair canceled" msgstr "Riparazione annullata" @@ -11858,10 +11936,10 @@ msgstr "" "l'oggetto potrebbe avere una maglia poligonale difettosa" msgid "Process change extrusion role G-code" -msgstr "" +msgstr "G-code cambio ruolo estrusione processo" msgid "Filament change extrusion role G-code" -msgstr "" +msgstr "G-code cambio ruolo estrusione filamento" msgid "No object can be printed. Maybe too small" msgstr "Non è possibile stampare alcun oggetto. Potrebbe essere troppo piccolo" @@ -11895,15 +11973,19 @@ msgstr "" "La matrice dei volumi di spurgo non corrisponde alla dimensione corretta!" msgid "set_accel_and_jerk() is only supported by Klipper" -msgstr "" +msgstr "set_accel_and_jerk() è supportato solo da Klipper" msgid "" "Input shaping is not supported by Marlin < 2.1.2.\n" "Check your firmware version and update your G-code flavor to ´Marlin 2´" msgstr "" +"La compensazione della risonanza non è supportata da Marlin < 2.1.2.\n" +"Verifica la versione del firmware e aggiorna il G-code a ´Marlin 2´" msgid "Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2" msgstr "" +"La compensazione della risonanza è supportata solo da Klipper, " +"RepRapFirmware e Marlin 2" msgid "Grouping error: " msgstr "Errore di raggruppamento: " @@ -12071,16 +12153,24 @@ msgid "" "temperature must fall within the recommended nozzle temperature range of the " "other filaments. Otherwise, nozzle clogging or printer damage may occur." msgstr "" +"Le temperature degli ugelli selezionate sono incompatibili. La temperatura " +"dell'ugello per ciascun filamento deve rientrare nell'intervallo di " +"temperatura consigliato per gli altri filamenti. In caso contrario, " +"potrebbero verificarsi ostruzioni degli ugelli o danni alla stampante." msgid "" "Invalid recommended nozzle temperature range. The lower bound must be lower " "than the upper bound." msgstr "" +"Intervallo di temperatura dell'ugello consigliato non valido. Il limite " +"inferiore deve essere minore del limite superiore." msgid "" "If you still want to print, you can enable the option in Preferences / " "Control / Slicing / Remove mixed temperature restriction." msgstr "" +"Se desideri comunque stampare, puoi abilitare l'opzione in Preferenze / " +"Controllo / Elaborazione / Rimuovi restrizione temperature miste." msgid "No extrusions under current settings." msgstr "Nessuna estrusione con le impostazioni attuali." @@ -12321,7 +12411,7 @@ msgid "" "each layer to prevent loss of floating point accuracy. Add \"G92 E0\" to " "layer_gcode." msgstr "" -"L'indirizzamento relativo dell'estrusore richiede la reimpostazione della " +"L'indirizzamento relativo dell'estrusore richiede il ripristino della " "posizione dell'estrusore ad ogni strato per evitare la perdita di precisione " "in virgola mobile. Aggiungi \"G92 E0\" a layer_gcode." @@ -12475,7 +12565,7 @@ msgstr "" "compensare l'effetto zampa d'elefante." msgid "Elephant foot compensation layers" -msgstr "Strato di compensazione zampa d'elefante" +msgstr "Strati compensazione zampa d'elefante" msgid "" "The number of layers on which the elephant foot compensation will be active. " @@ -12483,13 +12573,13 @@ msgid "" "the next layers will be linearly shrunk less, up to the layer indicated by " "this value." msgstr "" -"Il numero di strati su cui sarà attiva la compensazione della zampa " -"d'elefante. Il primo strato verrà ridotto in base al valore della " -"compensazione della zampa d'elefante, mentre gli strati successivi saranno " -"ridotti in modo lineare, fino allo strato indicato da questo parametro." +"Numero di strati su cui sarà attiva la compensazione della zampa d'elefante. " +"Il primo strato verrà ridotto in base al valore della compensazione della " +"zampa d'elefante, mentre gli strati successivi saranno ridotti in modo " +"lineare, fino allo strato indicato da questo parametro." msgid "Elephant foot layers density" -msgstr "" +msgstr "Densità strati zampa d'elefante" msgid "" "Density of internal solid infill for Elephant foot layers compensation.\n" @@ -12497,6 +12587,11 @@ msgid "" "Subsequent layers become linearly denser by the height specified in " "elefant_foot_compensation_layers." msgstr "" +"Densità del riempimento solido interno per gli strati di compensazione " +"dell'effetto zampa d'elefante.\n" +"Il valore iniziale è impostato per il secondo strato.\n" +"Gli strati successivi aumentano di densità in modo lineare in base " +"all'altezza specificata in elefant_foot_compensation_layers." msgid "" "Slicing height for each layer. Smaller layer height means more accurate and " @@ -13043,7 +13138,7 @@ msgstr "" "Diminuisci leggermente questo valore (ad esempio 0,9) per ridurre la " "quantità di filamento estruso per i ponti e tendere il materiale.\n" "\n" -"Il flusso effettivo utilizzato nei ponti viene calcolato moltiplicando " +"Il flusso di stampa effettivo per i ponti viene calcolato moltiplicando " "questo valore con il flusso di stampa del filamento e, se impostato, con il " "flusso di stampa dell'oggetto." @@ -13062,9 +13157,10 @@ msgstr "" "Questo valore regola lo spessore dello strato dei ponti interni. È il primo " "strato sopra il riempimento sparso. Ridurre leggermente questo valore (ad " "esempio 0,9) per migliorare la qualità della superficie sopra i riempimenti " -"radi.\n" -"Il flusso effettivo utilizzato nei ponti interni viene calcolato " -"moltiplicando questo valore con il flusso di stampa dei ponti, flusso di " +"sparsi.\n" +"\n" +"Il flusso di stampa effettivo utilizzato per i ponti interni viene calcolato " +"moltiplicando questo valore con il flusso di stampa dei ponti, il flusso di " "stampa del filamento e, se impostato, con il flusso di stampa dell'oggetto." msgid "Top surface flow ratio" @@ -13077,13 +13173,13 @@ msgid "" "The actual top surface flow used is calculated by multiplying this value " "with the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo valore influenza la quantità di materiale utilizzata per il " +"Questo fattore influenza la quantità di materiale utilizzata per il " "riempimento solido della superficie superiore. Puoi diminuirlo leggermente " "per avere una finitura liscia sulla superficie.\n" "\n" -"Il flusso di stampa effettivo utilizzato nelle superfici superiori viene " -"calcolato moltiplicando questo valore con il flusso di stampa del filamento " -"e, se impostato, con il flusso di stampa dell'oggetto." +"Il flusso di stampa effettivo per le superfici superiori viene calcolato " +"moltiplicando questo valore con il flusso di stampa del filamento e, se " +"impostato, con il flusso di stampa dell'oggetto." msgid "Bottom surface flow ratio" msgstr "Flusso di stampa superficie inferiore" @@ -13094,12 +13190,12 @@ msgid "" "The actual bottom solid infill flow used is calculated by multiplying this " "value with the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo valore influenza la quantità di materiale utilizzata per il " +"Questo fattore influenza la quantità di materiale utilizzata per il " "riempimento solido della superficie inferiore.\n" "\n" -"Il flusso di stampa effettivo utilizzato nelle superfici inferiori viene " -"calcolato moltiplicando questo valore con il flusso di stampa del filamento " -"e, se impostato, con il flusso di stampa dell'oggetto." +"Il flusso di stampa effettivo per le superfici inferiori viene calcolato " +"moltiplicando questo valore con il flusso di stampa del filamento e, se " +"impostato, con il flusso di stampa dell'oggetto." msgid "Set other flow ratios" msgstr "Imposta altri rapporti di flusso" @@ -13109,7 +13205,7 @@ msgstr "" "Modifica i rapporti di flusso per altri tipi di percorso di estrusione." msgid "First layer flow ratio" -msgstr "Rapporto di flusso primo strato" +msgstr "Flusso di stampa primo strato" msgid "" "This factor affects the amount of material on the first layer for the " @@ -13118,14 +13214,15 @@ msgid "" "For the first layer, the actual flow ratio for each path role (does not " "affect brims and skirts) will be multiplied by this value." msgstr "" -"Questo fattore influisce sulla quantità di materiale sul primo strato per i " -"ruoli del percorso di estrusione elencati in questa sezione.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata sul primo " +"strato per i ruoli del percorso di estrusione elencati in questa sezione.\n" "\n" -"Per il primo strato, il rapporto di flusso effettivo per ogni ruolo del " -"percorso (non influisce su tese e gonne) sarà moltiplicato per questo valore." +"Per il primo strato, il flusso di stampa effettivo per ogni ruolo del " +"percorso di estrusione (non influisce su tese e gonne) sarà moltiplicato per " +"questo valore." msgid "Outer wall flow ratio" -msgstr "Rapporto di flusso parete esterna" +msgstr "Flusso di stampa pareti esterne" msgid "" "This factor affects the amount of material for outer walls.\n" @@ -13133,14 +13230,15 @@ msgid "" "The actual outer wall flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per le pareti esterne.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per le " +"pareti esterne.\n" "\n" -"Il flusso effettivo della parete esterna viene calcolato moltiplicando " -"questo valore per il rapporto di flusso del filamento e, se impostato, per " -"il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per le pareti esterne viene calcolato " +"moltiplicando questo valore per il flusso di stampa del filamento e, se " +"impostato, per il flusso di stampa dell'oggetto." msgid "Inner wall flow ratio" -msgstr "Rapporto di flusso parete interna" +msgstr "Flusso di stampa pareti interne" msgid "" "This factor affects the amount of material for inner walls.\n" @@ -13148,14 +13246,15 @@ msgid "" "The actual inner wall flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per le pareti interne.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per le " +"pareti interne.\n" "\n" -"Il flusso effettivo della parete interna viene calcolato moltiplicando " -"questo valore per il rapporto di flusso del filamento e, se impostato, per " -"il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per le pareti interne viene calcolato " +"moltiplicando questo valore per il flusso di stampa del filamento e, se " +"impostato, per il flusso di stampa dell'oggetto." msgid "Overhang flow ratio" -msgstr "Rapporto di flusso per sbalzi" +msgstr "Flusso di stampa sporgenze" msgid "" "This factor affects the amount of material for overhangs.\n" @@ -13163,14 +13262,15 @@ msgid "" "The actual overhang flow used is calculated by multiplying this value by the " "filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per gli sbalzi.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per le " +"sporgenze.\n" "\n" -"Il flusso effettivo degli sbalzi viene calcolato moltiplicando questo valore " -"per il rapporto di flusso del filamento e, se impostato, per il rapporto di " -"flusso dell'oggetto." +"Il flusso di stampa effettivo per le sporgenze viene calcolato moltiplicando " +"questo valore per il flusso di stampa del filamento e, se impostato, per il " +"flusso di stampa dell'oggetto." msgid "Sparse infill flow ratio" -msgstr "Rapporto di flusso riempimento sparso" +msgstr "Flusso di stampa riempimento sparso" msgid "" "This factor affects the amount of material for sparse infill.\n" @@ -13178,15 +13278,15 @@ msgid "" "The actual sparse infill flow used is calculated by multiplying this value " "by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per il riempimento " -"sparso.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per il " +"riempimento sparso.\n" "\n" -"Il flusso effettivo del riempimento sparso viene calcolato moltiplicando " -"questo valore per il rapporto di flusso del filamento e, se impostato, per " -"il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per il riempimento sparso viene calcolato " +"moltiplicando questo valore per il flusso di stampa del filamento e, se " +"impostato, per il flusso di stampa dell'oggetto." msgid "Internal solid infill flow ratio" -msgstr "Rapporto di flusso riempimento solido interno" +msgstr "Flusso di stampa riempimento solido interno" msgid "" "This factor affects the amount of material for internal solid infill.\n" @@ -13194,15 +13294,15 @@ msgid "" "The actual internal solid infill flow used is calculated by multiplying this " "value by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per il riempimento " -"solido interno.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per il " +"riempimento solido interno.\n" "\n" -"Il flusso effettivo del riempimento solido interno viene calcolato " -"moltiplicando questo valore per il rapporto di flusso del filamento e, se " -"impostato, per il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per il riempimento solido interno viene " +"calcolato moltiplicando questo valore per il flusso di stampa del filamento " +"e, se impostato, per il flusso di stampa dell'oggetto." msgid "Gap fill flow ratio" -msgstr "Rapporto di flusso riempimento spazi" +msgstr "Flusso di stampa riempimento spazi" msgid "" "This factor affects the amount of material for filling the gaps.\n" @@ -13210,15 +13310,15 @@ msgid "" "The actual gap filling flow used is calculated by multiplying this value by " "the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per il riempimento " -"degli spazi.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per il " +"riempimento degli spazi vuoti.\n" "\n" -"Il flusso effettivo del riempimento spazi viene calcolato moltiplicando " -"questo valore per il rapporto di flusso del filamento e, se impostato, per " -"il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per il riempimento degli spazi vuoti viene " +"calcolato moltiplicando questo valore per il flusso di stampa del filamento " +"e, se impostato, per il flusso di stampa dell'oggetto." msgid "Support flow ratio" -msgstr "Rapporto di flusso supporto" +msgstr "Flusso di stampa supporti" msgid "" "This factor affects the amount of material for support.\n" @@ -13226,14 +13326,15 @@ msgid "" "The actual support flow used is calculated by multiplying this value by the " "filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per il supporto.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per i " +"supporti.\n" "\n" -"Il flusso effettivo del supporto viene calcolato moltiplicando questo valore " -"per il rapporto di flusso del filamento e, se impostato, per il rapporto di " -"flusso dell'oggetto." +"Il flusso di stampa effettivo per i supporti viene calcolato moltiplicando " +"questo valore per il flusso di stampa del filamento e, se impostato, per il " +"flusso di stampa dell'oggetto." msgid "Support interface flow ratio" -msgstr "Rapporto di flusso interfaccia supporto" +msgstr "Flusso di stampa interfaccie supporti" msgid "" "This factor affects the amount of material for the support interface.\n" @@ -13241,12 +13342,12 @@ msgid "" "The actual support interface flow used is calculated by multiplying this " "value by the filament flow ratio, and if set, the object's flow ratio." msgstr "" -"Questo fattore influisce sulla quantità di materiale per l'interfaccia di " -"supporto.\n" +"Questo fattore influisce sulla quantità di materiale utilizzata per le " +"interfacce dei supporti.\n" "\n" -"Il flusso effettivo dell'interfaccia di supporto viene calcolato " -"moltiplicando questo valore per il rapporto di flusso del filamento e, se " -"impostato, per il rapporto di flusso dell'oggetto." +"Il flusso di stampa effettivo per le interfacce dei supporti viene calcolato " +"moltiplicando questo valore per il flusso di stampa del filamento e, se " +"impostato, per il flusso di stampa dell'oggetto." msgid "Precise wall" msgstr "Parete precisa" @@ -13391,7 +13492,7 @@ msgid "Sacrificial layer" msgstr "Strato sacrificale" msgid "Reverse threshold" -msgstr "Soglia inversa" +msgstr "Soglia di inversione" msgid "Overhang reversal threshold" msgstr "Soglia di inversione sporgenze" @@ -13518,7 +13619,7 @@ msgstr "" "più facile la rimozione della tesa." msgid "Brim flow ratio" -msgstr "" +msgstr "Flusso di stampa tese" msgid "" "This factor affects the amount of material for brims.\n" @@ -13528,9 +13629,17 @@ msgid "" "\n" "Note: The resulting value will not be affected by the first-layer flow ratio." msgstr "" +"Questo valore influisce sulla quantità di materiale utilizzata per le tese.\n" +"\n" +"Il flusso di stampa effettivo per le tese viene calcolato moltiplicando " +"questo valore per il flusso di stampa del filamento e, se impostato, per il " +"flusso di stampa dell'oggetto.\n" +"\n" +"Nota: il valore risultante non sarà influenzato dal flusso di stampa del " +"primo strato." msgid "Brim follows compensated outline" -msgstr "Tesa segue il contorno compensato" +msgstr "Tesa su contorno con compensazione" msgid "" "When enabled, the brim is aligned with the first-layer perimeter geometry " @@ -13541,21 +13650,24 @@ msgid "" "If your current setup already works well, enabling it may be unnecessary and " "can cause the brim to fuse with upper layers." msgstr "" -"Quando abilitato, tesa è allineato con la geometria perimetrale del primo " -"strato dopo l'applicazione della compensazione del piede di elefante.\n" -"Questa opzione è prevista per i casi in cui è prevista la compensazione del " -"piede di elefante altera significativamente l'impronta del primo strato.\n" +"Se abilitata, la tesa viene allineata con il perimetro del primo strato dopo " +"l'applicazione della Compensazione della zampa d'elefante.\n" +"Questa opzione è pensata per i casi in cui la compensazione della zampa di " +"elefante altera significativamente le dimensioni del primo strato.\n" "\n" -"Se la tua configurazione attuale funziona già bene, abilitarla potrebbe non " -"essere necessaria e può causare la fusione del tesa con gli strati superiori." +"Se la tua configurazione attuale funziona in modo ottimale, non è necessario " +"abilitare questa opzione, in quanto potrebbe causare la fusione della tesa " +"con gli strati superiori." msgid "Combine brims" -msgstr "" +msgstr "Unisci tese" msgid "" "Combine multiple brims into one when they are close to each other. This can " "improve brim adhesion." msgstr "" +"Unisce più tese in una quando sono vicine tra loro. Questo può migliorare " +"l'adesione delle tese." msgid "Brim ears" msgstr "Tesa ad orecchio" @@ -13688,14 +13800,18 @@ msgstr "" msgid "" "Enable this to override the fan speed set in custom G-code during print." msgstr "" +"Abilita questa opzione per sovrascrivere la velocità della ventola impostata " +"nel G-code personalizzato durante la stampa." msgid "On completion" -msgstr "" +msgstr "Al completamento" msgid "" "Enable this to override the fan speed set in custom G-code after print " "completion." msgstr "" +"Abilita questa opzione per sovrascrivere la velocità della ventola impostata " +"nel G-code personalizzato una volta terminata la stampa." msgid "" "Speed of exhaust fan during printing. This speed will override the speed in " @@ -14130,6 +14246,13 @@ msgid "" "\n" "This option will be disabled if spiral vase mode is enabled." msgstr "" +"Direzione in cui vengono estrusi i perimetri di stampa, guardando dall'alto " +"verso il basso.\n" +"I fori vengono stampati nella direzione opposta ai perimetri, per mantenere " +"l'allineamento con gli strati i cui contorni sono incompleti e cambiano " +"direzione, formando parzialmente contorni di fori.\n" +"\n" +"Questa opzione verrà disabilitata se la modalità vaso a spirale è attiva." msgid "Counter clockwise" msgstr "Senso antiorario" @@ -14777,9 +14900,9 @@ msgid "" "this movement should be before the filament is retracted again." msgstr "" "Se impostato su un valore diverso da zero, il filamento viene spostato verso " -"l'ugello tra i singoli movimenti nei tubi di raffreddamento (\"timbratura" -"\"). Questa opzione configura la durata di questo movimento prima che il " -"filamento venga nuovamente retratto." +"l'ugello tra i singoli movimenti nei tubi di raffreddamento " +"(\"timbratura\"). Questa opzione configura la durata di questo movimento " +"prima che il filamento venga nuovamente retratto." msgid "Speed of the first cooling move" msgstr "Velocità del primo movimento di raffreddamento" @@ -14807,10 +14930,11 @@ msgstr "" "oggetti sacrificali o riempimenti." msgid "Wipe tower cooling" -msgstr "" +msgstr "Raffreddamento torre di spurgo" msgid "Temperature drop before entering filament tower" msgstr "" +"Calo di temperatura prima dell'ingresso nella torre di spurgo del filamento" msgid "Interface layer pre-extrusion distance" msgstr "Distanza di pre-estrusione dello strato di interfaccia" @@ -14880,7 +15004,7 @@ msgid "" "This string is edited by RammingDialog and contains ramming specific " "parameters." msgstr "" -"Questa stringa è stata modifcata da RammingDialog e contiene parametri " +"Questa stringa è stata modificata da RammingDialog e contiene parametri " "specifici per l'operazione di modellazione della punta del filamento." msgid "Enable ramming for multi-tool setups" @@ -15264,12 +15388,14 @@ msgstr "" "inferiore, è possibile migliorare l'adesione sul piano di stampa." msgid "First layer travel" -msgstr "" +msgstr "Spostamento primo strato" msgid "" "Travel acceleration of first layer.\n" "The percentage value is relative to Travel Acceleration." msgstr "" +"Accelerazione dello spostamento nel primo strato.\n" +"Il valore percentuale è relativo all'accelerazione dello spostamento." msgid "Enable accel_to_decel" msgstr "Abilita accel_to_decel" @@ -15323,6 +15449,8 @@ msgid "" "Travel jerk of first layer.\n" "The percentage value is relative to Travel Jerk." msgstr "" +"Scatto dello spostamento nel primo strato.\n" +"Il valore percentuale è relativo allo scatto dello spostamento." msgid "" "Line width of the first layer. If expressed as a %, it will be computed over " @@ -15379,21 +15507,21 @@ msgstr "" "Temperatura dell'ugello per la stampa del primo strato con questo filamento." msgid "Full fan speed at layer" -msgstr "Velocità massima della ventola su strato" +msgstr "Velocità massima ventola su strato" msgid "" "Fan speed will be ramped up linearly from zero at layer " -"\"close_fan_the_first_x_layers\" to maximum at layer \"full_fan_speed_layer" -"\". \"full_fan_speed_layer\" will be ignored if lower than " -"\"close_fan_the_first_x_layers\", in which case the fan will be running at " -"maximum allowed speed at layer \"close_fan_the_first_x_layers\" + 1." +"\"close_fan_the_first_x_layers\" to maximum at layer " +"\"full_fan_speed_layer\". \"full_fan_speed_layer\" will be ignored if lower " +"than \"close_fan_the_first_x_layers\", in which case the fan will be running " +"at maximum allowed speed at layer \"close_fan_the_first_x_layers\" + 1." msgstr "" "La velocità della ventola aumenterà in modo lineare da zero nello strato " "\"close_fan_the_first_x_layers\" al massimo nello strato " "\"full_fan_speed_layer\". Se inferiore a \"close_fan_the_first_x_layers\", " "\"full_fan_speed_layer\" verrà ignorato. in tal caso la ventola funzionerà " -"alla massima velocità consentita nello strato \"close_fan_the_first_x_layers" -"\" + 1." +"alla massima velocità consentita nello strato " +"\"close_fan_the_first_x_layers\" + 1." msgid "layer" msgstr "strato" @@ -15617,6 +15745,17 @@ msgid "" "Ripple: Uniform ripple pattern that ripples left and right of the original " "path. Repeating pattern, woven appearance." msgstr "" +"Tipo di rumore da utilizzare per la generazione della superficie ruvida:\n" +"Classico: rumore casuale uniforme classico.\n" +"Perlin: rumore Perlin, che conferisce una trama più uniforme.\n" +"Ondulato: Simile al rumore Perlin, ma più granuloso.\n" +"Multifrattale ruvido: rumore con superfici nette e frastagliate. Crea trame " +"simili al marmo.\n" +"Voronoi: divide la superficie in tassellazioni di Voronoi e ne sposta " +"ciascuna di una quantità casuale. Crea una trama a mosaico.\n" +"Increspature: Motivo con onde uniformi che si propagano a sinistra e a " +"destra del percorso originale. Motivo ripetuto, aspetto in stile tessuto " +"intrecciato." msgid "Classic" msgstr "Classico" @@ -15628,13 +15767,13 @@ msgid "Billow" msgstr "Ondulato" msgid "Ridged Multifractal" -msgstr "Multifrattale increspato" +msgstr "Multifrattale ruvido" msgid "Voronoi" msgstr "Voronoi" msgid "Ripple" -msgstr "" +msgstr "Increspature" msgid "Fuzzy skin feature size" msgstr "Dimensione struttura superficie ruvida" @@ -15667,13 +15806,15 @@ msgstr "" "daranno luogo a un rumore più uniforme." msgid "Number of ripples per layer" -msgstr "" +msgstr "Numero increspature per strato" msgid "Controls how many full cycles of ripples will be added per layer." msgstr "" +"Controlla quanti cicli completi di increspature verranno aggiunti per ogni " +"strato." msgid "Ripple offset" -msgstr "" +msgstr "Deviazione increspature" msgid "" "Shifts the ripple phase forward along the print path by the specified " @@ -15687,9 +15828,20 @@ msgid "" "The shift is applied once every number of layers set by Layers between " "ripple offset, so layers within the same group are printed identically." msgstr "" +"Sposta in avanti la fase dell'increspatura, lungo il percorso di stampa, " +"della percentuale specificata di lunghezza d'onda.\n" +"- 0% mantieni ogni strato identico.\n" +"- 50% sposta il motivo di mezza lunghezza d'onda, invertendo di fatto la " +"fase.\n" +"- 100% sposta il motivo di un'intera lunghezza d'onda, tornando alla fase " +"originale.\n" +"\n" +"Lo spostamento viene applicato una volta ogni numero di strati impostato " +"nell'opzione \"Strati deviazione increspature\", in modo che gli strati " +"all'interno dello stesso gruppo vengano stampati in modo identico." msgid "Layers between ripple offset" -msgstr "" +msgstr "Strati deviazione increspature" msgid "" "Specifies how many consecutive layers share the same ripple phase before the " @@ -15702,6 +15854,15 @@ msgid "" "to 6 are shifted by the configured offset, then layers 7 to 9 return to the " "base pattern, etc." msgstr "" +"Specifica quanti strati consecutivi condividono la stessa fase di " +"increspatura prima che venga applicata la deviazione.\n" +"Per esempio:\n" +"- 1 = lo strato 1 viene stampato con il motivo di increspatura di base, lo " +"strato 2 viene spostato in base alla deviazione configurata, lo strato 3 " +"ritorna al motivo di base e così via.\n" +"- 3 = Gli strati da 1 a 3 vengono stampati con il motivo di increspatura di " +"base, gli strati da 4 a 6 vengono spostati in base alla deviazione " +"configurata, gli strati da 7 a 9 ritornano al motivo di base e così via." msgid "Filter out tiny gaps" msgstr "Filtra piccoli spazi vuoti" @@ -15895,7 +16056,7 @@ msgid "Will only take into account the delay for the cooling of overhangs." msgstr "Terrà conto solo del ritardo per il raffreddamento delle sporgenze." msgid "Fan kick-start time" -msgstr "Tempo di avvio della ventola" +msgstr "Tempo avvio ventola" msgid "" "Emit a max fan speed command for this amount of seconds before reducing to " @@ -16370,7 +16531,7 @@ msgid "Print speed of ironing lines." msgstr "Indica la velocità di stampa per le linee di stiratura." msgid "Ironing angle offset" -msgstr "Offset angolo di stiratura" +msgstr "Angolo di stiratura" msgid "The angle of ironing lines offset from the top surface." msgstr "L'angolo delle linee di stiratura rispetto alla superficie superiore." @@ -16382,42 +16543,53 @@ msgid "Use a fixed absolute angle for ironing." msgstr "Usa un angolo assoluto fisso per la stiratura." msgid "Ironing expansion" -msgstr "" +msgstr "Espansione stiratura" msgid "Expand or contract the ironing area." -msgstr "" +msgstr "Espande o riduce l'area di stiratura." msgid "Z contouring enabled" -msgstr "" +msgstr "Contornatura Z abilitata" msgid "Enable Z-layer contouring (aka Z-layer anti-aliasing)." msgstr "" +"Abilita la contornatura degli strati sull'asse Z (noto anche come anti-" +"aliasing dell'asse Z)." msgid "Minimize wall height angle" -msgstr "" +msgstr "Riduci altezza su pareti inclinate" msgid "" "Reduce the height of top-surface perimeters to match the model edge height.\n" "Affects perimeters with a slope less than this angle (degrees).\n" "A reasonable value is 35. Set to 0 to disable." msgstr "" +"Riduce l'altezza dei perimetri della superficie superiore in modo che si " +"adattino meglio al bordo del modello\n" +"Influisce sui perimetri con una pendenza inferiore a questo angolo (in " +"gradi).\n" +"Il valore consigliato è 35. Impostare a 0 per disabilitare questa funzione." msgid "°" msgstr "°" msgid "Don't alternate fill direction" -msgstr "" +msgstr "Non alternare direzione riempimento" msgid "Disable alternating fill direction when using Z contouring." msgstr "" +"Disabilita il riempimento a direzione alternata quando si utilizza l'opzione " +"\"Contornatura Z\"." msgid "Minimum z height" -msgstr "" +msgstr "Altezza Z minima" msgid "" "Minimum Z-layer height.\n" "Also controls the slicing plane." msgstr "" +"Altezza minima dello strato sull'asse Z.\n" +"Controlla anche il piano per l'elaborazione." msgid "This G-code is inserted at every layer change after the Z lift." msgstr "" @@ -16599,16 +16771,17 @@ msgstr "" "Marlin 2." msgid "Resonance avoidance" -msgstr "Evitamento della risonanza" +msgstr "Prevenzione risonanza" msgid "" "By reducing the speed of the outer wall to avoid the resonance zone of the " "printer, ringing on the surface of the model are avoided.\n" "Please turn this option off when testing ringing." msgstr "" -"Riducendo la velocità della parete esterna per evitare la zona di risonanza " -"della stampante, si evitano le ondulazioni sulla superficie del modello.\n" -"Disattivare questa opzione quando si testa il ringing." +"Riducendo la velocità nelle pareti esterne per evitare la zona di risonanza " +"della stampante, si evitano le ondulazioni o ronzii (ringing) sulla " +"superficie del modello.\n" +"Disattivare questa opzione quando si testa il ronzio ." msgid "Min" msgstr "Minimo" @@ -16623,12 +16796,14 @@ msgid "Maximum speed of resonance avoidance." msgstr "Velocità massima per l'evitamento della risonanza." msgid "Emit input shaping" -msgstr "" +msgstr "Sovrascrivi compensazione risonanza" msgid "" "Override firmware input shaping settings.\n" "If disabled, firmware settings are used." msgstr "" +"Sovrascrivi le impostazioni di compensazione della risonanza del firmware.\n" +"Se disabilitato, verranno utilizzate le impostazioni del firmware." msgid "Input shaper type" msgstr "Tipo di compensazione della risonanza" @@ -16638,42 +16813,44 @@ msgid "" "Default uses the firmware default settings.\n" "Disable turns off input shaping in the firmware." msgstr "" +"Seleziona l'algoritmo di compensazione della risonanza.\n" +"L'opzione \"Default\" utilizza le impostazioni predefinite del firmware." msgid "MZV" -msgstr "" +msgstr "MZV" msgid "ZV" -msgstr "" +msgstr "ZV" msgid "ZVD" -msgstr "" +msgstr "ZVD" msgid "ZVDD" -msgstr "" +msgstr "ZVDD" msgid "ZVDDD" -msgstr "" +msgstr "ZVDDD" msgid "EI" -msgstr "" +msgstr "EI" msgid "EI2" -msgstr "" +msgstr "EI2" msgid "2HUMP_EI" -msgstr "" +msgstr "2HUMP_EI" msgid "EI3" -msgstr "" +msgstr "EI3" msgid "3HUMP_EI" -msgstr "" +msgstr "3HUMP_EI" msgid "DAA" -msgstr "" +msgstr "DAA" msgid "X" -msgstr "" +msgstr "X" msgid "" "Resonant frequency for the X axis input shaper.\n" @@ -16681,15 +16858,26 @@ msgid "" "To disable input shaping, use the Disable type.\n" "RRF: X and Y values are equal." msgstr "" +"Frequenza di risonanza per la compensazione sull'asse X.\n" +"Se impostato a zero, verranno utilizzate le impostazioni di frequenza del " +"firmware.\n" +"Per disabilitare la compensazione della risonanza, selezionare il tipo " +"\"Disabilita\".\n" +"RRF: i valori X e Y sono uguali." msgid "Y" -msgstr "" +msgstr "Y" msgid "" "Resonant frequency for the Y axis input shaper.\n" "Zero will use the firmware frequency.\n" "To disable input shaping, use the Disable type." msgstr "" +"Frequenza di risonanza per la compensazione sull'asse Y.\n" +"Se impostato a zero, verranno utilizzate le impostazioni di frequenza del " +"firmware.\n" +"Per disabilitare la compensazione della risonanza, selezionare il tipo " +"\"Disabilita\"." msgid "" "Damping ratio for the X axis input shaper.\n" @@ -16697,12 +16885,23 @@ msgid "" "To disable input shaping, use the Disable type.\n" "RRF: X and Y values are equal." msgstr "" +"Rapporto di smorzamento per la compensazione della risonanza sull'asse X.\n" +"Se impostato a zero, verranno utilizzate le impostazioni di rapporto di " +"smorzamento del firmware.\n" +"Per disabilitare la compensazione della risonanza, selezionare il tipo " +"\"Disabilita\".\n" +"RRF: i valori X e Y sono uguali." msgid "" "Damping ratio for the Y axis input shaper.\n" "Zero will use the firmware damping ratio.\n" "To disable input shaping, use the Disable type." msgstr "" +"Rapporto di smorzamento per la compensazione della risonanza sull'asse Y.\n" +"Se impostato a zero, verranno utilizzate le impostazioni di rapporto di " +"smorzamento del firmware.\n" +"Per disabilitare la compensazione della risonanza, selezionare il tipo " +"\"Disabilita\"." msgid "" "Part cooling fan speed may be increased when auto cooling is enabled. This " @@ -16840,10 +17039,12 @@ msgstr "" "utilizzare questa funzione. Comando G-code: M106 P2 S(0-255)" msgid "For the first" -msgstr "" +msgstr "Per il primo" msgid "Set special auxiliary cooling fan for the first certain layers." msgstr "" +"Imposta la ventola di raffreddamento ausiliaria per i primi strati " +"specificati." msgid "" "Auxiliary fan speed will be ramped up linearly from layer \"For the first\" " @@ -16852,10 +17053,18 @@ msgid "" "in which case the fan will run at maximum allowed speed at layer \"For the " "first\" + 1." msgstr "" +"La velocità della ventola ausiliaria aumenterà linearmente da \"Per il " +"primo\" fino al valore massimo impostato su \"Velocità massima ventola su " +"strato\".\n" +"Il valore \"Velocità massima ventola su strato\" verrà ignorato se inferiore " +"a \"Per il primo\"; in tal caso, la ventola funzionerà alla velocità massima " +"consentita con il valore \"Per il primo\" + 1." msgid "" "Special auxiliary cooling fan speed, effective only for the first x layers." msgstr "" +"Velocità della ventola di raffreddamento ausiliaria, operativa solo per i " +"primi x strati." msgid "" "The lowest printable layer height for the extruder. Used to limit the " @@ -17094,12 +17303,15 @@ msgstr "" "OrcaSlicer leggendo le variabili di ambiente." msgid "Change extrusion role G-code (process)" -msgstr "" +msgstr "Modifica G-code ruolo di estrusione (processo)" msgid "" "This G-code is inserted when the extrusion role is changed. It runs after " "the machine and filament extrusion role G-code." msgstr "" +"Questo G-code viene inserito quando si effettua il cambio del ruolo di " +"estrusione. Viene eseguito dopo il G-code della macchina e del ruolo di " +"estrusione del filamento." msgid "Printer type" msgstr "Tipo stampante" @@ -17452,9 +17664,10 @@ msgid "" "Apply scarf joints only to smooth perimeters where traditional seams do not " "conceal the seams at sharp corners effectively." msgstr "" -"Applica le cuciture a sciarpa solo sui perimetri lisci, dove le cuciture " -"tradizionali non riescono a nascondere efficacemente quelle in " -"corrispondenza degli angoli vivi." +"Applica le cuciture a sciarpa solo sui perimetri lisci e curvi, dove le " +"cuciture tradizionali risulterebbero molto evidenti. Gli angoli netti " +"continueranno a utilizzare le cuciture normali per mantenere la precisione " +"dimensionale." msgid "Conditional angle threshold" msgstr "Soglia angolo condizionale" @@ -17522,45 +17735,48 @@ msgstr "" "cucitura a sciarpa." msgid "Scarf start height" -msgstr "Altezza iniziale sciarpa" +msgstr "Altezza iniziale cucitura a sciarpa" msgid "" "Start height of the scarf.\n" "This amount can be specified in millimeters or as a percentage of the " "current layer height. The default value for this parameter is 0." msgstr "" -"Altezza iniziale della sciarpa.\n" -"Questa quantità può essere specificata in millimetri o come percentuale " +"Altezza iniziale della cucitura a sciarpa.\n" +"Questo valore può essere specificato in millimetri o come percentuale " "dell'altezza dello strato corrente. Il valore predefinito per questo " "parametro è 0." msgid "Scarf around entire wall" -msgstr "Sciarpa attorno all'intera parete" +msgstr "Cucitura a sciarpa su intera parete" msgid "The scarf extends to the entire length of the wall." -msgstr "La sciarpa si estende per tutta la lunghezza della parete." +msgstr "" +"La cucitura a sciarpa si estende lungo tutto il perimetro della parete." msgid "Scarf length" -msgstr "Lunghezza sciarpa" +msgstr "Lunghezza cucitura a sciarpa" msgid "" "Length of the scarf. Setting this parameter to zero effectively disables the " "scarf." msgstr "" -"Lunghezza della sciarpa. Impostando questo parametro su zero, la sciarpa " -"viene effettivamente disabilitata." +"Lunghezza della cucitura a sciarpa. Impostando questo parametro su zero, la " +"cucitura a sciarpa viene disabilitata." msgid "Scarf steps" -msgstr "Incrementi sciarpa" +msgstr "Incrementi cucitura a sciarpa" msgid "Minimum number of segments of each scarf." -msgstr "Numero minimo di segmenti di ogni sciarpa." +msgstr "" +"Numero minimo di segmenti utilizzati per la creazione della sfumatura della " +"cucitura a sciarpa." msgid "Scarf joint for inner walls" msgstr "Cucitura a sciarpa per pareti interne" msgid "Use scarf joint for inner walls as well." -msgstr "Utilizzare la cucitura a sciarpa anche per le pareti interne." +msgstr "Utilizza la cucitura a sciarpa anche per le pareti interne." msgid "Role base wipe speed" msgstr "Velocità di spurgo basata su ruolo" @@ -17944,7 +18160,7 @@ msgstr "" "l'azione di cambio filamento manuale." msgid "Wipe tower type" -msgstr "Tipo di torre di pulizia" +msgstr "Tipo di torre di spurgo" msgid "" "Choose the wipe tower implementation for multi-material prints. Type 1 is " @@ -18107,10 +18323,11 @@ msgstr "" "sbalzi, ecc." msgid "Ignore small overhangs" -msgstr "Ignora sbalzi piccoli" +msgstr "Ignora piccole sporgenze" msgid "Ignore small overhangs that possibly don't require support." -msgstr "Ignora i piccoli sbalzi che potrebbero non richiedere supporto." +msgstr "" +"Ignora le piccole sporgenze che potrebbero non necessitare dei supporti." msgid "Top Z distance" msgstr "Distanza Z superiore" @@ -18330,15 +18547,18 @@ msgid "Threshold angle" msgstr "Angolo di soglia" msgid "" -"Support will be generated for overhangs whose slope angle is below the threshold. " -"The smaller this value is, the steeper the overhang that can be printed without support.\n" -"Note: If set to 0, normal supports use the Threshold overlap instead, " -"while tree supports fall back to a default value of 30." +"Support will be generated for overhangs whose slope angle is below the " +"threshold. The smaller this value is, the steeper the overhang that can be " +"printed without support.\n" +"Note: If set to 0, normal supports use the Threshold overlap instead, while " +"tree supports fall back to a default value of 30." msgstr "" -"I supporti verranno generati per gli sbalzi il cui angolo di inclinazione è inferiore alla soglia." -"Più piccolo è questo valore, più ripido sarà lo sbalzo che può essere stampato senza supporto.\n" -"Nota: se impostato su 0, i supporti normali useranno invece Soglia sovrapposizione, " -"mentre i supporti ad albero torneranno al valore predefinito di 30." +"I supporti verranno generati per le sporgenze il cui angolo di inclinazione " +"è inferiore a questa soglia. Più piccolo è questo valore, più ripide saranno " +"le sporgenze stampabili senza supporti.\n" +"Nota: se impostato a 0, i supporti normali useranno il valore specificato in " +"\"Soglia sovrapposizione\", mentre i supporti ad albero torneranno al valore " +"predefinito di 30." msgid "Threshold overlap" msgstr "Soglia sovrapposizione" @@ -18350,8 +18570,8 @@ msgid "" msgstr "" "Se l'angolo di soglia è zero, i supporti verranno generati per le sporgenze " "la cui sovrapposizione è al di sotto della soglia. Quanto più piccolo è " -"questo valore, tanto più ripida sarà la sporgenza che può essere stampata " -"senza supporto." +"questo valore, tanto più ripide saranno le sporgenze stampabili senza " +"supporti." msgid "Tree support branch angle" msgstr "Angolo rami supporti ad albero" @@ -18509,8 +18729,8 @@ msgstr "Attiva controllo della temperatura" msgid "" "Enable this option for automated chamber temperature control. This option " -"activates the emitting of an M191 command before the \"machine_start_gcode" -"\"\n" +"activates the emitting of an M191 command before the " +"\"machine_start_gcode\"\n" " which sets the chamber temperature and waits until it is reached. In " "addition, it emits an M141 command at the end of the print to turn off the " "chamber heater, if present.\n" @@ -18598,12 +18818,14 @@ msgstr "" "Questo gcode viene inserito quando viene modificato il ruolo di estrusione." msgid "Change extrusion role G-code (filament)" -msgstr "" +msgstr "Modifica G-code ruolo di estrusione (filamento)" msgid "" "This G-code is inserted when the extrusion role is changed for the active " "filament." msgstr "" +"Questo G-code viene inserito quando si effettua il cambio del ruolo di " +"estrusione per il filamento attivo." msgid "" "Line width for top surfaces. If expressed as a %, it will be computed over " @@ -19217,15 +19439,18 @@ msgstr "" "singola." msgid "Maximum wall resolution" -msgstr "" +msgstr "Risoluzione massima parete" msgid "" "This value determines the smallest wall line segment length in mm. The " "smaller you set this value, the more accurate and precise the walls will be." msgstr "" +"Questo valore determina la lunghezza minima del segmento di linea della " +"parete, in mm. Più piccolo è il valore impostato, più accurate e precise " +"saranno le pareti." msgid "Maximum wall deviation" -msgstr "" +msgstr "Deviazione massima parete" msgid "" "The maximum deviation allowed when reducing the resolution for the 'Maximum " @@ -19234,6 +19459,11 @@ msgid "" "'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' " "takes precedence." msgstr "" +"Deviazione massima consentita quando si riduce la risoluzione tramite " +"l'impostazione \"Risoluzione massima parete\". Se si aumenta questo valore, " +"la stampa sarà meno precisa, ma il G-Code sarà più contenuto. \"Deviazione " +"massima parete\" limita \"Risoluzione massima parete\", quindi in caso di " +"conflitto tra i due valori, \"Deviazione massima parete\" ha la precedenza." msgid "First layer minimum wall width" msgstr "Larghezza minima parete del primo strato" @@ -20023,7 +20253,7 @@ msgid "Generating infill toolpath" msgstr "Generazione percorso testina per riempimento" msgid "Z contouring" -msgstr "" +msgstr "Contornatura Z" msgid "Detect overhangs for auto-lift" msgstr "Rilevamento sporgenze per il sollevamento automatico" @@ -20660,6 +20890,11 @@ msgid "" "temperature range of the other filaments. Otherwise, nozzle clogging or " "printer damage may occur." msgstr "" +"Le temperature degli ugelli selezionate sono incompatibili. Per la stampa " +"multimateriale, la temperatura dell'ugello per ciascun filamento deve " +"rientrare nell'intervallo di temperatura consigliato per gli altri " +"filamenti. In caso contrario, potrebbero verificarsi ostruzioni degli ugelli " +"o danni alla stampante." msgid "Sync AMS and nozzle information" msgstr "Sincronizza informazioni AMS e ugello" @@ -21090,25 +21325,25 @@ msgid "NOTE: High values may cause Layer shift (>%s)" msgstr "NOTA: valori elevati possono causare spostamento degli strati (>%s)" msgid "Flow Ratio Calibration" -msgstr "" +msgstr "Calibrazione flusso di stampa" msgid "Calibration Test Type" -msgstr "" +msgstr "Tipo test calibrazione" msgid "Pass 1 (Coarse)" -msgstr "" +msgstr "Passaggio 1 (Impreciso)" msgid "Pass 2 (Fine)" -msgstr "" +msgstr "Passaggio 2 (Fine)" msgid "YOLO (Recommended)" msgstr "YOLO (Consigliato)" msgid "YOLO (Perfectionist)" -msgstr "" +msgstr "YOLO (Perfezionista)" msgid "Top Surface Pattern" -msgstr "" +msgstr "Motivo superficie superiore" msgid "Send G-code to printer host" msgstr "Invia G-code all'host di stampa" @@ -21378,12 +21613,12 @@ msgstr "" "Vuoi riscriverlo?" msgid "" -"We would rename the presets as \"Vendor Type Serial @printer you selected" -"\".\n" +"We would rename the presets as \"Vendor Type Serial @printer you " +"selected\".\n" "To add preset for more printers, please go to printer selection" msgstr "" -"Rinomineremo i profili come \"Produttore Tipo Seriale @stampante selezionata" -"\".\n" +"Rinomineremo i profili come \"Produttore Tipo Seriale @stampante " +"selezionata\".\n" "Per aggiungere il profilo per più stampanti, vai alla selezione della " "stampante" @@ -21505,7 +21740,7 @@ msgstr "" "Il nome del profilo della stampante che hai creato esiste già. Vuoi " "sovrascriverlo?\n" "\tSì: Sovrascrivi il profilo della stampante con lo stesso nome, e i profili " -"del filamento e del processo con lo stesso nome saranno ricreati,\n" +"di filamento e di processo con lo stesso nome saranno ricreati,\n" "mentre gli altri saranno conservati.\n" "\tAnnulla: Non creare un profilo, torna alla pagina di creazione." @@ -21626,7 +21861,7 @@ msgid "Printer presets(.zip)" msgstr "Profili stampante (.zip)" msgid "Filament presets(.zip)" -msgstr "Profili filamento (.zip)" +msgstr "Profili di filamento (.zip)" msgid "Process presets(.zip)" msgstr "Profili di processo (.zip)" @@ -22738,7 +22973,7 @@ msgid "Global settings" msgstr "Impostazioni globali" msgid "Video tutorial" -msgstr "" +msgstr "Video tutorial" msgid "(Sync with printer)" msgstr "(Sincronizza con stampante)" @@ -23017,7 +23252,7 @@ msgid "" "Generic filament presets will be used." msgstr "" "Il filamento potrebbe non essere compatibile con le impostazioni correnti " -"della macchina. Verranno utilizzati i profili filamento generici." +"della macchina. Verranno utilizzati i profili di filamento generici." msgid "" "The filament model is unknown. Still using the previous filament preset." @@ -23027,7 +23262,7 @@ msgstr "" msgid "The filament model is unknown. Generic filament presets will be used." msgstr "" -"Il modello di filamento è sconosciuto. Verranno utilizzati i profili " +"Il modello di filamento è sconosciuto. Verranno utilizzati i profili di " "filamento generici." msgid "" @@ -25417,12 +25652,13 @@ msgstr "" #~ "nostro wiki.\n" #~ "\n" #~ "Di solito la calibrazione non è necessaria. Quando si avvia una stampa a " -#~ "singolo colore/materiale, con l'opzione \"calibrazione dinamica del flusso" -#~ "\" selezionata nel menu di avvio della stampa, la stampante seguirà il " -#~ "vecchio modo, calibrando il filamento prima della stampa; Quando si avvia " -#~ "una stampa multicolore/materiale, la stampante utilizzerà il parametro di " -#~ "compensazione predefinito per il filamento durante ogni cambio di " -#~ "filamento, che avrà un buon risultato nella maggior parte dei casi.\n" +#~ "singolo colore/materiale, con l'opzione \"calibrazione dinamica del " +#~ "flusso\" selezionata nel menu di avvio della stampa, la stampante seguirà " +#~ "il vecchio modo, calibrando il filamento prima della stampa; Quando si " +#~ "avvia una stampa multicolore/materiale, la stampante utilizzerà il " +#~ "parametro di compensazione predefinito per il filamento durante ogni " +#~ "cambio di filamento, che avrà un buon risultato nella maggior parte dei " +#~ "casi.\n" #~ "\n" #~ "Si prega di notare che ci sono alcuni casi che renderanno il risultato " #~ "della calibrazione non affidabile: utilizzo di una piastra di texture per " diff --git a/resources/data/hints.ini b/resources/data/hints.ini index 7839e5fd45..3ecf029298 100644 --- a/resources/data/hints.ini +++ b/resources/data/hints.ini @@ -94,8 +94,8 @@ text = Switch workspaces\nYou can switch between Prepare and PreviewReverse on odd feature can significantly improve the surface quality of your overhangs? +[hint:Reverse on even] +text = Reverse on even\nDid you know that Reverse on even feature can significantly improve the surface quality of your overhangs? However, it can cause wall inconsistencies so use carefully! [hint:Cut Tool] text = Cut Tool\nDid you know that you can cut a model at any angle and position with the cutting tool? diff --git a/resources/images/filter.svg b/resources/images/filter.svg new file mode 100644 index 0000000000..c48942073b --- /dev/null +++ b/resources/images/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/profiles/Afinia/filament/fdm_filament_common.json b/resources/profiles/Afinia/filament/fdm_filament_common.json index dd89148ec9..94ed0997ee 100644 --- a/resources/profiles/Afinia/filament/fdm_filament_common.json +++ b/resources/profiles/Afinia/filament/fdm_filament_common.json @@ -61,7 +61,7 @@ "nil" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Anet A8 Plus(A8+)_cover.png b/resources/profiles/Anet A8 Plus(A8+)_cover.png deleted file mode 100644 index 4eb1ee93b2..0000000000 Binary files a/resources/profiles/Anet A8 Plus(A8+)_cover.png and /dev/null differ diff --git a/resources/profiles/Anet/Anet A8 Plus(A8+)_cover.png b/resources/profiles/Anet/Anet A8 Plus(A8+)_cover.png deleted file mode 100644 index 4eb1ee93b2..0000000000 Binary files a/resources/profiles/Anet/Anet A8 Plus(A8+)_cover.png and /dev/null differ diff --git a/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.json b/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.json deleted file mode 100644 index 50c3866955..0000000000 --- a/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.json +++ /dev/null @@ -1,237 +0,0 @@ -{ - "type": "machine", - "name": "Anet A8 Plus 0.4 nozzle", - "inherits": "", - "from": "User", - "adaptive_bed_mesh_margin": "0", - "auxiliary_fan": "0", - "bbl_use_printhost": "0", - "bed_custom_model": "", - "bed_custom_texture": "", - "bed_exclude_area": [ - "0x0" - ], - "bed_mesh_max": "99999,99999", - "bed_mesh_min": "-99999,-99999", - "bed_mesh_probe_distance": "50,50", - "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n", - "best_object_pos": "0.5,0.5", - "change_extrusion_role_gcode": "", - "change_filament_gcode": "M600", - "cooling_tube_length": "5", - "cooling_tube_retraction": "91.5", - "default_bed_type": "", - "default_filament_profile": [ - "Anycubic Generic PLA" - ], - "default_print_profile": "0.20mm Standard @Anycubic 4MaxPro2", - "deretraction_speed": [ - "25" - ], - "disable_m73": "0", - "emit_machine_limits_to_gcode": "1", - "enable_filament_ramming": "1", - "enable_long_retraction_when_cut": "0", - "extra_loading_move": "-2", - "extruder_clearance_height_to_lid": "140", - "extruder_clearance_height_to_rod": "36", - "extruder_clearance_radius": "65", - "extruder_colour": [ - "#018001" - ], - "extruder_offset": [ - "0x0" - ], - "fan_kickstart": "0", - "fan_speedup_overhangs": "1", - "fan_speedup_time": "0", - "gcode_flavor": "marlin", - "head_wrap_detect_zone": [], - "high_current_on_filament_swap": "0", - "host_type": "octoprint", - "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]", - "long_retractions_when_cut": [ - "0" - ], - "machine_end_gcode": "M104 S0 ; turn off extruder heating\nM140 S0 ; turn off bed heating\nM107 ; turn off fans\nG91 ; relative positioning\nG0 Z+0.5 ; move Z up a tiny bit\nG90 ; absolute positioning\nG0 X135 Y105 F{machine_max_speed_x[0]*60} ; move extruder to center position\nG0 Z190.5 F{machine_max_speed_z[0]*60} ; lower the plattform to Z min\nM84 ; steppers off\nG90 ; absolute positioning\n", - "machine_load_filament_time": "0", - "machine_max_acceleration_e": [ - "5000", - "5000" - ], - "machine_max_acceleration_extruding": [ - "1250", - "1250" - ], - "machine_max_acceleration_retracting": [ - "1250", - "1250" - ], - "machine_max_acceleration_travel": [ - "1500", - "1500" - ], - "machine_max_acceleration_x": [ - "1000", - "900" - ], - "machine_max_acceleration_y": [ - "1000", - "900" - ], - "machine_max_acceleration_z": [ - "1000", - "100" - ], - "machine_max_jerk_e": [ - "5", - "5" - ], - "machine_max_jerk_x": [ - "6", - "6" - ], - "machine_max_jerk_y": [ - "6", - "6" - ], - "machine_max_jerk_z": [ - "0.2", - "0.2" - ], - "machine_max_junction_deviation": [ - "0.10", - "0" - ], - "machine_max_speed_e": [ - "120", - "120" - ], - "machine_max_speed_x": [ - "200", - "200" - ], - "machine_max_speed_y": [ - "200", - "200" - ], - "machine_max_speed_z": [ - "64", - "16" - ], - "machine_min_extruding_rate": [ - "0", - "0" - ], - "machine_min_travel_rate": [ - "0", - "0" - ], - "machine_pause_gcode": "M601", - "machine_start_gcode": "G21 ; metric values\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 X0 Y0 ; home X and Y\nG28 Z0 ; home Z\nG1 Z30 F{machine_max_speed_z[0]*60} ; move Z a bit down to not blow on the bed edge while heating\nG1 X10 F3900 ; let some space on x to prevent the filament cooling exhaust from beeing blocked by the servo motor\nM190 S[bed_temperature_initial_layer_single] ; wait for bed temp\nM104 S[nozzle_temperature_initial_layer] ; set extruder temp\nM106 S80 ; turn on fan to prevent air nozzle melt while heating up\nM109 S[nozzle_temperature_initial_layer] ; wait for extruder temp\nM107 ; start with the fan off\nG28 X0 ; goto X home again\nG92 E0 ; zero the extruded length\nG1 Z0.2 F360 ; move plattform upwards\n; extrude material next to the plattform (comment or remove following lines to disable)\nG1 F180 E20 ; extrude some material next to the plattform\nG92 E0 ; zero the extruded length\nG1 E-[retraction_length] F{retraction_speed[0]*60} ; do a filament retract\nG92 E0 ; zero the extruded length again\nG1 X5 F3900 ; move sideways to get rid of that string\nG1 E[retraction_length] F{retraction_speed[0]*60} ; do a filament deretract with retract parameters\nG92 E0 ; zero the extruded length again\n; draw intro line (comment or remove following lines to disable)\nG1 X30 E5 F700 ; draw intro line\nG92 E0 ; zero the extruded length\nG1 E-[retraction_length] F{retraction_speed[0]*60} ; do a filament retract\nG1 X40 Z2.0 ; move away from the introline\nG92 E0 ; zero the extruded length again\nG1 E[retraction_length] F{retraction_speed[0]*60} ; do a filament deretract with retract parameters\n; end of intro line code\nM117 Printing...\nG5", - "machine_tool_change_time": "0", - "machine_unload_filament_time": "0", - "manual_filament_change": "0", - "max_layer_height": [ - "0.3" - ], - "max_resonance_avoidance_speed": "120", - "min_layer_height": [ - "0.07" - ], - "min_resonance_avoidance_speed": "70", - "nozzle_diameter": [ - "0.4" - ], - "nozzle_height": "2.5", - "nozzle_hrc": "0", - "nozzle_type": "undefine", - "nozzle_volume": "0", - "parking_pos_retraction": "92", - "pellet_modded_printer": "0", - "preferred_orientation": "0", - "printable_area": [ - "0x0", - "300x0", - "300x300", - "0x300" - ], - "printable_height": "350", - "printer_model": "Anet A8 Plus", - "printer_notes": "", - "printer_settings_id": "Anet A8 Plus 0.4 nozzle", - "printer_structure": "undefine", - "printer_technology": "FFF", - "printer_variant": "0.4", - "printhost_authorization_type": "key", - "printhost_ssl_ignore_revoke": "0", - "printing_by_object_gcode": "", - "purge_in_prime_tower": "1", - "resonance_avoidance": "0", - "retract_before_wipe": [ - "0%" - ], - "retract_length_toolchange": [ - "10" - ], - "retract_lift_above": [ - "0" - ], - "retract_lift_below": [ - "0" - ], - "retract_lift_enforce": [ - "All Surfaces" - ], - "retract_restart_extra": [ - "0" - ], - "retract_restart_extra_toolchange": [ - "0" - ], - "retract_when_changing_layer": [ - "1" - ], - "retraction_distances_when_cut": [ - "18" - ], - "retraction_length": [ - "2.5" - ], - "retraction_minimum_travel": [ - "2" - ], - "retraction_speed": [ - "35" - ], - "scan_first_layer": "0", - "silent_mode": "0", - "single_extruder_multi_material": "1", - "support_air_filtration": "1", - "support_chamber_temp_control": "1", - "support_multi_bed_types": "0", - "template_custom_gcode": "", - "thumbnails": "48x48/PNG,300x300/PNG", - "thumbnails_format": "PNG", - "time_cost": "0", - "time_lapse_gcode": "", - "travel_slope": [ - "3" - ], - "upward_compatible_machine": [], - "use_firmware_retraction": "0", - "use_relative_e_distances": "1", - "wipe": [ - "1" - ], - "wipe_distance": [ - "1" - ], - "z_hop": [ - "0.4" - ], - "z_hop_types": [ - "Normal Lift" - ], - "z_offset": "0" -} diff --git a/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.orca_printer b/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.orca_printer deleted file mode 100644 index b73091555d..0000000000 Binary files a/resources/profiles/Anet/machine/Anet A8 Plus 0.4 nozzle.orca_printer and /dev/null differ diff --git a/resources/profiles/Anycubic/filament/fdm_filament_common.json b/resources/profiles/Anycubic/filament/fdm_filament_common.json index 868a8418e6..2949245a6e 100644 --- a/resources/profiles/Anycubic/filament/fdm_filament_common.json +++ b/resources/profiles/Anycubic/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json b/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json index a33b6ee6f8..72e5707665 100644 --- a/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json +++ b/resources/profiles/Anycubic/machine/Anycubic Kobra X 0.4 nozzle.json @@ -41,7 +41,7 @@ "before_layer_change_gcode": "", "best_object_pos": "0.5,0.5", "change_extrusion_role_gcode": "", - "change_filament_gcode": "; FLUSH_START\n;@2026-04-03 17:46:45 3+n换料gcode,包括7=3+4,19=3+4×4\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n;;; SET_VELOCITY_LIMIT VELOCITY=350 ACCEL=10000\n;;; G1 E-2 F4800\n;;; G1 Z{toolchange_z+0.6} F1800\n;;; M106 S0\n;;; G1 X265 F21000\n;;; M400 P370\n;;; G1 X277.5 F600\n;;; G1 E-2 F300\n;;; M400 P361\n;;; G1 Z{toolchange_z+3} F1200\n;;; G1 X0 F21000\n;;; G1 X-17.5 F5250\n;;; M400 P1569\n\n{local minimal_extrude_ = 5.0}\n{if one_of(filament_type[current_extruder], \"TPU\", \"PVA\")}\n{local minimal_extrude_ = 8.0}\n{endif}\n;;; G1 E{minimal_extrude_} F300\n;;; G1 E-33 F600\n\n{ local curr_t = current_extruder; local next_t = next_extruder;}\n{ local tab_step_time_ = (0, 850, 1350, 850, 850, 0, 1350, 1350, 1350, 1350, 0, 850, 850, 1350, 850, 0)};\n{ if (0 <= curr_t && curr_t < 3) then local step_from_=curr_t else local step_from_=3 endif}; from {step_from_}\n{ if (0 <= next_t && next_t < 3) then local step_into_=next_t else local step_into_=3 endif}; from {step_into_}\n;;; M400 P{tab_step_time_[step_from_ * 4 + step_into_]}\n\n{ local magic_mask_with_box = flush_length_4}\n{ if magic_mask_with_box == -1392 && size(filament_type) > 0 && size(filament_type) == size(ace_t_box_vector) && size(filament_type) == size(ace_t_slot_vector) }\n { local is_curr_in_box = size(ace_t_box_vector) > curr_t ? ace_t_box_vector[curr_t] >= 0 ? true : false : false}; is_curr_in_box = {is_curr_in_box}\n { local is_next_in_box = size(ace_t_box_vector) > next_t ? ace_t_box_vector[next_t] >= 0 ? true : false : false}; is_next_in_box = {is_next_in_box}\n\n; curr_t box={ace_t_box_vector[curr_t]}, slot={ace_t_slot_vector[curr_t]}; next_t box={ace_t_box_vector[next_t]}, slot={ace_t_slot_vector[next_t]}\n { if ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] < 0}\n;;; M400 P0 ; 料架→料架\n { elsif ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] >= 0 }\n;;; M400 P40409 ; 料架→盒子\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] < 0 }\n;;; M400 P51591 ; 盒子→料架\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] == ace_t_box_vector[curr_t] }\n { if 0 < ace_t_slot_vector[curr_t] && ace_t_slot_vector[curr_t] <= 4 && 0 < ace_t_slot_vector[next_t] && ace_t_slot_vector[next_t] <= 4}\n;;; M400 P2700 ; 四进四→料盒\n { else }\n;;; M400 P91279 ; 盒子→盒子\n { endif }\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] != ace_t_box_vector[curr_t] }\n;;; M400 P93746 ; 盒子→不同盒子\n { else }\n; 未知\n { endif }\n{ endif }\n\n\nT[next_extruder]\n\n;;; G1 E8 F300\n;;; M400 P3643\n;;; G1 E13 F1200\n;;; M400 P1000\n\n{local flush_length_= flush_length}\n{local loops_=max(1,int((flush_length_-70+150) / 150))}\n{local extrude_length_=flush_length_ / loops_}\n{local EXTRUDE_SPEED_ = 5 * 60}\n{local UNWIND_SPEED_ = 20 *60}\n{local index_ = 0}\n\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; G1 E0.000001\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n\n; G1 X{x_after_toolchange} Y{y_after_toolchange} F12000\n; G1 Z{toolchange_z} F1200\n;;; G1 E2 F1800\n; SET_VELOCITY_LIMIT VELOCITY=450 ACCEL=10000\n;;; M400 P0\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n; FLUSH_END", + "change_filament_gcode": "; FLUSH_START\n;@2026-04-03 17:46:45 3+n换料gcode,包括7=3+4,19=3+4×4\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n;;; SET_VELOCITY_LIMIT VELOCITY=350 ACCEL=10000\n;;; G1 E-2 F4800\n;;; G1 Z{toolchange_z+0.6} F1800\n;;; M106 S0\n;;; G1 X265 F21000\n;;; M400 P370\n;;; G1 X277.5 F600\n;;; G1 E-2 F300\n;;; M400 P361\n;;; G1 Z{toolchange_z+3} F1200\n;;; G1 X0 F21000\n;;; G1 X-17.5 F5250\n;;; M400 P1569\n\n{local minimal_extrude_ = 5.0}\n{if one_of(filament_type[current_extruder], \"TPU\", \"PVA\")}\n{local minimal_extrude_ = 8.0}\n{endif}\n;;; G1 E{minimal_extrude_} F300\n;;; G1 E-33 F600\n\n{ local curr_t = current_extruder; local next_t = next_extruder;}\n{ local tab_step_time_ = (0, 850, 1350, 850, 850, 0, 1350, 1350, 1350, 1350, 0, 850, 850, 1350, 850, 0)};\n{ if (0 <= curr_t && curr_t < 3) then local step_from_=curr_t else local step_from_=3 endif}; from {step_from_}\n{ if (0 <= next_t && next_t < 3) then local step_into_=next_t else local step_into_=3 endif}; from {step_into_}\n;;; M400 P{tab_step_time_[step_from_ * 4 + step_into_]}\n\n{ local magic_mask_with_box = flush_length_4}\n{ if magic_mask_with_box == -1392 }\n { local is_curr_in_box = size(ace_t_box_vector) > curr_t ? ace_t_box_vector[curr_t] >= 0 ? true : false : false}; is_curr_in_box = {is_curr_in_box}\n { local is_next_in_box = size(ace_t_box_vector) > next_t ? ace_t_box_vector[next_t] >= 0 ? true : false : false}; is_next_in_box = {is_next_in_box}\n\n; curr_t box={ace_t_box_vector[curr_t]}, slot={ace_t_slot_vector[curr_t]}; next_t box={ace_t_box_vector[next_t]}, slot={ace_t_slot_vector[next_t]}\n { if ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] < 0}\n;;; M400 P0 ; 料架→料架\n { elsif ace_t_box_vector[curr_t] < 0 && ace_t_box_vector[next_t] >= 0 }\n;;; M400 P40409 ; 料架→盒子\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] < 0 }\n;;; M400 P51591 ; 盒子→料架\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] == ace_t_box_vector[curr_t] }\n { if 0 < ace_t_slot_vector[curr_t] && ace_t_slot_vector[curr_t] <= 4 && 0 < ace_t_slot_vector[next_t] && ace_t_slot_vector[next_t] <= 4}\n;;; M400 P2700 ; 四进四→料盒\n { else }\n;;; M400 P91279 ; 盒子→盒子\n { endif }\n { elsif ace_t_box_vector[curr_t] >= 0 && ace_t_box_vector[next_t] != ace_t_box_vector[curr_t] }\n;;; M400 P93746 ; 盒子→不同盒子\n { else }\n; 未知\n { endif }\n{ endif }\n\n\nT[next_extruder]\n\n;;; G1 E8 F300\n;;; M400 P3643\n;;; G1 E13 F1200\n;;; M400 P1000\n\n{local flush_length_= flush_length}\n{local loops_=max(1,int((flush_length_-70+150) / 150))}\n{local extrude_length_=flush_length_ / loops_}\n{local EXTRUDE_SPEED_ = 5 * 60}\n{local UNWIND_SPEED_ = 20 *60}\n{local index_ = 0}\n\n{ if (loops_ > 0) }\n{ local loops_ = loops_ - 1}\n{ local index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; G1 E0.000001\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n{ if (loops_ > 0) }\n{ loops_ = loops_ - 1}\n{ index_ = index_ + 1}\n; {index_} + {loops_}\n;;; M106 S0\n;;; M400 P1000\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.18} F{EXTRUDE_SPEED_}\n;;; G1 E{extrude_length_*0.02} F{EXTRUDE_SPEED_}\n;;; M400 P{extrude_length_/0.03}\n;;; M106 S255\n;;; M400 P2005\n;;; G1 E-2 F{UNWIND_SPEED_}\n;;; M400 P414\n{endif}\n\n; G1 X{x_after_toolchange} Y{y_after_toolchange} F12000\n; G1 Z{toolchange_z} F1200\n;;; G1 E2 F1800\n; SET_VELOCITY_LIMIT VELOCITY=450 ACCEL=10000\n;;; M400 P0\n;_GP_INLINE_ESTIMATED_PRINTING_TIME_PLACEHOLDER\n; FLUSH_END", "cooling_tube_length": "0", "cooling_tube_retraction": "0", "deretraction_speed": [ diff --git a/resources/profiles/Artillery/filament/fdm_filament_common.json b/resources/profiles/Artillery/filament/fdm_filament_common.json index f8aa522eb2..abf727c392 100644 --- a/resources/profiles/Artillery/filament/fdm_filament_common.json +++ b/resources/profiles/Artillery/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/BBL/filament/fdm_filament_common.json b/resources/profiles/BBL/filament/fdm_filament_common.json index 69fb92a4ec..caa037c74b 100644 --- a/resources/profiles/BBL/filament/fdm_filament_common.json +++ b/resources/profiles/BBL/filament/fdm_filament_common.json @@ -97,7 +97,7 @@ "nil" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_ramming_volumetric_speed": [ "-1" diff --git a/resources/profiles/Blocks/filament/fdm_filament_common.json b/resources/profiles/Blocks/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Blocks/filament/fdm_filament_common.json +++ b/resources/profiles/Blocks/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/CONSTRUCT3D/filament/fdm_filament_common.json b/resources/profiles/CONSTRUCT3D/filament/fdm_filament_common.json index fc6dba4016..bf2a52192b 100644 --- a/resources/profiles/CONSTRUCT3D/filament/fdm_filament_common.json +++ b/resources/profiles/CONSTRUCT3D/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/CoLiDo/filament/fdm_filament_common.json b/resources/profiles/CoLiDo/filament/fdm_filament_common.json index 996fd8412b..ab6956a1a4 100644 --- a/resources/profiles/CoLiDo/filament/fdm_filament_common.json +++ b/resources/profiles/CoLiDo/filament/fdm_filament_common.json @@ -67,7 +67,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Comgrow/filament/fdm_filament_common.json b/resources/profiles/Comgrow/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Comgrow/filament/fdm_filament_common.json +++ b/resources/profiles/Comgrow/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Creality/filament/fdm_filament_common.json b/resources/profiles/Creality/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Creality/filament/fdm_filament_common.json +++ b/resources/profiles/Creality/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Cubicon/filament/fdm_filament_common.json b/resources/profiles/Cubicon/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Cubicon/filament/fdm_filament_common.json +++ b/resources/profiles/Cubicon/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/DeltaMaker/filament/fdm_filament_pet.json b/resources/profiles/DeltaMaker/filament/fdm_filament_pet.json index 6e60f86bbd..52cc522d49 100755 --- a/resources/profiles/DeltaMaker/filament/fdm_filament_pet.json +++ b/resources/profiles/DeltaMaker/filament/fdm_filament_pet.json @@ -14,7 +14,7 @@ "15" ], "filament_max_volumetric_speed": [ - "0" + "8" ], "filament_type": [ "PETG" diff --git a/resources/profiles/DeltaMaker/filament/fdm_filament_pla.json b/resources/profiles/DeltaMaker/filament/fdm_filament_pla.json index b4a6b48e02..6a791a5846 100755 --- a/resources/profiles/DeltaMaker/filament/fdm_filament_pla.json +++ b/resources/profiles/DeltaMaker/filament/fdm_filament_pla.json @@ -6,7 +6,7 @@ "instantiation": "false", "fan_cooling_layer_time": "100", "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_type": [ "PLA" diff --git a/resources/profiles/DeltaMaker/filament/fdm_filament_tpu.json b/resources/profiles/DeltaMaker/filament/fdm_filament_tpu.json index 5776cd8939..29b2e790a5 100755 --- a/resources/profiles/DeltaMaker/filament/fdm_filament_tpu.json +++ b/resources/profiles/DeltaMaker/filament/fdm_filament_tpu.json @@ -14,7 +14,7 @@ "30" ], "filament_max_volumetric_speed": [ - "0" + "3.6" ], "filament_type": [ "TPU" diff --git a/resources/profiles/Dremel/filament/fdm_filament_common.json b/resources/profiles/Dremel/filament/fdm_filament_common.json index fbfcbfb193..b87e860352 100644 --- a/resources/profiles/Dremel/filament/fdm_filament_common.json +++ b/resources/profiles/Dremel/filament/fdm_filament_common.json @@ -40,7 +40,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Elegoo/filament/fdm_filament_common.json b/resources/profiles/Elegoo/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Elegoo/filament/fdm_filament_common.json +++ b/resources/profiles/Elegoo/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Eryone/filament/fdm_filament_common.json b/resources/profiles/Eryone/filament/fdm_filament_common.json index 83af95dd28..83f2a1f5d3 100644 --- a/resources/profiles/Eryone/filament/fdm_filament_common.json +++ b/resources/profiles/Eryone/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/FLSun/filament/fdm_filament_common.json b/resources/profiles/FLSun/filament/fdm_filament_common.json index 868a8418e6..2949245a6e 100644 --- a/resources/profiles/FLSun/filament/fdm_filament_common.json +++ b/resources/profiles/FLSun/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Flashforge/filament/fdm_filament_common.json b/resources/profiles/Flashforge/filament/fdm_filament_common.json index cb6109169c..77353ae799 100644 --- a/resources/profiles/Flashforge/filament/fdm_filament_common.json +++ b/resources/profiles/Flashforge/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Flashforge/filament/fdm_filament_pet.json b/resources/profiles/Flashforge/filament/fdm_filament_pet.json index f32eb3f72c..678ab77822 100644 --- a/resources/profiles/Flashforge/filament/fdm_filament_pet.json +++ b/resources/profiles/Flashforge/filament/fdm_filament_pet.json @@ -38,7 +38,7 @@ "15" ], "filament_max_volumetric_speed": [ - "0" + "8" ], "filament_type": [ "PETG" diff --git a/resources/profiles/Flashforge/filament/fdm_filament_pla.json b/resources/profiles/Flashforge/filament/fdm_filament_pla.json index 3086172aab..7dd7f4e42a 100644 --- a/resources/profiles/Flashforge/filament/fdm_filament_pla.json +++ b/resources/profiles/Flashforge/filament/fdm_filament_pla.json @@ -8,7 +8,7 @@ "100" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_type": [ "PLA" diff --git a/resources/profiles/FlyingBear/filament/Ghost7/fdm_filament_common_Ghost7.json b/resources/profiles/FlyingBear/filament/Ghost7/fdm_filament_common_Ghost7.json index 01c835d5c8..7200bb2a0f 100644 --- a/resources/profiles/FlyingBear/filament/Ghost7/fdm_filament_common_Ghost7.json +++ b/resources/profiles/FlyingBear/filament/Ghost7/fdm_filament_common_Ghost7.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/FlyingBear/filament/S1/fdm_filament_common_S1.json b/resources/profiles/FlyingBear/filament/S1/fdm_filament_common_S1.json index cefa33afa5..5501986fb5 100644 --- a/resources/profiles/FlyingBear/filament/S1/fdm_filament_common_S1.json +++ b/resources/profiles/FlyingBear/filament/S1/fdm_filament_common_S1.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/FlyingBear/filament/fdm_filament_common.json b/resources/profiles/FlyingBear/filament/fdm_filament_common.json index 64993e656a..b01bfa0377 100644 --- a/resources/profiles/FlyingBear/filament/fdm_filament_common.json +++ b/resources/profiles/FlyingBear/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/InfiMech/filament/EX+APS/fdm_filament_common_EX+APS.json b/resources/profiles/InfiMech/filament/EX+APS/fdm_filament_common_EX+APS.json index 9cc78b356c..2d051eeee2 100644 --- a/resources/profiles/InfiMech/filament/EX+APS/fdm_filament_common_EX+APS.json +++ b/resources/profiles/InfiMech/filament/EX+APS/fdm_filament_common_EX+APS.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/InfiMech/filament/EX/fdm_filament_common_EX.json b/resources/profiles/InfiMech/filament/EX/fdm_filament_common_EX.json index f4990a806c..a67718f5e0 100644 --- a/resources/profiles/InfiMech/filament/EX/fdm_filament_common_EX.json +++ b/resources/profiles/InfiMech/filament/EX/fdm_filament_common_EX.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/InfiMech/filament/HSN/fdm_filament_common_HSN.json b/resources/profiles/InfiMech/filament/HSN/fdm_filament_common_HSN.json index 847c3260e4..e8ae383cf3 100644 --- a/resources/profiles/InfiMech/filament/HSN/fdm_filament_common_HSN.json +++ b/resources/profiles/InfiMech/filament/HSN/fdm_filament_common_HSN.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/InfiMech/filament/fdm_filament_common.json b/resources/profiles/InfiMech/filament/fdm_filament_common.json index 64993e656a..b01bfa0377 100644 --- a/resources/profiles/InfiMech/filament/fdm_filament_common.json +++ b/resources/profiles/InfiMech/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/LH/filament/fdm_filament_common.json b/resources/profiles/LH/filament/fdm_filament_common.json index 788382bc9e..50f0df75c4 100644 --- a/resources/profiles/LH/filament/fdm_filament_common.json +++ b/resources/profiles/LH/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/LONGER/filament/fdm_filament_common.json b/resources/profiles/LONGER/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/LONGER/filament/fdm_filament_common.json +++ b/resources/profiles/LONGER/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/OrcaArena/filament/fdm_filament_common.json b/resources/profiles/OrcaArena/filament/fdm_filament_common.json index 4026949258..27b0ff7b5e 100644 --- a/resources/profiles/OrcaArena/filament/fdm_filament_common.json +++ b/resources/profiles/OrcaArena/filament/fdm_filament_common.json @@ -70,7 +70,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/OrcaFilamentLibrary/filament/base/fdm_filament_common.json b/resources/profiles/OrcaFilamentLibrary/filament/base/fdm_filament_common.json index 1dc6e50f39..ce95ca7c52 100644 --- a/resources/profiles/OrcaFilamentLibrary/filament/base/fdm_filament_common.json +++ b/resources/profiles/OrcaFilamentLibrary/filament/base/fdm_filament_common.json @@ -61,7 +61,7 @@ "nil" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Peopoly/filament/fdm_filament_common.json b/resources/profiles/Peopoly/filament/fdm_filament_common.json index 868a8418e6..2949245a6e 100644 --- a/resources/profiles/Peopoly/filament/fdm_filament_common.json +++ b/resources/profiles/Peopoly/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Phrozen/filament/fdm_filament_common.json b/resources/profiles/Phrozen/filament/fdm_filament_common.json index 868a8418e6..2949245a6e 100644 --- a/resources/profiles/Phrozen/filament/fdm_filament_common.json +++ b/resources/profiles/Phrozen/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Prusa/filament/fdm_filament_common.json b/resources/profiles/Prusa/filament/fdm_filament_common.json index f8aa522eb2..abf727c392 100644 --- a/resources/profiles/Prusa/filament/fdm_filament_common.json +++ b/resources/profiles/Prusa/filament/fdm_filament_common.json @@ -58,7 +58,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Qidi/filament/fdm_filament_common.json b/resources/profiles/Qidi/filament/fdm_filament_common.json index 81e3df4e5b..e0e07572c3 100644 --- a/resources/profiles/Qidi/filament/fdm_filament_common.json +++ b/resources/profiles/Qidi/filament/fdm_filament_common.json @@ -61,7 +61,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Ratrig/filament/fdm_filament_common.json b/resources/profiles/Ratrig/filament/fdm_filament_common.json index 8d05a6f91a..ab5b8305a6 100644 --- a/resources/profiles/Ratrig/filament/fdm_filament_common.json +++ b/resources/profiles/Ratrig/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/SecKit/filament/fdm_filament_common.json b/resources/profiles/SecKit/filament/fdm_filament_common.json index 8d05a6f91a..ab5b8305a6 100644 --- a/resources/profiles/SecKit/filament/fdm_filament_common.json +++ b/resources/profiles/SecKit/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Snapmaker/filament/fdm_filament_common.json b/resources/profiles/Snapmaker/filament/fdm_filament_common.json index 66296d8ded..04c0a64a6f 100644 --- a/resources/profiles/Snapmaker/filament/fdm_filament_common.json +++ b/resources/profiles/Snapmaker/filament/fdm_filament_common.json @@ -67,7 +67,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "0" diff --git a/resources/profiles/Tiertime/filament/fdm_filament_common.json b/resources/profiles/Tiertime/filament/fdm_filament_common.json index dd89148ec9..94ed0997ee 100644 --- a/resources/profiles/Tiertime/filament/fdm_filament_common.json +++ b/resources/profiles/Tiertime/filament/fdm_filament_common.json @@ -61,7 +61,7 @@ "nil" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Vzbot/filament/fdm_filament_common.json b/resources/profiles/Vzbot/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Vzbot/filament/fdm_filament_common.json +++ b/resources/profiles/Vzbot/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/Wanhao France/filament/fdm_filament_common.json b/resources/profiles/Wanhao France/filament/fdm_filament_common.json index 205c0d3075..9294e67f0f 100644 --- a/resources/profiles/Wanhao France/filament/fdm_filament_common.json +++ b/resources/profiles/Wanhao France/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "1.75" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/WonderMaker/filament/fdm_filament_common.json b/resources/profiles/WonderMaker/filament/fdm_filament_common.json index 458f1a0113..fff218a7f5 100755 --- a/resources/profiles/WonderMaker/filament/fdm_filament_common.json +++ b/resources/profiles/WonderMaker/filament/fdm_filament_common.json @@ -61,7 +61,7 @@ "nil" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/resources/profiles/re3D/filament/fdm_filament_common.json b/resources/profiles/re3D/filament/fdm_filament_common.json index 3fbf7a0288..745f258139 100644 --- a/resources/profiles/re3D/filament/fdm_filament_common.json +++ b/resources/profiles/re3D/filament/fdm_filament_common.json @@ -64,7 +64,7 @@ "2.85" ], "filament_max_volumetric_speed": [ - "0" + "12" ], "filament_minimal_purge_on_wipe_tower": [ "15" diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 41e612fdab..8cfb99a46b 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -719,6 +719,9 @@ std::string CoolingBuffer::apply_layer_cooldown( // Second generate the adjusted G-code. std::string new_gcode; new_gcode.reserve(gcode.size() * 2); + // ORCA: per-printer minimum non-zero fan PWM. Applied at every part-cooling fan emission below so any + // non-zero command is raised to at least this percent (0 disables the clamp). + const unsigned int part_cooling_fan_min_pwm = static_cast(std::max(0, m_config.part_cooling_fan_min_pwm.value)); bool overhang_fan_control= false; int overhang_fan_speed = 0; bool internal_bridge_fan_control= false; // ORCA: Add support for separate internal bridge fan speed control @@ -727,7 +730,7 @@ std::string CoolingBuffer::apply_layer_cooldown( int supp_interface_fan_speed = 0; bool ironing_fan_control= false; // ORCA: Add support for ironing fan speed control int ironing_fan_speed = 0; // ORCA: Add support for ironing fan speed control - auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, + auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, part_cooling_fan_min_pwm, &overhang_fan_control, &overhang_fan_speed, &internal_bridge_fan_control, &internal_bridge_fan_speed, &supp_interface_fan_control, &supp_interface_fan_speed, @@ -743,11 +746,11 @@ std::string CoolingBuffer::apply_layer_cooldown( int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer); supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed); - if (close_fan_the_first_x_layers <= 0 && full_fan_speed_layer > 0) { - // When ramping up fan speed from close_fan_the_first_x_layers to full_fan_speed_layer, force close_fan_the_first_x_layers above zero, - // so there will be a zero fan speed at least at the 1st layer. - close_fan_the_first_x_layers = 1; - } + // ORCA: previously a silent override forced `close_fan_the_first_x_layers` from 0 up to 1 whenever a ramp + // was configured (`full_fan_speed_layer > 0`), so the first printed layer always had the fan disabled. + // That hid the user's literal "no cooling for the first 0 layers" setting and produced a non-zero starting + // factor on the ramp denominator. The override has been removed: with N=0 and M>0 the ramp now genuinely + // starts on layer 0 at a factor of 1/M and reaches 100% at layer M-1, matching the intent of the option. if (int(layer_id) >= close_fan_the_first_x_layers) { float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed); float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time)); @@ -806,7 +809,7 @@ std::string CoolingBuffer::apply_layer_cooldown( m_fan_speed = fan_speed_new; m_current_fan_speed = fan_speed_new; if (immediately_apply) - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed, part_cooling_fan_min_pwm); } //BBS if (additional_fan_speed_new != m_additional_fan_speed) { @@ -980,26 +983,26 @@ std::string CoolingBuffer::apply_layer_cooldown( if (need_set_fan) { if (fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]){ - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed, part_cooling_fan_min_pwm); m_current_fan_speed = overhang_fan_speed; } else if (fan_speed_change_requests[CoolingLine::TYPE_INTERNAL_BRIDGE_FAN_START]){ // ORCA: Add support for separate internal bridge fan speed control - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, internal_bridge_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, internal_bridge_fan_speed, part_cooling_fan_min_pwm); m_current_fan_speed = internal_bridge_fan_speed; } else if (fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]){ - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed, part_cooling_fan_min_pwm); m_current_fan_speed = supp_interface_fan_speed; } else if (fan_speed_change_requests[CoolingLine::TYPE_IRONING_FAN_START]){ - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, ironing_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, ironing_fan_speed, part_cooling_fan_min_pwm); m_current_fan_speed = ironing_fan_speed; } else if(fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] && m_current_fan_speed != -1){ - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed, part_cooling_fan_min_pwm); fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false; } else - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed, part_cooling_fan_min_pwm); need_set_fan = false; } pos = line_end; diff --git a/src/libslic3r/GCode/FanMover.cpp b/src/libslic3r/GCode/FanMover.cpp index 63e47f3f73..112066bb85 100644 --- a/src/libslic3r/GCode/FanMover.cpp +++ b/src/libslic3r/GCode/FanMover.cpp @@ -230,7 +230,10 @@ void FanMover::_remove_slow_fan(int16_t min_speed, float past_sec) { std::string FanMover::_set_fan(int16_t speed) { //const Tool* tool = m_writer.get_tool(m_currrent_extruder < 20 ? m_currrent_extruder : 0); - return GCodeWriter::set_fan(m_writer.config.gcode_flavor.value, speed); + // ORCA: apply the per-printer non-zero fan PWM floor so reposted fan commands respect the clamp too. + const int floor_pct = m_writer.config.part_cooling_fan_min_pwm.value; + const unsigned int part_cooling_fan_min_pwm = floor_pct > 0 ? static_cast(floor_pct) : 0u; + return GCodeWriter::set_fan(m_writer.config.gcode_flavor.value, speed, part_cooling_fan_min_pwm); } diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 1ca9c3ffc4..598ae5bcd2 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -1230,8 +1230,15 @@ void GCodeProcessor::run_post_process() } }; + // Orca: track the current layer during the post-processing pass so that preheat M104s emitted + // for tool changes on the first layer use the correct first-layer temperature. The member + // m_layer_id is populated during the analysis pass and ends at the total layer count, so it + // cannot be used here — it would always select the "other layers" temperature for multi-layer + // prints. + unsigned int current_layer_id = 0; + // add lines M104 to exported gcode - auto process_line_T = [this, &export_line](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { + auto process_line_T = [this, &export_line, ¤t_layer_id](const std::string& gcode_line, const size_t g1_lines_counter, const ExportLines::Backtrace& backtrace) { const std::string cmd = GCodeReader::GCodeLine::extract_cmd(gcode_line); int tool_number = -1; @@ -1257,8 +1264,13 @@ void GCodeProcessor::run_post_process() export_line.insert_lines( backtrace, cmd, // line inserter - [tool_number, this](unsigned int id, const std::vector& time_diffs) { - const int temperature = int(m_layer_id != 1 ? m_filament_nozzle_temp[tool_number] : + [tool_number, this, ¤t_layer_id](unsigned int id, const std::vector& time_diffs) { + // Orca: use the locally-tracked layer index (current_layer_id) rather than + // the stale m_layer_id from the analysis pass. current_layer_id == 0 means + // we haven't reached the first ;LAYER_CHANGE marker yet (e.g. tool change + // inside start gcode); == 1 means we are inside the first printed layer. + // Both cases should use the first-layer nozzle temperature. + const int temperature = int(current_layer_id > 1 ? m_filament_nozzle_temp[tool_number] : m_filament_nozzle_temp_first_layer[tool_number]); // Orca: M104.1 for XL printers, I can't find the documentation for this so I copied the C++ comments from // Prusa-Firmware-Buddy here @@ -1351,6 +1363,19 @@ void GCodeProcessor::run_post_process() if (eol) { ++line_id; const unsigned int internal_g1_lines_counter = export_line.update(gcode_line, line_id, g1_lines_counter); + // Orca: track the current layer for preheat temperature selection. + // The line is ";" + reserved_tag(Layer_Change) + EOL; match it independent of + // BBL vs. compatible flavor (which differ in the tag text). + if (gcode_line.size() > 1 && gcode_line.front() == ';') { + std::string_view tag_line(gcode_line); + // strip trailing CR/LF + while (!tag_line.empty() && (tag_line.back() == '\n' || tag_line.back() == '\r')) + tag_line.remove_suffix(1); + // strip leading ';' + tag_line.remove_prefix(1); + if (tag_line == reserved_tag(ETags::Layer_Change)) + ++current_layer_id; + } // replace placeholder lines bool processed = process_placeholders(gcode_line); if (processed) diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 0c0bbcd3b6..3029f1f89c 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -1092,9 +1092,13 @@ std::string GCodeWriter::unlift() return gcode; } -std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int speed) +std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm) { std::ostringstream gcode; + // ORCA: clamp non-zero fan commands up to the configured PWM floor so fans that can't spool at low duty + // cycles still start reliably. Zero (fan off) is preserved exactly so disable-fan commands are never altered. + if (speed > 0 && part_cooling_fan_min_pwm > 0 && speed < part_cooling_fan_min_pwm) + speed = part_cooling_fan_min_pwm; if (speed == 0) { switch (gcode_flavor) { case gcfTeacup: @@ -1129,7 +1133,9 @@ std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int sp std::string GCodeWriter::set_fan(unsigned int speed) const { //BBS - return GCodeWriter::set_fan(this->config.gcode_flavor, speed); + // ORCA: pick up the per-printer PWM floor from the active config. + return GCodeWriter::set_fan(this->config.gcode_flavor, speed, + static_cast(std::max(0, this->config.part_cooling_fan_min_pwm.value))); } //BBS: set additional fan speed for BBS machine only diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index dbc64694e2..3fd7a7668b 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -98,7 +98,9 @@ public: void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; } Vec2f get_xy_offset() { return Vec2f{m_x_offset, m_y_offset}; }; // To be called by the CoolingBuffer from another thread. - static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed); + // ORCA: `part_cooling_fan_min_pwm` (0-100, default 0) is a floor applied only when `speed` is non-zero, used to overcome + // PWM start-up thresholds on fans that won't spool below a certain duty cycle. A `speed` of 0 is always honoured. + static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm = 0); // To be called by the main thread. It always emits the G-code, it does not remember the previous state. // Keeping the state is left to the CoolingBuffer, which runs asynchronously on another thread. std::string set_fan(unsigned int speed) const; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 67959a508a..0a80c019ae 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -159,6 +159,12 @@ bool Layer::is_perimeter_compatible(const PrintRegion& a, const PrintRegion& b) && config.detect_thin_wall == other_config.detect_thin_wall && config.infill_wall_overlap == other_config.infill_wall_overlap && config.top_bottom_infill_wall_overlap == other_config.top_bottom_infill_wall_overlap + // Orca: these flags directly change the effective wall count produced by the perimeter + // generator. If two regions disagree on any of them, merging their slices into one shared make_perimeters + // call would silently use the first region's flag for both. + && config.only_one_wall_first_layer == other_config.only_one_wall_first_layer + && config.only_one_wall_top == other_config.only_one_wall_top + && config.min_width_top_surface == other_config.min_width_top_surface && config.seam_slope_type == other_config.seam_slope_type && config.seam_slope_conditional == other_config.seam_slope_conditional && config.scarf_angle_threshold == other_config.scarf_angle_threshold diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6780cb6188..2c894450dd 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1326,7 +1326,7 @@ static std::vector s_Preset_machine_limits_options { static std::vector s_Preset_printer_options { "printer_technology", "printable_area", "extruder_printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor", - "fan_kickstart", "fan_speedup_time", "fan_speedup_overhangs", + "fan_kickstart", "part_cooling_fan_min_pwm", "fan_speedup_time", "fan_speedup_overhangs", "single_extruder_multi_material", "manual_filament_change", "file_start_gcode", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "printing_by_object_gcode", "layer_change_gcode", "time_lapse_gcode", "wrapping_detection_gcode", "change_filament_gcode", "change_extrusion_role_gcode", "printer_model", "printer_variant", "printer_extruder_id", "printer_extruder_variant", "extruder_variant_list", "default_nozzle_volume_type", "printable_height", "extruder_printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", @@ -2259,6 +2259,10 @@ bool PresetCollection::load_user_preset(std::string name, std::mapname == m_edited_preset.name && iter->is_dirty) { // Keep modifies when update from remote new_config.apply_only(m_edited_preset.config, m_edited_preset.config.diff(iter->config)); + } else if (iter->name == m_edited_preset.name) { + // Preset is not dirty (no local unsaved changes) — also update the edited preset + // to prevent a false "dirty" indication (orange highlight) after a silent cloud sync + m_edited_preset.config = new_config; } iter->config = new_config; iter->updated_time = cloud_update_time; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index d5a4296dcc..f2e59c3b67 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -133,6 +133,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "fan_cooling_layer_time", "full_fan_speed_layer", "fan_kickstart", + "part_cooling_fan_min_pwm", "fan_speedup_overhangs", "fan_speedup_time", "filament_colour", @@ -1753,46 +1754,47 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons* }; std::string warning_key; + const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; + const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0; + // check jerk - if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 || - m_default_object_config.inner_wall_jerk == 1) { - warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces"); - if (m_default_object_config.outer_wall_jerk == 1) - warning_key = "outer_wall_jerk"; - else if (m_default_object_config.inner_wall_jerk == 1) - warning_key = "inner_wall_jerk"; - else - warning_key = "default_jerk"; + if (!ignore_jerk_validation) { + if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 || + m_default_object_config.inner_wall_jerk == 1) { + warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces"); + if (m_default_object_config.outer_wall_jerk == 1) + warning_key = "outer_wall_jerk"; + else if (m_default_object_config.inner_wall_jerk == 1) + warning_key = "inner_wall_jerk"; + else + warning_key = "default_jerk"; - warning->opt_key = warning_key; - } + warning->opt_key = warning_key; + } - if (warning_key.empty() && m_default_object_config.default_jerk > 0) { - std::vector jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", - "top_surface_jerk", "initial_layer_jerk", "travel_jerk"}; - const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]); - warning_key.clear(); - if (m_default_object_config.default_jerk > 0) - warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk); - if (!warning_key.empty()) { - warning->string = L( - "The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\nOrca will " - "automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the " - "maximum jerk setting in your printer's configuration to get higher speeds."); - warning->opt_key = warning_key; - } + if (warning_key.empty() && m_default_object_config.default_jerk > 0) { + std::vector jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk", + "top_surface_jerk", "initial_layer_jerk", "travel_jerk"}; + const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]); + warning_key.clear(); + warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk); + if (!warning_key.empty()) { + warning->string = L( + "The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n" + "Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n" + "You can adjust the maximum jerk setting in your printer's configuration to get higher speeds."); + warning->opt_key = warning_key; + } + } } // Check junction deviation - const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0]; // Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it. const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware); if (warning_key.empty() && m_default_object_config.default_junction_deviation.value > max_junction_deviation && support_max_junction_deviation) { - warning->string = L( "Junction deviation setting exceeds the printer's maximum value " - "(machine_max_junction_deviation).\nOrca will " - "automatically cap the junction deviation to ensure it doesn't surpass the printer's " - "capabilities.\nYou can adjust the " - "machine_max_junction_deviation value in your printer's configuration to get higher limits."); + warning->string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n" + "Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n" + "You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits."); warning->opt_key = warning_key; } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0c0549f5c1..393198351b 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3724,6 +3724,28 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(0)); + // ORCA: minimum non-zero part cooling fan speed. + def = this->add("part_cooling_fan_min_pwm", coInt); + def->label = L("Minimum non-zero part cooling fan speed"); + def->tooltip = L("Some part-cooling fans cannot start spinning when commanded below a certain PWM duty cycle. " + "When set above 0, any non-zero part-cooling fan command will be raised to at least this percentage " + "so the fan reliably starts. A fan command of 0 (fan off) is always honoured exactly. " + "This clamp is applied after every other fan calculation (first-layer ramp, layer-time interpolation, " + "overhang/bridge/support-interface/ironing overrides), so scaling still operates within the range " + "[this value, 100%]." + "\nIf your firmware already disables the fan below a threshold (for example Klipper's " + "[fan] off_below: 0.10 shuts the fan off whenever the commanded duty cycle is below 10%), " + "this option and the firmware threshold should ideally be set to the same value. Matching them " + "(e.g. off_below: 0.10 in Klipper and 10% here) guarantees the slicer never emits a non-zero " + "value that the firmware would silently drop, and the fan never receives a value below the one " + "you know it can actually spool at." + "\nSet to 0 to deactivate."); + def->sidetext = L("%"); + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionInt(0)); + def = this->add("time_cost", coFloat); def->label = L("Time cost"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index a7f29bda07..b84e227c4c 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -1309,6 +1309,10 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, fan_kickstart)) ((ConfigOptionBool, fan_speedup_overhangs)) ((ConfigOptionFloat, fan_speedup_time)) + // ORCA: minimum PWM (as a percent 0-100) emitted when the part-cooling fan is asked for a non-zero speed. + // Used to overcome the PWM start-up threshold on fans that cannot spool below a certain duty cycle. + // A value of 0 (the default) leaves behaviour unchanged. A fan command of 0 (off) is always honoured. + ((ConfigOptionInt, part_cooling_fan_min_pwm)) ((ConfigOptionFloats, filament_diameter)) ((ConfigOptionBoolsNullable, filament_adaptive_volumetric_speed)) ((ConfigOptionStrings, volumetric_speed_coefficients)) diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 9e153c1792..07f0d4f3d0 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -329,6 +329,8 @@ set(SLIC3R_GUI_SOURCES GUI/Mouse3DController.hpp GUI/MsgDialog.cpp GUI/MsgDialog.hpp + GUI/MultiChoiceDialog.hpp + GUI/MultiChoiceDialog.cpp GUI/MultiMachine.cpp GUI/MultiMachine.hpp GUI/MultiMachineManagerPage.cpp @@ -496,6 +498,8 @@ set(SLIC3R_GUI_SOURCES GUI/Widgets/Button.hpp GUI/Widgets/CheckBox.cpp GUI/Widgets/CheckBox.hpp + GUI/Widgets/CheckList.cpp + GUI/Widgets/CheckList.hpp GUI/Widgets/ComboBox.cpp GUI/Widgets/ComboBox.hpp GUI/Widgets/DialogButtons.cpp @@ -685,6 +689,8 @@ if (APPLE) GUI/Mouse3DHandlerMac.mm GUI/InstanceCheckMac.mm GUI/InstanceCheckMac.h + GUI/DeepLinkHandlerMac.mm + GUI/DeepLinkHandlerMac.h GUI/GUI_UtilsMac.mm GUI/wxMediaCtrl2.mm GUI/wxMediaCtrl2.h diff --git a/src/slic3r/GUI/DeepLinkHandlerMac.h b/src/slic3r/GUI/DeepLinkHandlerMac.h new file mode 100644 index 0000000000..e9877e3868 --- /dev/null +++ b/src/slic3r/GUI/DeepLinkHandlerMac.h @@ -0,0 +1,16 @@ +#ifndef slic3r_GUI_DeepLinkHandlerMac_h_ +#define slic3r_GUI_DeepLinkHandlerMac_h_ + +namespace Slic3r { +namespace GUI { + +// Re-registers a Cocoa Apple Event handler for kInternetEventClass/kAEGetURL. +// Works around a regression observed after upgrading to wxWidgets 3.3.2 on +// macOS Tahoe (#13119) where wxWidgets' built-in handler is registered but +// never fires for orcaslicer:// deep links. +void register_mac_deep_link_handler(); + +} // namespace GUI +} // namespace Slic3r + +#endif diff --git a/src/slic3r/GUI/DeepLinkHandlerMac.mm b/src/slic3r/GUI/DeepLinkHandlerMac.mm new file mode 100644 index 0000000000..fd3d8272ff --- /dev/null +++ b/src/slic3r/GUI/DeepLinkHandlerMac.mm @@ -0,0 +1,41 @@ +#import +#import + +#include + +#include "DeepLinkHandlerMac.h" +#include "GUI_App.hpp" + +@interface OrcaDeepLinkHandler : NSObject +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply; +@end + +@implementation OrcaDeepLinkHandler +- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply +{ + NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + if (url == nil || url.length == 0) + return; + BOOST_LOG_TRIVIAL(info) << "Deep link received: " << [url UTF8String]; + Slic3r::GUI::wxGetApp().MacOpenURL(wxString::FromUTF8([url UTF8String])); +} +@end + +namespace Slic3r { +namespace GUI { + +void register_mac_deep_link_handler() +{ + static OrcaDeepLinkHandler *handler = nil; + if (handler == nil) + handler = [[OrcaDeepLinkHandler alloc] init]; + + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:handler + andSelector:@selector(handleGetURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; +} + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/ExtraRenderers.cpp b/src/slic3r/GUI/ExtraRenderers.cpp index 28837dbdad..18811ef241 100644 --- a/src/slic3r/GUI/ExtraRenderers.cpp +++ b/src/slic3r/GUI/ExtraRenderers.cpp @@ -324,9 +324,18 @@ wxWindow* BitmapChoiceRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelR else c_editor->SetSelection(atoi(data.GetText().c_str()) - 1); - // Open the dropdown immediately when the editor is focused. c_editor->Bind(wxEVT_SET_FOCUS, [c_editor](wxFocusEvent& evt) { +#ifdef __WXGTK__ + // On wxGTK the data-view editor may receive focus before its native + // window is mapped. Opening the popup one event later avoids creating + // the GTK popup without a valid toplevel parent. + c_editor->CallAfter([c_editor]() { + if (c_editor->IsShownOnScreen()) + c_editor->ForceDropdownOpen(); + }); +#else c_editor->ForceDropdownOpen(); +#endif evt.Skip(); }); @@ -392,4 +401,3 @@ wxSize TextRenderer::GetSize() const return GetTextExtent(m_value); } - diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp index 7bf4d008d4..d670181b1b 100644 --- a/src/slic3r/GUI/GLTexture.cpp +++ b/src/slic3r/GUI/GLTexture.cpp @@ -663,7 +663,9 @@ void GLTexture::render_texture(unsigned int tex_id, float left, float right, flo void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const GLTexture::Quad_UVs& uvs) { glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + // Orca: fix washed-out toolbar icons on Wayland: keep destination alpha at 1.0 so the compositor + // does not treat anti-aliased icon edges as window transparency. + glsafe(::glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); glsafe(::glEnable(GL_TEXTURE_2D)); glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 3169e53eee..aa58a2e3a1 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -11,6 +11,7 @@ #include "Downloader.hpp" #include #include +#include #include // Localization headers: include libslic3r version first so everything in this file @@ -100,6 +101,9 @@ #include "Mouse3DController.hpp" #include "RemovableDriveManager.hpp" #include "InstanceCheck.hpp" +#ifdef __APPLE__ +#include "DeepLinkHandlerMac.h" +#endif #include "NotificationManager.hpp" #include "UnsavedChangesDialog.hpp" #include "SavePresetDialog.hpp" @@ -783,9 +787,20 @@ void GUI_App::post_init() mainframe->select_tab(size_t(MainFrame::tp3DEditor)); plater_->select_view_3D("3D"); //BBS init the opengl resource here -//#ifdef __linux__ - if (plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen()&&plater_->canvas3D()->make_current_for_postinit()) { -//#endif + if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() || + !plater_->canvas3D()->make_current_for_postinit()) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": glcontext not ready, postpone init"; + plater_->canvas3D()->enable_render(true); + plater_->canvas3D()->set_as_dirty(); +#ifdef __linux__ + // Wayland/EGL may not have committed the GL surface yet; ask the + // idle loop to retry post_init when the canvas is actually mapped. + // Without this, GL function pointers stay null and the first + // Preview focus crashes in Camera::apply_viewport. + m_post_initialized = false; + return; +#endif + } else { Size canvas_size = plater_->canvas3D()->get_canvas_size(); wxGetApp().imgui()->set_display_size(static_cast(canvas_size.get_width()), static_cast(canvas_size.get_height())); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl"; @@ -805,14 +820,7 @@ void GUI_App::post_init() plater_->canvas3D()->render(false); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test"; } -//#ifdef __linux__ } - else { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "Found glcontext not ready, postpone the init"; - plater_->canvas3D()->enable_render(true); - plater_->canvas3D()->set_as_dirty(); - } -//#endif if (is_editor()) mainframe->select_tab(size_t(0)); if (app_config->get("default_page") == "1") @@ -1900,6 +1908,7 @@ void GUI_App::init_networking_callbacks() } if (return_code == 5) { GUI::wxGetApp().CallAfter([this, provider = event.provider] { + BOOST_LOG_TRIVIAL(info) << "logout: login expired"; this->request_user_logout(provider); MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK); if (msg_dlg.ShowModal() == wxOK) { @@ -2546,6 +2555,12 @@ std::string get_system_info() bool GUI_App::on_init_inner() { wxLog::SetActiveTarget(new wxBoostLog()); + +#ifdef __APPLE__ + // Override wxWidgets' kAEGetURL handler so orcaslicer:// deep links keep + // working after the wxWidgets 3.3.2 upgrade on macOS (#13119). + register_mac_deep_link_handler(); +#endif #if BBL_RELEASE_TO_PUBLIC wxLog::SetLogLevel(wxLOG_Message); #endif @@ -4526,7 +4541,8 @@ std::string GUI_App::handle_web_request(std::string cmd) } else if (command_str.compare("homepage_logout") == 0) { CallAfter([this] { - wxGetApp().request_user_logout(); + BOOST_LOG_TRIVIAL(info) << "logout: homepage_logout"; + request_user_logout(); }); } else if (command_str.compare("get_orca_login_info") == 0) { @@ -4539,18 +4555,22 @@ std::string GUI_App::handle_web_request(std::string cmd) CallAfter([this] { request_login(true, BBL_CLOUD_PROVIDER); }); } else if (command_str.compare("homepage_bambu_logout") == 0) { - CallAfter([this] { request_user_logout(BBL_CLOUD_PROVIDER); }); + CallAfter([this] { + BOOST_LOG_TRIVIAL(info) << "logout: homepage_bambu_logout"; + request_user_logout(BBL_CLOUD_PROVIDER); + }); } else if (command_str.compare("homepage_orca_login_or_register") == 0) { CallAfter([this] { request_login(true, ORCA_CLOUD_PROVIDER); }); } else if (command_str.compare("homepage_orca_logout") == 0) { - CallAfter([this] { request_user_logout(ORCA_CLOUD_PROVIDER); }); + CallAfter([this] { + BOOST_LOG_TRIVIAL(info) << "logout: homepage_orca_logout"; + request_user_logout(ORCA_CLOUD_PROVIDER); + }); } else if (command_str.compare("homepage_modeldepot") == 0) { - CallAfter([this] { - wxGetApp().open_mall_page_dialog(); - }); + CallAfter([this] { open_mall_page_dialog(); }); } else if (command_str.compare("homepage_newproject") == 0) { this->request_open_project(""); @@ -4826,14 +4846,15 @@ void GUI_App::on_http_error(wxCommandEvent &evt) if (status == 401) { if (m_agent) { if (m_agent->is_user_login(provider)) { + BOOST_LOG_TRIVIAL(warning) << "logout: http error 401."; this->request_user_logout(provider); - if (!m_show_http_errpr_msgdlg) { + if (!m_show_http_error_msgdlg) { MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK); - m_show_http_errpr_msgdlg = true; + m_show_http_error_msgdlg = true; auto modal_result = msg_dlg.ShowModal(); if (modal_result == wxOK || modal_result == wxCLOSE) { - m_show_http_errpr_msgdlg = false; + m_show_http_error_msgdlg = false; return; } } @@ -4841,6 +4862,40 @@ void GUI_App::on_http_error(wxCommandEvent &evt) } return; } + + // No need to show dialog for 410: 410 means resource has been deleted from the server. + if (status == 410) { + BOOST_LOG_TRIVIAL(info) << "Http error 410."; + return; + } + + static bool m_is_error_shown = false; + // Show general error notification for Orca Cloud API failures (not Bambu) + if (provider == ORCA_CLOUD_PROVIDER && status >= 400 && code != HttpErrorVersionLimited) { + wxString msg; + if (!error.empty()) { + msg = wxString::Format(_L("API error (HTTP %u): %s"), status, wxString::FromUTF8(error)); + } else { + msg = wxString::Format(_L("API error (HTTP %u)"), status); + } + + if (app_config->get_bool("developer_mode")) { + // Use notification manager if ImGui is ready; fall back to wxMessageBox on Linux + // where ImGui may not be initialized until the user switches to the Prepare tab. + if (wxGetApp().plater() != nullptr && wxGetApp().imgui()->display_initialized()) { + wxGetApp() + .plater() + ->get_notification_manager() + ->push_notification(NotificationType::PlaterError, NotificationManager::NotificationLevel::WarningNotificationLevel, + msg.ToUTF8().data()); + } + } + + if (!m_is_error_shown) { + m_is_error_shown = true; + wxMessageBox(msg, _L("Orca Cloud API Error"), wxOK | wxICON_ERROR, wxGetApp().mainframe); + } + } } void GUI_App::enable_user_preset_folder(bool enable) @@ -5599,6 +5654,7 @@ void GUI_App::show_check_privacy_dlg(wxCommandEvent& evt) privacy_dlg.Bind(EVT_PRIVACY_UPDATE_CANCEL, [this, provider](wxCommandEvent &e) { app_config->set_bool("privacy_update_checked", false); if (m_agent) { + BOOST_LOG_TRIVIAL(info) << "logout: Privacy update dialog cancelled."; m_agent->user_logout(false, provider); post_logout_to_webview(provider); } @@ -6521,8 +6577,8 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg) dlg->Update(percent, _L("Loading user preset")); }); }; - cancelFn = [this, dlg]() { - return is_closing() || dlg->WasCanceled(); + cancelFn = [this, dlg, t = std::weak_ptr(m_user_sync_token)]() { + return is_closing() || dlg->WasCanceled() || t.expired(); }; finishFn = [this, dlg](bool) { CallAfter([=]{ dlg->Destroy(); }); @@ -6530,8 +6586,8 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg) } else { finishFn = [](bool) {}; // reload_settings() is now triggered from the background thread - cancelFn = [this]() { - return is_closing(); + cancelFn = [this, t = std::weak_ptr(m_user_sync_token)]() { + return is_closing() || t.expired(); }; } @@ -6763,9 +6819,41 @@ void GUI_App::stop_sync_user_preset() } } +void GUI_App::restart_sync_user_preset() +{ + if (!m_user_sync_token) { + // No sync running. If a restart helper is already in flight it will + // start the new sync once the old thread is joined — don't race it. + if (!m_restart_sync_pending) + start_sync_user_preset(true); + return; + } + + // Resetting the token signals the old thread to stop (cancelFn checks + // t.expired(), so it exits after its current HTTP request completes). + // A helper thread joins the old thread off the UI thread — no freeze — + // then starts the new sync via CallAfter once the old one is fully done. + m_user_sync_token.reset(); + m_restart_sync_pending = true; + + auto old_thread = std::move(m_sync_update_thread); + + std::thread([this, old_thread = std::move(old_thread)]() mutable { + if (old_thread.joinable()) + old_thread.join(); + m_restart_sync_pending = false; + if (!is_closing()) + CallAfter([this]() { + if (!is_closing()) + start_sync_user_preset(true); + }); + }).detach(); +} + void GUI_App::on_stealth_mode_enter() { stop_sync_user_preset(); + BOOST_LOG_TRIVIAL(info) << "logout: on_stealth_mode_enter"; request_user_logout(ORCA_CLOUD_PROVIDER); request_user_logout(BBL_CLOUD_PROVIDER); if (mainframe && mainframe->m_webview) { diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index fac853e65c..7244425cfb 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -321,10 +321,11 @@ private: boost::thread m_sync_update_thread; std::shared_ptr m_user_sync_token; + std::atomic m_restart_sync_pending {false}; bool m_is_dark_mode{ false }; bool m_adding_script_handler { false }; bool m_side_popup_status{false}; - bool m_show_http_errpr_msgdlg{false}; + bool m_show_http_error_msgdlg{false}; bool m_show_error_msgdlg{false}; wxString m_info_dialog_content; HttpServer m_http_server; @@ -530,6 +531,7 @@ public: void sync_preset(Preset* preset); void start_sync_user_preset(bool with_progress_dlg = false); void stop_sync_user_preset(); + void restart_sync_user_preset(); void on_stealth_mode_enter(); // Bundle subscription sync diff --git a/src/slic3r/GUI/GUI_ObjectTable.cpp b/src/slic3r/GUI/GUI_ObjectTable.cpp index 71174665e1..aa3408ba29 100644 --- a/src/slic3r/GUI/GUI_ObjectTable.cpp +++ b/src/slic3r/GUI/GUI_ObjectTable.cpp @@ -561,14 +561,23 @@ wxString GridCellSupportEditor::ms_stringValues[2] = { wxT(""), wxT("") }; void GridCellSupportEditor::DoActivate(int row, int col, wxGrid* grid) { - ObjectGrid* local_table = dynamic_cast(grid); wxGridBlocks cell_array = grid->GetSelectedBlocks(); - - auto left_col = cell_array.begin()->GetLeftCol(); - auto right_col = cell_array.begin()->GetRightCol(); - auto top_row = cell_array.begin()->GetTopRow(); - auto bottom_row = cell_array.begin()->GetBottomRow(); - + auto iter = cell_array.begin(); + + int left_col, right_col, top_row, bottom_row; + if (iter == cell_array.end()) { + // wxWidgets 3.3.x returns an empty range when nothing is selected; + // fall back to the cell that triggered activation so the single-cell + // branch below handles it. + left_col = right_col = col; + top_row = bottom_row = row; + } else { + left_col = iter->GetLeftCol(); + right_col = iter->GetRightCol(); + top_row = iter->GetTopRow(); + bottom_row = iter->GetBottomRow(); + } + if ((left_col == right_col) && (top_row == bottom_row)) { wxGridCellBoolEditor::DoActivate(row, col, grid); diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 8855a38405..af92140379 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -373,12 +373,13 @@ public: //BBS static int TOOLBAR_WINDOW_FLAGS; + bool display_initialized() const; + private: void init_font(bool compress); void init_input(); void init_style(); void render_draw_data(ImDrawData *draw_data); - bool display_initialized() const; void destroy_font(); std::vector load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index f4aeae01f6..d83cc1445a 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2780,6 +2780,24 @@ void MainFrame::init_menubar_as_editor() append_submenu(fileMenu, export_menu, wxID_ANY, _L("Export"), ""); fileMenu->AppendSeparator(); + append_menu_item(fileMenu, wxID_ANY, _L("Sync Presets"), _L("Pull and apply the latest presets from OrcaCloud"), + [this](wxCommandEvent&) { + if (!wxGetApp().is_user_login()) { + MessageDialog info_dlg(this, _L("You must be logged in to sync presets from cloud."), + _L("Sync Presets"), wxOK | wxICON_INFORMATION); + info_dlg.ShowModal(); + return; + } + if (m_plater) + m_plater->get_notification_manager()->push_notification( + into_u8(_L("Syncing presets from cloud\u2026"))); + wxGetApp().restart_sync_user_preset(); + }, "", nullptr, + [this]() { + return wxGetApp().is_user_login() && !wxGetApp().app_config->get_stealth_mode(); + }, this); + + fileMenu->AppendSeparator(); #ifndef __APPLE__ append_menu_item(fileMenu, wxID_EXIT, _L("Quit"), wxString::Format(_L("Quit")), diff --git a/src/slic3r/GUI/MultiChoiceDialog.cpp b/src/slic3r/GUI/MultiChoiceDialog.cpp new file mode 100644 index 0000000000..6bd5412737 --- /dev/null +++ b/src/slic3r/GUI/MultiChoiceDialog.cpp @@ -0,0 +1,58 @@ +#include "MultiChoiceDialog.hpp" + +#include "GUI_App.hpp" +#include "MainFrame.hpp" + +namespace Slic3r { namespace GUI { + +MultiChoiceDialog::MultiChoiceDialog( + wxWindow* parent, + const wxString& message, + const wxString& caption, + const wxArrayString& choices +) + : DPIDialog(parent ? parent : static_cast(wxGetApp().mainframe), wxID_ANY, caption, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) +{ + SetBackgroundColour(*wxWHITE); + + wxBoxSizer* w_sizer = new wxBoxSizer(wxVERTICAL); + + if(!message.IsEmpty()){ + wxStaticText *msg = new wxStaticText(this, wxID_ANY, message); + msg->SetFont(Label::Body_13); + msg->Wrap(-1); + w_sizer->Add(msg, 0, wxRIGHT | wxLEFT | wxTOP, FromDIP(10)); + } + + m_check_list = new CheckList(this, choices); + + w_sizer->Add(m_check_list, 1, wxRIGHT | wxLEFT | wxTOP | wxEXPAND, FromDIP(10)); + + auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"}); + + dlg_btns->GetOK()->Bind( wxEVT_BUTTON, [this](wxCommandEvent &e) {EndModal(wxID_OK);}); + dlg_btns->GetCANCEL()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {EndModal(wxID_CANCEL);}); + + w_sizer->Add(dlg_btns, 0, wxEXPAND); + + SetSizer(w_sizer); + Layout(); + w_sizer->Fit(this); + wxGetApp().UpdateDlgDarkUI(this); +} + +wxArrayInt MultiChoiceDialog::GetSelections() const +{ + return m_check_list->GetSelections(); +} + +void MultiChoiceDialog::SetSelections(wxArrayInt sel_array) +{ + m_check_list->SetSelections(sel_array); +} + +MultiChoiceDialog::~MultiChoiceDialog() {} + +void MultiChoiceDialog::on_dpi_changed(const wxRect &suggested_rect) {} + +}} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/MultiChoiceDialog.hpp b/src/slic3r/GUI/MultiChoiceDialog.hpp new file mode 100644 index 0000000000..f636bebd3b --- /dev/null +++ b/src/slic3r/GUI/MultiChoiceDialog.hpp @@ -0,0 +1,37 @@ +#ifndef slic3r_GUI_MultiChoiceDialog_hpp_ +#define slic3r_GUI_MultiChoiceDialog_hpp_ + +#include "Widgets/CheckList.hpp" +#include "Widgets/DialogButtons.hpp" + +#include +#include +#include + + +namespace Slic3r { namespace GUI { + +class MultiChoiceDialog : public DPIDialog +{ +public: + MultiChoiceDialog( + wxWindow* parent = nullptr, + const wxString& message = wxEmptyString, + const wxString& caption = wxEmptyString, + const wxArrayString& choices = wxArrayString() + ); + ~MultiChoiceDialog(); + + wxArrayInt GetSelections() const; + + void SetSelections(wxArrayInt sel_array); + +protected: + CheckList* m_check_list; + wxArrayInt m_selected_indices; + void on_dpi_changed(const wxRect &suggested_rect) override; +}; + +}} // namespace Slic3r::GUI + +#endif \ No newline at end of file diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3e7dd4868d..9fa4668607 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -15013,7 +15013,8 @@ void Plater::export_gcode(bool prefer_removable) unsigned int state = this->p->update_restart_background_process(false, false); if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) return; - default_output_file = this->p->background_process.output_filepath_for_project(""); + default_output_file = this->p->background_process.output_filepath_for_project( + into_path(this->p->get_project_filename(".3mf"))); } catch (const Slic3r::PlaceholderParserError &ex) { // Show the error with monospaced font. show_error(this, ex.what(), true); @@ -15116,7 +15117,8 @@ void Plater::export_gcode_3mf(bool export_all) unsigned int state = this->p->update_restart_background_process(false, false); if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) return; - default_output_file = this->p->background_process.output_filepath_for_project(""); + default_output_file = this->p->background_process.output_filepath_for_project( + into_path(this->p->get_project_filename(".3mf"))); } catch (const Slic3r::PlaceholderParserError& ex) { // Show the error with monospaced font. @@ -16263,7 +16265,8 @@ void Plater::send_gcode_legacy(int plate_idx, Export3mfProgressFn proFn, bool us unsigned int state = this->p->update_restart_background_process(false, false); if (state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) return; - default_output_file = this->p->background_process.output_filepath_for_project(""); + default_output_file = this->p->background_process.output_filepath_for_project( + into_path(this->p->get_project_filename(".3mf"))); } catch (const Slic3r::PlaceholderParserError& ex) { // Show the error with monospaced font. show_error(this, ex.what(), true); diff --git a/src/slic3r/GUI/PrinterWebView.cpp b/src/slic3r/GUI/PrinterWebView.cpp index 1dccfab66f..6c20e98ce6 100644 --- a/src/slic3r/GUI/PrinterWebView.cpp +++ b/src/slic3r/GUI/PrinterWebView.cpp @@ -23,6 +23,81 @@ namespace Slic3r { namespace GUI { +#ifdef __linux__ +// Workaround for #7210: WebKitGTK crashes on vue-resize's hidden probe used by +// older Fluidd/Mainsail pages. Swap that for a
shim at appendChild time +// and bridge resize events through a fake contentDocument.defaultView so vue-resize keeps +// working. Workaround proposed by @VittC. +static void inject_vue_resize_workaround(wxWebView *webView) +{ + webView->AddUserScript( + "(function() {" + " 'use strict';" + " function isVueResizeObject(el) {" + " return el && el.tagName === 'OBJECT'" + " && el.type === 'text/html'" + " && el.getAttribute('aria-hidden') === 'true'" + " && el.getAttribute('tabindex') === '-1';" + " }" + " function isResizeObserverParent(p) {" + " return p && p.classList && p.classList.contains('resize-observer');" + " }" + " function makeShim(orig, parentForRO) {" + " var shim = document.createElement('div');" + " shim.setAttribute('aria-hidden', 'true');" + " shim.setAttribute('tabindex', '-1');" + " shim.style.display = 'none';" + " var fakeWin = document.createElement('div');" + " var ro = null;" + " var origRemoveEL = fakeWin.removeEventListener.bind(fakeWin);" + " fakeWin.removeEventListener = function(type, fn, opts) {" + " origRemoveEL(type, fn, opts);" + " if (type === 'resize' && ro) { ro.disconnect(); ro = null; }" + " };" + " Object.defineProperty(shim, 'contentDocument', {" + " configurable: true," + " get: function() { return { defaultView: fakeWin }; }" + " });" + " Object.defineProperty(shim, 'contentWindow', {" + " configurable: true," + " get: function() { return fakeWin; }" + " });" + " if (typeof orig.onload === 'function') { shim.onload = orig.onload; }" + " queueMicrotask(function() {" + " if (parentForRO && typeof ResizeObserver !== 'undefined') {" + " ro = new ResizeObserver(function() {" + " fakeWin.dispatchEvent(new Event('resize'));" + " });" + " ro.observe(parentForRO);" + " }" + " if (typeof shim.onload === 'function') {" + " try { shim.onload(new Event('load')); } catch (e) {}" + " }" + " shim.dispatchEvent(new Event('load'));" + " });" + " return shim;" + " }" + " var origAppend = Node.prototype.appendChild;" + " Node.prototype.appendChild = function(child) {" + " if (isResizeObserverParent(this) && isVueResizeObject(child)) {" + " return origAppend.call(this, makeShim(child, this));" + " }" + " return origAppend.call(this, child);" + " };" + " var origInsertBefore = Node.prototype.insertBefore;" + " Node.prototype.insertBefore = function(child, ref) {" + " if (isResizeObserverParent(this) && isVueResizeObject(child)) {" + " return origInsertBefore.call(this, makeShim(child, this), ref);" + " }" + " return origInsertBefore.call(this, child, ref);" + " };" + " console.log('[vr-fix] vue-resize WebKitGTK patch active');" + "})();", + wxWEBVIEW_INJECT_AT_DOCUMENT_START + ); +} +#endif + PrinterWebView::PrinterWebView(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize) , m_browser(nullptr) @@ -43,6 +118,8 @@ PrinterWebView::PrinterWebView(wxWindow *parent) } #ifdef __linux__ + inject_vue_resize_workaround(m_browser); + auto cookiesPath = boost::filesystem::path(data_dir() + "/cache/cookies.db"); auto wv = static_cast(m_browser->GetNativeBackend()); auto wv_ctx = webkit_web_view_get_context(wv); @@ -165,6 +242,10 @@ void PrinterWebView::SendAPIKey() )", m_apikey); m_browser->RemoveAllUserScripts(); +#ifdef __linux__ + // Re-inject the vue-resize/WebKitGTK workaround that RemoveAllUserScripts just cleared. + inject_vue_resize_workaround(m_browser); +#endif m_browser->AddUserScript(script); m_browser->Reload(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index ccf595b22a..3bfdc39983 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -40,7 +40,7 @@ #include "UnsavedChangesDialog.hpp" #include "SavePresetDialog.hpp" #include "EditGCodeDialog.hpp" - +#include "MultiChoiceDialog.hpp" #include "MsgDialog.hpp" #include "Notebook.hpp" @@ -4500,6 +4500,8 @@ void TabPrinter::build_fff() line.append_option(optgroup->get_option("fan_speedup_overhangs")); optgroup->append_line(line); optgroup->append_single_option_line("fan_kickstart", "printer_basic_information_cooling_fan#fan-kick-start-time"); + // ORCA: PWM floor for fans that won't spool at low duty cycles. + optgroup->append_single_option_line("part_cooling_fan_min_pwm", "printer_basic_information_cooling_fan#minimum-non-zero-part-cooling-fan-speed"); optgroup = page->new_optgroup(L("Extruder Clearance"), "param_extruder_clearance"); optgroup->append_single_option_line("extruder_clearance_radius", "printer_basic_information_extruder_clearance#radius"); @@ -7002,7 +7004,15 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep presets.Add(from_u8(preset.name)); } - wxMultiChoiceDialog dlg(parent, deps.dialog_title, deps.dialog_label, presets); + if(deps.type == Preset::TYPE_PRINTER){ + deps.dialog_title = "Compatible printers"; + deps.dialog_label = "Select printers"; + }else{ + deps.dialog_title = "Compatible process profiles"; + deps.dialog_label = "Select profiles"; + } + + MultiChoiceDialog dlg(parent, deps.dialog_label, deps.dialog_title, presets); wxGetApp().UpdateDlgDarkUI(&dlg); // Collect and set indices of depending_presets marked as compatible. wxArrayInt selections; @@ -7015,13 +7025,16 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep break; } dlg.SetSelections(selections); + dlg.SetSize(FromDIP(wxSize(360, 480))); std::vector value; // Show the dialog. if (dlg.ShowModal() == wxID_OK) { selections.Clear(); selections = dlg.GetSelections(); - for (auto idx : selections) - value.push_back(presets[idx].ToUTF8().data()); + // leave list empty if all items checked. this will check "All" checkbox automatically. also fixes unnecessary config change + if(selections.GetCount() != presets.GetCount()) + for (auto idx : selections) + value.push_back(presets[idx].ToUTF8().data()); if (value.empty()) { deps.checkbox->SetValue(1); deps.btn->Disable(); diff --git a/src/slic3r/GUI/WebGuideDialog.cpp b/src/slic3r/GUI/WebGuideDialog.cpp index 575748fce0..f68c00ff40 100644 --- a/src/slic3r/GUI/WebGuideDialog.cpp +++ b/src/slic3r/GUI/WebGuideDialog.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "I18N.hpp" #include "libslic3r/AppConfig.hpp" @@ -516,7 +517,9 @@ void GuideFrame::OnScriptMessage(wxWebViewEvent &evt) if (agent) { agent->set_country_code(country_code); if (wxGetApp().is_user_login()) { - agent->user_logout(); + BOOST_LOG_TRIVIAL(info) << "logout: user_logout on user_guide_finish"; + // agent->user_logout(); + wxGetApp().request_user_logout(); } } } diff --git a/src/slic3r/GUI/Widgets/CheckList.cpp b/src/slic3r/GUI/Widgets/CheckList.cpp new file mode 100644 index 0000000000..cd0dcebff3 --- /dev/null +++ b/src/slic3r/GUI/Widgets/CheckList.cpp @@ -0,0 +1,225 @@ +#include "CheckList.hpp" + +#include "slic3r/GUI/GUI_App.hpp" + +CheckList::CheckList( + wxWindow* parent, + const wxArrayString& choices, + long scroll_style +) + : wxWindow(parent, wxID_ANY) + , m_search(this, "search", 16) + , m_menu(this, "filter", 16) + , m_first_load(true) +{ + Freeze(); + w_sizer = new wxBoxSizer(wxVERTICAL); + + f_sizer = new wxBoxSizer(wxHORIZONTAL); + f_bar = new wxPanel(this, wxID_ANY); + f_bar->SetBackgroundColour(parent->GetBackgroundColour()); + m_filter_box = new TextInput(f_bar, "", "", "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); + m_filter_box->SetIcon(m_search.bmp()); + m_filter_box->SetMinSize(FromDIP(wxSize(200,24))); + m_filter_box->SetSize(FromDIP(wxSize(-1,24))); + m_filter_box->SetFocus(); + m_filter_ctrl = m_filter_box->GetTextCtrl(); + m_filter_ctrl->SetFont(Label::Body_13); + m_filter_ctrl->SetSize(wxSize(-1, FromDIP(16))); // Centers text vertically + m_filter_ctrl->SetHint(_L("Type to filter...")); + m_filter_ctrl->Bind(wxEVT_TEXT, [this](auto &e) {Filter(m_filter_ctrl->GetValue());}); + m_filter_ctrl->Bind(wxEVT_TEXT_ENTER, [this](auto &e) {Filter(m_filter_ctrl->GetValue());}); + m_filter_ctrl->Bind(wxEVT_SET_FOCUS, [this](auto &e) {Filter(m_filter_ctrl->GetValue());e.Skip();}); + m_filter_ctrl->Bind(wxEVT_KILL_FOCUS, [this](auto &e) {Filter(m_filter_ctrl->GetValue());e.Skip();}); + f_sizer->Add(m_filter_box, 1, wxEXPAND); + Bind(wxEVT_SET_FOCUS, [this](auto &e) {m_filter_box->SetFocus();}); + + fb_sizer = new wxBoxSizer(wxHORIZONTAL); + auto create_btn = [this] (wxString title, bool select){ + auto btn = new wxStaticText(f_bar, wxID_ANY, title); + btn->SetForegroundColour("#009687"); + btn->SetCursor(wxCURSOR_HAND); + btn->SetFont(Label::Body_13); + btn->Bind(wxEVT_LEFT_DOWN, [this, select](wxMouseEvent &e) {SelectAll(select);}); + fb_sizer->Add(btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10)); + }; + f_sizer->Add(fb_sizer,0 ,wxALIGN_CENTER_VERTICAL); + create_btn(_L("All") , true); + create_btn(_L("None"), false); + + m_menu_button = new wxStaticBitmap(f_bar, wxID_ANY, m_menu.bmp()); + m_menu_button->SetCursor(wxCURSOR_HAND); + m_menu_button->Bind(wxEVT_LEFT_DOWN, &CheckList::ShowMenu, this); + f_sizer->Add(m_menu_button,0 ,wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + f_bar->SetSizerAndFit(f_sizer); + w_sizer->Add(f_bar, 0, wxEXPAND); + + auto spacer = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(3))); + spacer->SetBackgroundColour(parent->GetBackgroundColour()); + w_sizer->Add(spacer, 0, wxEXPAND); + + s_sizer = new wxBoxSizer(wxVERTICAL); + m_scroll_area = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, scroll_style); + m_scroll_area->SetScrollRate(0, 10); + m_scroll_area->SetSizer(s_sizer); + m_scroll_area->SetBackgroundColour(parent->GetBackgroundColour()); + m_scroll_area->Bind(wxEVT_RIGHT_DOWN, &CheckList::ShowMenu, this); + m_scroll_area->DisableFocusFromKeyboard(); + + m_info = new wxStaticText(m_scroll_area, wxID_ANY, ""); + m_info->SetFont(Label::Body_13); + s_sizer->Add(m_info, 1, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(10)); + m_info->Hide(); + + m_info_nonsel = _L("No selected items..."); + m_info_allsel = _L("All items selected..."); + m_info_empty = _L("No matching items..."); + + SetBackgroundColour(StateColor::darkModeColorFor("#DBDBDB")); // draws border on wxScrolledWindow + + w_sizer->Add(m_scroll_area, 1, wxEXPAND | wxALL, FromDIP(1)); // 1 for border + s_sizer->Layout(); + + m_list_size = choices.size(); + + m_checks.reserve(m_list_size); + + auto margin = FromDIP(2); + wxCheckBox* cb; + + for (size_t i = 0; i < m_list_size; ++i){ + cb = new wxCheckBox(m_scroll_area, wxID_ANY, choices[i]); + m_checks.emplace_back(cb); + s_sizer->Add(cb, 0, wxALL, margin); + } + + m_scroll_area->FitInside(); + s_sizer->Layout(); + + SetSizer(w_sizer); + Layout(); + Thaw(); +} + +void CheckList::SetSelections(wxArrayInt sel_array){ + if(!m_first_load){ + for (size_t i = 0; i < m_list_size; ++i) + Check(i, false); + m_first_load = false; + } + + for (int i : sel_array) + Check(i, true); +} + +wxArrayInt CheckList::GetSelections() +{ + wxArrayInt checks; + for (size_t i = 0; i < m_list_size; ++i) + if (m_checks[i]->GetValue()) + checks.push_back(i); + return checks; +} + +void CheckList::Check(int i, bool checked) +{ + if (i > -1 && i < m_list_size) + m_checks[i]->SetValue(checked); +} + +void CheckList::SelectAll(bool value) +{ + for (size_t i = 0; i < m_list_size; ++i) + Check(i, value); +} + +void CheckList::SelectVisible(bool value) +{ + auto filter = m_filter_ctrl->GetValue().Lower(); + if((!value && filter == "::unsel") || (value && filter == "::sel")) + m_filter_ctrl->SetValue(""); + for (size_t i = 0; i < m_list_size; ++i) + if(m_checks[i]->IsShown()) + Check(i, value); +} + +bool CheckList::IsChecked(int i) +{ + if (i > -1 && i < m_list_size) + return false; + return m_checks[i]->GetValue(); +} + +void CheckList::Filter(const wxString& filterText) +{ + Freeze(); + auto filter = filterText.Lower(); + auto c_text = m_filter_ctrl->GetValue().Lower(); + + if(filter == "::sel" || filter == "::nonsel"){ + if(c_text != filter){ // not text input + m_filter_ctrl->SetValue(filter); + m_filter_ctrl->SetSelection(0,-1); + } + fb_sizer->Show(false); + if (filter == "::sel") + for (auto& cb : m_checks) cb->Show(cb->GetValue()); + else + for (auto& cb : m_checks) cb->Show(!cb->GetValue()); + } + else{ + bool clear = filterText.IsEmpty(); + fb_sizer->Show(clear); + for (auto& cb : m_checks) + cb->Show(clear || cb->GetLabel().Lower().Contains(filter)); + } + + m_info->Show(); + for (size_t i = 0; i < m_list_size; ++i) { + if (m_checks[i]->IsShown()){ + m_info->Hide(); + break; + } + } + if (m_info->IsShown()) + m_info->SetLabel(filter == "::sel" ? m_info_nonsel : filter == "::nonsel" ? m_info_allsel : m_info_empty); + + m_scroll_area->FitInside(); + f_sizer->Layout(); + Thaw(); +} + +void CheckList::ShowMenu(wxMouseEvent &evt) +{ + bool filtering = !m_filter_ctrl->GetValue().IsEmpty(); + bool list_empty = m_info->IsShown(); + + wxMenu m; + m.Append(wxID_FILE1, _L("Select All" ))->Enable(!filtering); + m.Append(wxID_FILE2, _L("Deselect All"))->Enable(!filtering); + m.AppendSeparator(); + m.Append(wxID_FILE3, _L("Select visible" ))->Enable(!list_empty && filtering); + m.Append(wxID_FILE4, _L("Deselect visible"))->Enable(!list_empty && filtering); + m.AppendSeparator(); + m.Append(wxID_FILE5, _L("Filter selected" )); + m.Append(wxID_FILE6, _L("Filter nonSelected")); + + m.Bind(wxEVT_MENU, [this](wxCommandEvent& e) { + switch (e.GetId()){ + case wxID_FILE1: SelectAll(true) ; break; + case wxID_FILE2: SelectAll(false) ; break; + case wxID_FILE3: SelectVisible(true) ; break; + case wxID_FILE4: SelectVisible(false); break; + case wxID_FILE5: Filter("::sel") ; break; + case wxID_FILE6: Filter("::nonsel") ; break; + default: break; + } + },wxID_FILE1, wxID_FILE6); + + wxWindow* src = dynamic_cast(evt.GetEventObject()); + if (!src) return; + wxPoint screen_pos = src->ClientToScreen(evt.GetPosition()); + wxPoint local_pos = ScreenToClient(screen_pos); + PopupMenu(&m, local_pos); +} \ No newline at end of file diff --git a/src/slic3r/GUI/Widgets/CheckList.hpp b/src/slic3r/GUI/Widgets/CheckList.hpp new file mode 100644 index 0000000000..bd40e1ad84 --- /dev/null +++ b/src/slic3r/GUI/Widgets/CheckList.hpp @@ -0,0 +1,59 @@ +#ifndef slic3r_GUI_CHECKLIST_hpp_ +#define slic3r_GUI_CHECKLIST_hpp_ + +#include "../wxExtensions.hpp" + +#include "Label.hpp" +#include "TextInput.hpp" + +#include +#include +#include +#include + +class CheckList : public wxWindow +{ +public: + CheckList( + wxWindow* parent, + const wxArrayString& choices = wxArrayString(), + long scroll_style = wxVSCROLL + ); + + wxArrayInt GetSelections(); + void SetSelections(wxArrayInt sel_array); + void Check(int i, bool checked); + bool IsChecked(int i); + + void Filter(const wxString& filterText); + void SelectAll(bool value); + void SelectVisible(bool value); + +private: + void ShowMenu(wxMouseEvent &e); + + std::vector m_checks; + int m_list_size; + bool m_first_load; + wxBoxSizer* w_sizer; + + wxPanel* f_bar; + wxBoxSizer* f_sizer; + TextInput* m_filter_box; + wxTextCtrl* m_filter_ctrl; + wxBoxSizer* fb_sizer; + wxStaticBitmap* m_menu_button; + + wxScrolledWindow* m_scroll_area; + wxBoxSizer* s_sizer; + + wxStaticText* m_info; + wxString m_info_nonsel; + wxString m_info_allsel; + wxString m_info_empty; + + ScalableBitmap m_search; + ScalableBitmap m_menu; +}; + +#endif // !slic3r_GUI_CheckList_hpp_ diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp index d698f9f7dc..973113d0ac 100644 --- a/src/slic3r/GUI/Widgets/DropDown.cpp +++ b/src/slic3r/GUI/Widgets/DropDown.cpp @@ -167,6 +167,30 @@ bool DropDown::HasDismissLongTime() (now - dismissTime).total_milliseconds() >= 20; } +void DropDown::Popup(wxWindow *focus) +{ +#ifdef __WXGTK__ + if (!mainDropDown && m_widget) { + // Data-view cell editors can receive focus before wxGTK infers a + // native popup parent, so provide the current toplevel explicitly. + GtkWindow *transient_parent = nullptr; + for (wxWindow *win = GetParent(); win; win = win->GetParent()) { + GtkWidget *widget = static_cast(win->GetHandle()); + if (!widget) + continue; + GtkWidget *top = gtk_widget_get_toplevel(widget); + if (GTK_IS_WINDOW(top)) { + transient_parent = GTK_WINDOW(top); + break; + } + } + if (transient_parent) + gtk_window_set_transient_for(GTK_WINDOW(m_widget), transient_parent); + } +#endif + PopupWindow::Popup(focus); +} + void DropDown::paintEvent(wxPaintEvent& evt) { // depending on your system you may need to look at double-buffered dcs @@ -554,7 +578,8 @@ void DropDown::messureSize() wxWindow::SetSize(szContent); #ifdef __WXGTK__ // Gtk has a wrapper window for popup widget - gtk_window_resize (GTK_WINDOW (m_widget), szContent.x, szContent.y); + if (szContent.x > 0 && szContent.y > 0) + gtk_window_resize (GTK_WINDOW (m_widget), szContent.x, szContent.y); #endif if (!groups.empty() && subDropDown == nullptr) { subDropDown = new DropDown(items); @@ -564,11 +589,6 @@ void DropDown::messureSize() subDropDown->use_content_width = true; subDropDown->Create(GetParent()); #ifdef __WXGTK__ - // Orca: Keep the wx parent as the combobox so wxPopupTransientWindow installs - // its capture handlers on the main dropdown, but make the native GTK - // popup transient for the currently open popup to satisfy Wayland's - // xdg-shell rule that a popup's parent must be the topmost mapped popup. - gtk_window_set_transient_for(GTK_WINDOW(subDropDown->GetHandle()), GTK_WINDOW(GetHandle())); // Orca: On Wayland, while the sub holds an xdg_popup grab, motion events for // the cursor over main may not be delivered (Mutter drops motion // outside the grabbing surface). Poll on idle and synthesize a @@ -636,8 +656,11 @@ void DropDown::autoPosition() // may exceed auto drect = wxDisplay(GetParent()).GetGeometry(); if (GetPosition().y + size.y + 10 > drect.GetBottom()) { + int available_height = drect.GetBottom() - GetPosition().y - 10; + if (available_height < rowSize.y * 2) + return; if (use_content_width && count <= 15) size.x += 6; - size.y = drect.GetBottom() - GetPosition().y - 10; + size.y = available_height; wxWindow::SetSize(size); if (selection >= 0) { if (offset.y + rowSize.y * (selection + 1) > size.y) @@ -727,6 +750,13 @@ void DropDown::mouseMove(wxMouseEvent &event) drop.group = items[-index - 2].group_key; drop.need_sync = true; drop.messureSize(); +#ifdef __WXGTK__ + // wxGTK wraps popup contents in a native GtkWindow. Make the submenu + // transient for the currently mapped parent popup window before + // positioning/showing it, so wlroots/Hyprland sees the topmost parent. + if (m_widget && drop.m_widget) + gtk_window_set_transient_for(GTK_WINDOW(drop.m_widget), GTK_WINDOW(m_widget)); +#endif drop.autoPosition(); drop.paintNow(); if (!drop.IsShown()) diff --git a/src/slic3r/GUI/Widgets/DropDown.hpp b/src/slic3r/GUI/Widgets/DropDown.hpp index 639a13e526..09041e3dc0 100644 --- a/src/slic3r/GUI/Widgets/DropDown.hpp +++ b/src/slic3r/GUI/Widgets/DropDown.hpp @@ -105,6 +105,8 @@ public: bool HasDismissLongTime(); + void Popup(wxWindow *focus = nullptr) override; + protected: void Dismiss() override; diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp index 4298f9616c..0e1027cd46 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp @@ -1465,6 +1465,7 @@ bool OrcaCloudServiceAgent::load_refresh_token(std::string& out_token) if (payload.rfind("v2:", 0) == 0) { auto delim = payload.find(':', 3); if (delim == std::string::npos) { + BOOST_LOG_TRIVIAL(warning) << "payload missing delim ':'."; integrity_ok = false; } else { std::string stored_hmac = payload.substr(3, delim - 3); @@ -1783,7 +1784,8 @@ int OrcaCloudServiceAgent::http_get(const std::string& path, std::string* respon std::string url = api_base_url + path; BOOST_LOG_TRIVIAL(trace) << "OrcaCloudServiceAgent: GET " << url; - ensure_token_fresh("http_get_" + path); + if (!ensure_token_fresh("http_get_" + path)) + BOOST_LOG_TRIVIAL(warning) << "ensure_token_fresh returned false"; struct HttpResult { bool success{false}; @@ -1815,8 +1817,9 @@ int OrcaCloudServiceAgent::http_get(const std::string& path, std::string* respon }) .on_error([&](std::string body, std::string error, unsigned resp_status) { result.success = false; - result.status = resp_status; - result.body = body; + result.status = resp_status == 0 ? 404 : resp_status; + result.body = body; + BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP error - " << error; }) .timeout_max(30) .perform_sync(); @@ -1884,8 +1887,9 @@ int OrcaCloudServiceAgent::http_post(const std::string& path, const std::string& }) .on_error([&](std::string resp_body, std::string error, unsigned resp_status) { result.success = false; - result.status = resp_status; - result.body = resp_body; + result.status = resp_status == 0 ? 404 : resp_status; + result.body = body; + BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP error - " << error; }) .timeout_max(30) .perform_sync(); @@ -1953,8 +1957,9 @@ int OrcaCloudServiceAgent::http_put(const std::string& path, const std::string& }) .on_error([&](std::string resp_body, std::string error, unsigned resp_status) { result.success = false; - result.status = resp_status; - result.body = resp_body; + result.status = resp_status == 0 ? 404 : resp_status; + result.body = body; + BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP error - " << error; }) .timeout_max(30) .perform_sync(); @@ -2019,8 +2024,9 @@ int OrcaCloudServiceAgent::http_delete(const std::string& path, std::string* res }) .on_error([&](std::string resp_body, std::string error, unsigned resp_status) { result.success = false; - result.status = resp_status; - result.body = resp_body; + result.status = resp_status == 0 ? 404 : resp_status; + result.body = resp_body; + BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP error - " << error; }) .timeout_max(30) .perform_sync(); @@ -2101,7 +2107,7 @@ bool OrcaCloudServiceAgent::http_post_token(const std::string& body, std::string }) .on_error([&](std::string body, std::string error, unsigned resp_status) { success = false; - status = resp_status; + status = resp_status == 0 ? 404 : resp_status; resp_body = body; BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP error - " << error; }) @@ -2171,7 +2177,7 @@ bool OrcaCloudServiceAgent::http_post_auth(const std::string& path, const std::s }) .on_error([&](std::string body, std::string error, unsigned resp_status) { success = false; - status = resp_status; + status = resp_status == 0 ? 404 : resp_status; resp_body = body; BOOST_LOG_TRIVIAL(error) << "OrcaCloudServiceAgent: HTTP (auth) error - " << error; })