diff --git a/bbl/i18n/BambuStudio.pot b/bbl/i18n/BambuStudio.pot index 41cc462563..cc3a4f49b8 100644 --- a/bbl/i18n/BambuStudio.pot +++ b/bbl/i18n/BambuStudio.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -366,6 +366,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "" + msgid "Notice" msgstr "" @@ -629,9 +644,6 @@ msgstr "" msgid "Cone" msgstr "" -msgid "Timelapse Wipe Tower" -msgstr "" - msgid "Add settings" msgstr "" @@ -1201,6 +1213,9 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" msgstr "" @@ -1320,6 +1335,18 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" msgstr "" @@ -1777,9 +1804,6 @@ msgstr "" msgid "Display" msgstr "" -msgid "Line type" -msgstr "" - msgid "Layer Height (mm)" msgstr "" @@ -1867,6 +1891,9 @@ msgstr "" msgid "Normal mode" msgstr "" +msgid "Cost" +msgstr "" + msgid "Prepare time" msgstr "" @@ -1921,9 +1948,6 @@ msgstr "" msgid "Avoid extrusion calibration region" msgstr "" -msgid "Add" -msgstr "" - msgid "Add plate" msgstr "" @@ -2031,6 +2055,15 @@ msgstr "" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "" + +msgid "Online" +msgstr "" + +msgid "Offline" +msgstr "" + msgid "Application is closing" msgstr "" @@ -2052,6 +2085,9 @@ msgstr "" msgid "Project" msgstr "" +msgid "Debug" +msgstr "" + msgid "Slice" msgstr "" @@ -2089,6 +2125,12 @@ msgstr "" msgid "&About %s" msgstr "" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "" @@ -2160,9 +2202,24 @@ msgstr "" msgid "Load a model" msgstr "" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "" @@ -2172,6 +2229,12 @@ msgstr "" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "" @@ -2238,27 +2301,12 @@ msgstr "" msgid "Preferences" msgstr "" -msgid "About" -msgstr "" - msgid "View" msgstr "" msgid "Help" msgstr "" -msgid "&File" -msgstr "" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "" - -msgid "&Help" -msgstr "" - msgid "&Open G-code" msgstr "" @@ -2290,7 +2338,47 @@ msgstr "" msgid "Quit %s" msgstr "" -msgid "Save configuration as:" +msgid "&File" +msgstr "" + +msgid "&View" +msgstr "" + +msgid "&Help" +msgstr "" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" msgstr "" msgid "File is missing" @@ -2336,46 +2424,92 @@ msgstr "" msgid "Load failed [%d]!" msgstr "" -msgid "3Dconnexion settings" +msgid "Year" msgstr "" -msgid "Device:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" msgstr "" msgid "Speed:" msgstr "" -msgid "Translation" -msgstr "" - -msgid "Zoom" -msgstr "" - msgid "Deadzone:" msgstr "" msgid "Options:" msgstr "" +msgid "Zoom" +msgstr "" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "" + msgid "Swap Y/Z axes" msgstr "" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "" -msgid "Report" +msgid "Resume" msgstr "" msgid "Stop" msgstr "" -msgid "0%" +msgid "0" msgstr "" msgid "Clean" @@ -2414,9 +2548,6 @@ msgstr "" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "" - msgid "Silent" msgstr "" @@ -2447,9 +2578,6 @@ msgstr "" msgid "Failed to connect to the printer" msgstr "" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "" @@ -2483,9 +2611,6 @@ msgstr "" msgid "%s information" msgstr "" -msgid "Download" -msgstr "" - msgid "Skip" msgstr "" @@ -2674,9 +2799,6 @@ msgstr "" msgid "Used Materials" msgstr "" -msgid "Cost" -msgstr "" - msgid "Estimated time" msgstr "" @@ -2733,6 +2855,12 @@ msgstr "" msgid "Newer 3mf version" msgstr "" +#, possible-c-format, possible-boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -3247,12 +3375,6 @@ msgstr "" msgid "Simply switch to \"%1%\"" msgstr "" -msgid "Online" -msgstr "" - -msgid "Offline" -msgstr "" - msgid "My Device" msgstr "" @@ -3392,6 +3514,15 @@ msgstr "" msgid "Delete this preset" msgstr "" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3519,6 +3650,14 @@ msgid "" "filament does not support to print on the High Temp Plate" msgstr "" +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Volumetric speed limitation" msgstr "" @@ -3725,6 +3864,12 @@ msgstr "" msgid "Capabilities" msgstr "" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "" @@ -3750,7 +3895,7 @@ msgstr "" msgid "Choose files" msgstr "" -msgid "Designer" +msgid "Author" msgstr "" msgid "Model Name" @@ -3851,6 +3996,9 @@ msgstr "" msgid "Paste from clipboard" msgstr "" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "" @@ -3989,6 +4137,9 @@ msgstr "" msgid "Support/Color Painting: adjust pen radius" msgstr "" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "" @@ -4467,6 +4618,11 @@ msgid "" "filament does not support to print on the High Temp Plate" msgstr "" +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Initial layer" msgstr "" @@ -4488,6 +4644,11 @@ msgid "" "support to print on the High Temp Plate" msgstr "" +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" + msgid "Bed types supported by the printer" msgstr "" @@ -5453,6 +5614,9 @@ msgstr "" msgid "Back" msgstr "" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "" @@ -5497,10 +5661,12 @@ msgid "" msgstr "" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" msgid "Temperature variation" @@ -5650,8 +5816,7 @@ msgstr "" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" msgid "Threshold angle" @@ -5941,7 +6106,13 @@ msgstr "" #, possible-c-format, possible-boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" msgid "Optimizing toolpath" @@ -5950,10 +6121,7 @@ msgstr "" msgid "Empty layers around bottom are replaced by nearest normal layers." msgstr "" -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" msgid "Slicing mesh" diff --git a/bbl/i18n/de/BambuStudio_de.po b/bbl/i18n/de/BambuStudio_de.po index a47d247b74..f2e545338b 100644 --- a/bbl/i18n/de/BambuStudio_de.po +++ b/bbl/i18n/de/BambuStudio_de.po @@ -2,13 +2,16 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Localazy (https://localazy.com)\n" "Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" +"X-Generator: Poedit 3.1\n" msgid "Supports Painting" msgstr "Supports aufmalen" @@ -74,7 +77,7 @@ msgid "Sphere" msgstr "Kugel" msgid "Fill" -msgstr "Ausfüllen" +msgstr "Fill" msgid "Gap Fill" msgstr "" @@ -96,9 +99,9 @@ msgid "" "Filament count exceeds the maximum number that painting tool supports. only " "the first %1% filaments will be available in painting tool." msgstr "" -"Die Anzahl der Filamente übersteigt die maximale Anzahl, die das Malwerkzeug " -"unterstützt. Nur die ersten %1% der Filamente werden im Malwerkzeug " -"verfügbar sein." +"Die Anzahl der Materialien übersteigt die maximale Anzahl, die das " +"Malwerkzeug unterstützt. Nur die ersten %1% der Materialien werden im " +"Malwerkzeug verfügbar sein." msgid "Color Painting" msgstr "Farben malen" @@ -116,7 +119,7 @@ msgid "Key 1~9" msgstr "Schlüssel 1~9" msgid "Choose filament" -msgstr "Filament wählen" +msgstr "Wähle Material" msgid "Edge detection" msgstr "Kantenerkennung" @@ -125,7 +128,7 @@ msgid "Triangles" msgstr "Dreiecke" msgid "Filaments" -msgstr "Filamente" +msgstr "Materialien" msgid "Brush" msgstr "Pinsel" @@ -143,17 +146,17 @@ msgid "Shortcut Key " msgstr "Shortcut Taste " msgid "Triangle" -msgstr "Dreieck" +msgstr "Triangle" msgid "Height Range" -msgstr "Höhenreichweite" +msgstr "Height Range" msgid "Remove painted color" msgstr "Gemalte Farbe entfernen" #, boost-format msgid "Painted using: Filament %1%" -msgstr "Gemalt mit: Filament %1%" +msgstr "Gemalt mit: Material %1%" msgid "Move" msgstr "Bewegen" @@ -186,7 +189,7 @@ msgid "Position" msgstr "Position" msgid "Rotation" -msgstr "Drehung" +msgstr "Rotation" msgid "Scale ratios" msgstr "Skalierungsverhältnisse" @@ -240,7 +243,7 @@ msgid "Movement:" msgstr "Bewegung:" msgid "Rotation:" -msgstr "Drehung:" +msgstr "Rotation:" msgid "Height:" msgstr "Höhe:" @@ -301,7 +304,7 @@ msgid "High" msgstr "Hoch" msgid "Medium" -msgstr "Mittel" +msgstr "Medium" msgid "Low" msgstr "Niedrig" @@ -330,10 +333,10 @@ msgid "Operation already cancelling. Please wait few seconds." msgstr "Operation wird bereits abgebrochen. Bitte warten Sie einige Sekunden." msgid "Face recognition" -msgstr "Gesichtserkennung" +msgstr "Face recognition" msgid "Perform Recognition" -msgstr "Erkennung durchführen" +msgstr "Perform Recognition" msgid "Reset direction" msgstr "" @@ -365,6 +368,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Hinzufügen" + msgid "Notice" msgstr "Hinweis" @@ -390,7 +408,7 @@ msgid "Process" msgstr "Prozess" msgid "Filament" -msgstr "Filament" +msgstr "Material" msgid "Machine" msgstr "Maschine" @@ -480,7 +498,7 @@ msgid "This is the newest version." msgstr "Das ist die aktuellste Version." msgid "Info" -msgstr "Infos" +msgstr "Info" msgid "Loading user presets..." msgstr "Nutzervoreistellungen laden..." @@ -526,8 +544,8 @@ msgid "" "The version of Bambu studio is too low and needs to be updated to the latest " "version before it can be used normally" msgstr "" -"Die Version von Bambu Studio ist zu niedrig und muss auf die neueste Version " -"aktualisiert werden, bevor sie normal verwendet werden kann" +"The version of Bambu Studio is too low and needs to be updated to the latest " +"version before it can be used normally" msgid "Login information expired. Please login again." msgstr "Login abgelaufen. Bitte neu einloggen." @@ -536,7 +554,7 @@ msgid "Loading" msgstr "Lade" msgid "Loading user preset" -msgstr "Benutzervoreinstellung wird geladen" +msgstr "Loading user preset" msgid "Switching application language" msgstr "Wechsel der Sprache" @@ -554,7 +572,7 @@ msgid "Select a G-code file:" msgstr "Wähle eine G-Code Datei:" msgid "Bambu Studio GUI initialization failed" -msgstr "Initialisierung der Bambu Studio GUI ist fehlgeschlagen" +msgstr "Bambu Studio GUI initialization failed" #, boost-format msgid "Fatal error, exception catched: %1%" @@ -567,7 +585,7 @@ msgid "Shell" msgstr "Schale" msgid "Infill" -msgstr "Füllung" +msgstr "Infill" msgid "Support" msgstr "Support" @@ -591,7 +609,7 @@ msgid "Bottom Minimum Shell Thickness" msgstr "Minimale Dicke der unteren Schichten" msgid "Ironing" -msgstr "glätten" +msgstr "Ironing" msgid "Fuzzy Skin" msgstr "Fuzzy Skin" @@ -647,9 +665,6 @@ msgstr "Zylinder" msgid "Cone" msgstr "Kegel" -msgid "Timelapse Wipe Tower" -msgstr "Zeitraffer-Wischturm" - msgid "Add settings" msgstr "Einstellungen hinzufügen" @@ -681,17 +696,17 @@ msgid "Reload items" msgstr "Elemente neu laden" msgid "Change filament" -msgstr "Filament wechseln" +msgstr "Material wechseln" msgid "Set filament for selected items" -msgstr "Filament für ausgewählte Elemente festlegen" +msgstr "Material für ausgewählte Objekte festlegen" msgid "Default" msgstr "Standard" #, c-format, boost-format msgid "Filament %d" -msgstr "Filament %d" +msgstr "Material %d" msgid "active" msgstr "aktiv" @@ -825,10 +840,10 @@ msgid "Edit print parameters for a single object" msgstr "Druckparameter für ein einzelnes Objekt bearbeiten" msgid "Change Filament" -msgstr "Filament wechseln" +msgstr "Material ändern" msgid "Set Filament for selected items" -msgstr "Filament für ausgewählte Elemente festlegen" +msgstr "Materialfür ausgewählte Teile festlegen" msgid "current" msgstr "aktuell" @@ -1030,7 +1045,7 @@ msgid "Wall loops" msgstr "Wandschleifen" msgid "Infill density(%)" -msgstr "Füllungsdichte(%)" +msgstr "Infill-Dichte(%)" msgid "Auto Brim" msgstr "Automatische Umrandung" @@ -1063,16 +1078,16 @@ msgid "Heat the nozzle to target temperature" msgstr "" msgid "Cut filament" -msgstr "Material abschneiden" +msgstr "Material schneiden" msgid "Pull back current filament" -msgstr "Ziehen Sie das aktuelle Filament zurück" +msgstr "Aktuelles Material zurückziehen" msgid "Push new filament into extruder" msgstr "" msgid "Purge old filament" -msgstr "Altes Filament entfernen" +msgstr "Purge old filament" msgid "?" msgstr "?" @@ -1081,13 +1096,13 @@ msgid "Empty" msgstr "Leer" msgid "Click the pencil icon to edit the filament." -msgstr "Das Stift-Symbol drücken um das Filament zu bearbeiten." +msgstr "Das Stift-Symbol drücken um das Material zu bearbeiten." msgid "Load Filament" -msgstr "Laden" +msgstr "Load" msgid "Unload Filament" -msgstr "Entladen" +msgstr "Unload" msgid "Tips" msgstr "Tipps" @@ -1114,7 +1129,7 @@ msgid "" "load or unload filiament." msgstr "" "Wählen Sie einen AMS-Slot und drücken Sie dann die Taste \"Laden\" oder " -"\"Entladen\", um automatisch Filament zu laden oder zu entladen." +"\"Entladen\", um automatisch Material zu laden oder zu entladen." msgid "Edit" msgstr "Bearbeiten" @@ -1197,65 +1212,62 @@ msgid "Exception" msgstr "Ausnahme" msgid "Logging in" -msgstr "Einloggen" +msgstr "Logging in" msgid "Login failed" -msgstr "Anmeldung fehlgeschlagen" +msgstr "Login failed" msgid "The region parameter is incorrrect" -msgstr "Der Regionsparameter ist falsch." +msgstr "The region parameter is incorrrect." msgid "Failure of printer login" -msgstr "Druckeranmeldung fehlgeschlagen" +msgstr "Printer login failure" msgid "Failed to get ticket" -msgstr "Ticket konnte nicht abgerufen werden" +msgstr "Failed to get ticket" msgid "User authorization timeout" -msgstr "Zeitüberschreitung der Benutzerautorisierung" +msgstr "User authorization timeout" msgid "Failure of bind" -msgstr "Bindungsfehler" +msgstr "Binding failure" msgid "Unknown Failure" -msgstr "Unbekannter Fehler" +msgstr "Unknown Failure" msgid "Abnormal print file data. Please slice again" -msgstr "Abnormale Daten in der Druckdatei. Bitte slicen Sie erneut" +msgstr "Abnormal print file data. Please slice again" msgid "Task canceled" -msgstr "Auftrag abgebrochen" +msgstr "Task canceled" msgid "Upload task timed out. Please check the network problem and try again" -msgstr "" -"Upload-Aufgabe wurde abgebrochen. Bitte überprüfen Sie das Netzwerkproblem " -"und versuchen Sie es erneut" +msgstr "Upload task timed out. Please check the network and try again" msgid "Cloud service connection failed. Please try again." -msgstr "" -"Die Verbindung zum Cloud-Dienst ist fehlgeschlagen. Bitte versuche es erneut." +msgstr "Cloud service connection failed. Please try again." msgid "Print file not found, please slice again" -msgstr "Druckdatei nicht gefunden, bitte noch einmal probieren (erneut Slicen)" +msgstr "Print file not found, please slice again" msgid "" "The print file exceeds the maximum allowable size (1GB). Please simplify the " "model and slice again" msgstr "" -"Die Druckdatei überschreitet die maximal zulässige Größe (1 GB). Bitte " -"vereinfachen Sie das Modell und slicen Sie es erneut" +"The print file exceeds the maximum allowable size (1GB). Please simplify the " +"model and slice again" msgid "Failed uploading print file" -msgstr "Fehler beim Hochladen der Druckdatei" +msgstr "Failed uploading print file" msgid "Wrong Access code" -msgstr "Falscher Zugangscode" +msgstr "Wrong Access code" msgid "Sending print job over LAN" -msgstr "Druckauftrag über LAN senden" +msgstr "Sending print job over LAN" msgid "Sending print job through cloud service" -msgstr "Druckauftrag über den Cloud-Dienst senden" +msgstr "Sending print job through cloud service" msgid "Service Unavailable" msgstr "" @@ -1263,8 +1275,11 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" -msgstr "Druckkonfiguration senden" +msgstr "Sending print configuration" #, c-format, boost-format msgid "Successfully sent. Will automatically jump to the device page in %s s" @@ -1301,7 +1316,7 @@ msgid "License" msgstr "Lizenz" msgid "Bambu Studio is licensed under " -msgstr "Bambu Studio ist lizenziert unter " +msgstr "Bambu Studio is licensed under " msgid "GNU Affero General Public License, version 3" msgstr "GNU Affero General Public License, Version 3" @@ -1310,18 +1325,18 @@ msgid "" "Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " "by Alessandro Ranellucci and the RepRap community" msgstr "" -"Bambu Studio basiert auf PrusaSlicer von Prusa Research, das von Slic3r von " -"Alessandro Ranellucci und der RepRap Community stammt." +"Bambu Studio is based on PrusaSlicer by Prusa Research, which is based on " +"Slic3r by Alessandro Ranellucci and the RepRap community" msgid "Libraries" -msgstr "Bibliotheken" +msgstr "Libraries" msgid "" "This software uses open source components whose copyright and other " "proprietary rights belong to their respective owners" msgstr "" -"Diese Software verwendet Open-Source-Komponenten, deren Urheberrechte und " -"andere Eigentumsrechte den jeweiligen Eigentümern gehören." +"This software uses open source components whose copyright and other " +"proprietary rights belong to their respective owners" #, c-format, boost-format msgid "About %s" @@ -1353,12 +1368,14 @@ msgid "AMSMaterialsSetting" msgstr "" msgid "Colour" -msgstr "Farbe" +msgstr "Color" msgid "" "Nozzle\n" "Temperature" -msgstr "Druckdüsentemperatur" +msgstr "" +"Nozzle\n" +"Temperature" msgid "max" msgstr "max" @@ -1368,7 +1385,7 @@ msgstr "min" #, boost-format msgid "The input value should be greater than %1% and less than %2%" -msgstr "Der Eingabewert sollte größer als %1% und kleiner als %2% sein" +msgstr "The input value should be greater than %1% and less than %2%" msgid "SN" msgstr "SN" @@ -1386,52 +1403,62 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" -msgstr "Update einfügen" +msgstr "Insertion update" msgid "" "The AMS will automatically read the filament information when inserting a " "new Bambu Lab filament. This takes about 20 seconds." msgstr "" -"Die AMS liest automatisch die Filamentinformationen, wenn ein neues Bambu " -"Lab Filament eingesetzt wird. Dies dauert etwa 20 Sekunden." +"The AMS will automatically read the filament information when inserting a " +"new Bambu Lab filament spool. This takes about 20 seconds." msgid "" "Note: if new filament is inserted during printing, the AMS will not " "automatically read any information until printing is completed." msgstr "" -"Hinweis: Wenn während des Drucks neues Filament eingelegt wird, liest das " -"AMS nicht automatisch Informationen ein, bis der Druckvorgang abgeschlossen " -"ist." +"Note: if new filament is inserted during printing, the AMS will not " +"automatically read any information until printing has finished." msgid "" "When inserting a new filament, the AMS will not automatically read its " "information, leaving it blank for you to enter manually." msgstr "" -"Hinweis: Wenn während des Drucks neues Filament eingelegt wird, liest das " -"AMS nicht automatisch Informationen ein, bis der Druckvorgang abgeschlossen " -"ist." +"When inserting a new filament, the AMS will not automatically read its " +"information, leaving it blank for you to enter manually." msgid "Power on update" -msgstr "Update beim einschalten" +msgstr "Power on update" msgid "" "The AMS will automatically read the information of inserted filament on " "start-up. It will take about 1 minute.The reading process will roll filament " "spools." msgstr "" -"Das AMS liest beim Einschalten automatisch die Informationen über das " -"eingelegte Filament. Der Lesevorgang dauert ca. 1 Minute und lässt die " -"Filamentspulen rotieren." +"The AMS will automatically read the information of inserted filament on " +"start-up. It will take about 1 minute.The reading process will rotate the " +"filament spools." msgid "" "The AMS will not automatically read information from inserted filament " "during startup and will continue to use the information recorded before the " "last shutdown." msgstr "" -"Das AMS liest beim Start nicht automatisch Informationen vom eingesetzten " -"Filament und verwendet weiterhin die vor dem letzten Herunterfahren " -"aufgezeichneten Informationen." +"The AMS will not automatically read information from inserted filament " +"during startup and will continue to use the information recorded before the " +"last shutdown." msgid "File" msgstr "Datei" @@ -1609,7 +1636,7 @@ msgid "" "This may cause nozzle blocked and printing failure" msgstr "" "Die Temperatur des Druckbett ist höher als die Verglasungstemperatur dieses " -"Filaments.\n" +"Materials.\n" "Dies kann zu einer Verstopfung der Düse und zu Druckfehlern führen" msgid "" @@ -1676,9 +1703,10 @@ msgid "" "Spiral mode only works when wall loops is 1, \n" "support is disabled, top shell layers is 0 and sparse infill density is 0\n" msgstr "" -"Der Spiralmodus funktioniert nur, wenn die Wand 1 Linienweite breit sind, \n" -"Support ist deaktiviert, die oberen Schalenschichten sind 0 und die Dichte " -"der Füllung ist 0\n" +"Der Spiralmodus funktioniert nur, wenn die Wandschleifen 1 Linienweite breit " +"sind, \n" +"Support idt deaktiviert, die oberen Schalenschichten sind 0 und die Dichte " +"der dünnen Füllung ist 0\n" msgid "" "Change these settings automatically? \n" @@ -1740,67 +1768,67 @@ msgstr "" "zurück\n" msgid "Auto bed leveling" -msgstr "Automatische Druckbettnivellierung" +msgstr "Auto bed leveling" msgid "Heatbed preheating" -msgstr "Heizbett vorheitzen" +msgstr "Heatbed preheating" msgid "Sweeping XY mech mode" -msgstr "Säubern von XY mechanisch Modus" +msgstr "Sweeping XY mech mode" msgid "Changing filament" -msgstr "Filament wechseln" +msgstr "Changing filament" msgid "M400 pause" -msgstr "M400 Pause" +msgstr "M400 pause" msgid "Paused due to filament runout" -msgstr "Angehalten wegen Filament-Auslauf" +msgstr "Paused due to filament runout" msgid "Heating hotend" -msgstr "Heizen des Hotend" +msgstr "Heating hotend" msgid "Calibrating extrusion" -msgstr "Kalibrierung der Extrusion" +msgstr "Calibrating extrusion" msgid "Scanning bed surface" -msgstr "Scan der Druckbettoberfläche" +msgstr "Scanning bed surface" msgid "Inspecting first layer" -msgstr "Überprüfung der ersten Schicht" +msgstr "Inspecting first layer" msgid "Identifying build plate type" -msgstr "Identifikation der Bauplatte" +msgstr "Identifying build plate type" msgid "Calibrating Micro Lidar" -msgstr "Kalibrierung des Mikro-Lidars" +msgstr "Calibrating Micro Lidar" msgid "Homing toolhead" -msgstr "Homing des Werkzeugkopfes" +msgstr "Homing toolhead" msgid "Cleaning nozzle tip" -msgstr "Reinigen der Druckdüsenspitze" +msgstr "Cleaning nozzle tip" msgid "Checking extruder temperature" -msgstr "Überprüfen der Extruder Temperatur" +msgstr "Checking extruder temperature" msgid "Printing was paused by the user" -msgstr "Der Druckvorgang wurde vom Benutzer angehalten" +msgstr "Printing was paused by the user" msgid "Pause of front cover falling" -msgstr "Pause, da die Abdeckung des Werkzeugkopfes abgefallen ist" +msgstr "Pause of front cover falling" msgid "Calibrating the micro lida" -msgstr "Kalibrierung des Mikro-Lidars" +msgstr "Calibrating the micro lidar" msgid "Calibrating extrusion flow" -msgstr "Kalibrieren des Materialflusses" +msgstr "Calibrating extrusion flow" msgid "Paused due to nozzle temperature malfunction" -msgstr "Pausiert aufgrund einer Fehlfunktion der Düsentemperatur" +msgstr "Paused due to nozzle temperature malfunction" msgid "Paused due to heat bed temperature malfunction" -msgstr "Pausiert aufgrund einer Fehlfunktion der Heizbetttemperatur" +msgstr "Paused due to heat bed temperature malfunction" msgid "MC" msgstr "MC" @@ -1933,10 +1961,7 @@ msgid "Time" msgstr "Zeit" msgid "Display" -msgstr "Anzeigen" - -msgid "Line type" -msgstr "Linientyp" +msgstr "Display" msgid "Layer Height (mm)" msgstr "Schichthöhe (mm)" @@ -1957,10 +1982,10 @@ msgid "Volumetric flow rate (mm³/s)" msgstr "Volumetrische Flussrate (mm³/s)" msgid "Used filament" -msgstr "Genutztes Filament" +msgstr "Genutztes Material" msgid "Filament N XX" -msgstr "Filament N XX" +msgstr "Material N XX" msgid "Color Print" msgstr "Farbdruck" @@ -1981,7 +2006,7 @@ msgid "Unretract" msgstr "Auseinzug" msgid "Filament Changes" -msgstr "Filamentwechsel" +msgstr "Materialwechsel" msgid "Wipe" msgstr "Reinigen" @@ -1996,13 +2021,13 @@ msgid "Extruder" msgstr "Extruder" msgid "Filament 1" -msgstr "Filament 1" +msgstr "Material 1" msgid "Flushed filament" -msgstr "gereinigtes Filament" +msgstr "Flushed filament" msgid "Filament change times" -msgstr "Filamentwechselzeiten" +msgstr "Filament change times" msgid "Color change" msgstr "Farbwechsel" @@ -2025,6 +2050,9 @@ msgstr "Gesamtvorhersage" msgid "Normal mode" msgstr "Normaler Modus" +msgid "Cost" +msgstr "Kosten" + msgid "Prepare time" msgstr "Vorbereitungszeit" @@ -2079,9 +2107,6 @@ msgstr "Erlaube mehrere Materialien auf einer Druckplatte" msgid "Avoid extrusion calibration region" msgstr "Vermeiden Sie den Bereich der Extrusionskalibrierung" -msgid "Add" -msgstr "Hinzufügen" - msgid "Add plate" msgstr "Druckplatte hinzufügen" @@ -2110,7 +2135,7 @@ msgid "Assembly Return" msgstr "Zurücksetzen der Montage" msgid "return" -msgstr "Zurück" +msgstr "return" msgid "Paint Toolbar" msgstr "Malwerkzeuge" @@ -2156,8 +2181,9 @@ msgid "" "minimize deviation.\n" "It keeps the device performing optimally." msgstr "" -"Das Kalibrierungsprogramm erkennt den Status Ihres Geräts automatisch, um " -"Abweichungen zu minimieren. Es sorgt für eine optimale Leistung des Geräts." +"The calibration program detects the status of your device automatically to " +"minimize deviation.\n" +"It keeps the device performing optimally." msgid "Calibration Flow" msgstr "Flusskalibrierung" @@ -2175,24 +2201,33 @@ msgid "Timelapse" msgstr "Zeitraffer" msgid "Monitoring Recording" -msgstr "Überwachung der Aufzeichnung" +msgstr "Monitoring Recording" msgid "ConnectPrinter(LAN)" -msgstr "Drucker anschließen (LAN)" +msgstr "Connect Printer (LAN)" msgid "Please input the printer access code:" -msgstr "Bitte geben Sie den Zugangscode zum Drucker ein:" +msgstr "Please input the printer access code:" msgid "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" msgstr "" -"Sie finden ihn unter \"Einstellungen > Netzwerk > Verbindungscode\".\n" -"auf dem Drucker, wie in der Abbildung gezeigt:" +"You can find it in \"Settings > Network > Connection code\"\n" +"on the printer, as shown in the figure:" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Suchbegriff eingeben" + +msgid "Online" +msgstr "Online" + +msgid "Offline" +msgstr "Offline" + msgid "Application is closing" msgstr "Anwendung schließt" @@ -2210,11 +2245,14 @@ msgid "Preview" msgstr "Vorschau" msgid "Device" -msgstr "Gerät" +msgstr "Device" msgid "Project" msgstr "Projekt" +msgid "Debug" +msgstr "Debuggen" + msgid "Slice" msgstr "Slice" @@ -2252,6 +2290,12 @@ msgstr "Prüfen auf Update" msgid "&About %s" msgstr "&Über %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Standardansicht" @@ -2323,9 +2367,24 @@ msgstr "Importiere 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Lade ein Modell" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "Alle Objekte als STL exportieren" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Aktuelle geslicete Datei exportieren" @@ -2335,6 +2394,12 @@ msgstr "Exportiere G-Code" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exportieren" @@ -2401,27 +2466,12 @@ msgstr "Orthogonale Ansicht verwenden" msgid "Preferences" msgstr "Vorlieben" -msgid "About" -msgstr "" - msgid "View" msgstr "Ansicht" msgid "Help" msgstr "Hilfe" -msgid "&File" -msgstr "&Datei" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&Anzeige" - -msgid "&Help" -msgstr "&Hilfe" - msgid "&Open G-code" msgstr "Öffne G-C&ode" @@ -2453,8 +2503,48 @@ msgstr "&Beenden" msgid "Quit %s" msgstr "%s verlassen" -msgid "Save configuration as:" -msgstr "Konfiguration speichern unter:" +msgid "&File" +msgstr "&Datei" + +msgid "&View" +msgstr "&Anzeige" + +msgid "&Help" +msgstr "&Hilfe" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Datei fehlt" @@ -2463,7 +2553,7 @@ msgid "The project is no longer available." msgstr "Das Projekt ist nicht mehr verfügbar." msgid "Filament Settings" -msgstr "Filamenteinstellungen" +msgstr "Materialeinstellungen" msgid "" "Do you want to synchronize your personal data from Bambu Cloud? \n" @@ -2499,53 +2589,99 @@ msgstr "Laufend..." msgid "Load failed [%d]!" msgstr "Laden fehlgeschlagen [%d]!" -msgid "3Dconnexion settings" -msgstr "3Dconnexion Einstellungen" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Gerät:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Download" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Waiting" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Fertig" msgid "Speed:" msgstr "Geschwindigkeit:" -msgid "Translation" -msgstr "Übersetzung" - -msgid "Zoom" -msgstr "Vergrößern" - msgid "Deadzone:" msgstr "Todeszone:" msgid "Options:" msgstr "Optionen:" +msgid "Zoom" +msgstr "Zoom" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion Einstellungen" + msgid "Swap Y/Z axes" msgstr "Y/Z-Achsen vertauschen" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Druckprozess" -msgid "Report" -msgstr "Bericht" +msgid "Resume" +msgstr "Fortsetzen" msgid "Stop" msgstr "Stop" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" msgid "Control" -msgstr "Steuerung" +msgstr "Control" msgid "Print Options" msgstr "" @@ -2577,9 +2713,6 @@ msgstr "Druckliste" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Fortsetzen" - msgid "Silent" msgstr "Leise" @@ -2610,9 +2743,6 @@ msgstr "Verbindung zum Server fehlgeschlagen" msgid "Failed to connect to the printer" msgstr "Verbindung zum Drucker fehlgeschlagen" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "OK" @@ -2646,9 +2776,6 @@ msgstr "%s Info" msgid "%s information" msgstr "%s Information" -msgid "Download" -msgstr "Herunterladen" - msgid "Skip" msgstr "Überspringen" @@ -2719,7 +2846,7 @@ msgid "Warning:" msgstr "Warnung:" msgid "Export ok." -msgstr "Exportieren ok." +msgstr "Export ok." msgid " (Repair)" msgstr " (Reparatur)" @@ -2807,7 +2934,7 @@ msgid "Objects" msgstr "Objekte" msgid "Advance" -msgstr "Fortgeschritten" +msgstr "Fortfahren" msgid "Compare presets" msgstr "Voreinstellungen vergleichen" @@ -2816,7 +2943,7 @@ msgid "View all object's settings" msgstr "Alle Einstellungen des Objekts anzeigen" msgid "Filament settings" -msgstr "Filamenteinstellungen" +msgstr "Material-Einstellungen" msgid "Printer settings" msgstr "Drucker-Einstellungen" @@ -2832,25 +2959,22 @@ msgid "Sliced Info" msgstr "Slice-Info" msgid "Used Filament (m)" -msgstr "Filamentbedarf (Meter)" +msgstr "Materialbedarf (Meter)" msgid "Used Filament (mm³)" -msgstr "Filamentbedarf (mm³)" +msgstr "Materialbedarf (mm³)" msgid "Used Filament (g)" -msgstr "Filamentbedarf (g)" +msgstr "Materialbedarf (g)" msgid "Used Materials" msgstr "Genutztes Material" -msgid "Cost" -msgstr "Kosten" - msgid "Estimated time" msgstr "Geschätzte Zeit" msgid "Filament changes" -msgstr "Filamentwechsel" +msgstr "Materialwechsel" msgid "Click to edit preset" msgstr "Klicken zum Bearbeiten der Voreinstellung" @@ -2859,7 +2983,7 @@ msgid "Bed type" msgstr "Druckbetttyp" msgid "Flushing volumes" -msgstr "Säuberungsvolumen" +msgstr "Spülvolumen" msgid "Untitled" msgstr "Unbenannt" @@ -2906,6 +3030,12 @@ msgstr "Sie sollten Ihre Software aktualisieren.\n" msgid "Newer 3mf version" msgstr "Neuere 3mf-Version" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -2952,7 +3082,7 @@ msgid "Object with multiple parts was detected" msgstr "Objekt mit mehreren Teilen wurde entdeckt" msgid "The file does not contain any geometry data." -msgstr "Die Datei enthält keine Geometriedaten." +msgstr "The file does not contain any geometry data." msgid "" "Your object appears to be too large, Do you want to scale it down to fit the " @@ -3047,10 +3177,10 @@ msgid "G-code files can not be loaded with models together!" msgstr "G-Code-Dateien können nicht mit Modellen zusammen geladen werden!" msgid "Can not add models when in preview mode!" -msgstr "Modelle können im Vorschaumodus nicht hinzugefügt werden" +msgstr "Unable to add models in preview mode" msgid "Add Models" -msgstr "Modelle hinzufügen" +msgstr "Add Models" msgid "All objects will be removed, continue?" msgstr "Alle Objekte werden entfernt, fortfahren?" @@ -3115,7 +3245,7 @@ msgstr "Größe: %1% x %2% x %3% mm\n" #, boost-format msgid "Volume: %1% in³\n" -msgstr "Volumen: %1% in³\n" +msgstr "Volume: %1% in³\n" #, boost-format msgid "Volume: %1% mm³\n" @@ -3143,34 +3273,34 @@ msgid "Changing application language" msgstr "Wechsel der Sprache der Anwendung" msgid "Changing the region will log out your account.\n" -msgstr "Wenn Sie die Region ändern, werden Sie von Ihrem Konto abgemeldet.\n" +msgstr "Changing the region will log you out of your account.\n" msgid "Region selection" -msgstr "Auswahl der Region" +msgstr "Region selection" msgid "Second" msgstr "Sekunde" msgid "General Settings" -msgstr "Allgemeine Einstellungen" +msgstr "General Settings" msgid "Asia-Pacific" -msgstr "Asien-Pazifik" +msgstr "Asia-Pacific" msgid "China" msgstr "China" msgid "Europe" -msgstr "Europa" +msgstr "Europe" msgid "North America" -msgstr "Nordamerika" +msgstr "North America" msgid "Others" msgstr "Sonstige" msgid "Login Region" -msgstr "Login-Region" +msgstr "Login Region" msgid "Metric" msgstr "Metrisch" @@ -3185,12 +3315,10 @@ msgid "User sync" msgstr "Benutzer-Synchronisation" msgid "Auto sync user presets(Printer/Filament/Process)" -msgstr "" -"Benutzervoreinstellungen automatisch synchronisieren (Drucker/Filament/" -"Prozess)" +msgstr "Auto sync user presets (Printer/Filament/Process)" msgid "User Sync" -msgstr "Benutzer-Synchronisation" +msgstr "User Sync" msgid "Associate files to BambuStudio" msgstr "Dateien mit BambuStudio verknüpfen" @@ -3212,7 +3340,7 @@ msgstr "" "Dateien festgelegt" msgid "Associate .step/.stp files to BambuStudio" -msgstr "Verknüpfen Sie .step/.stp-Dateien mit BambuStudio" +msgstr "Associate .step/.stp files to Bambu Studio" msgid "If enabled, sets BambuStudio as default application to open .step files" msgstr "" @@ -3289,7 +3417,7 @@ msgid "trace" msgstr "Spurensuche" msgid "Host Setting" -msgstr "Host-Einstellung" +msgstr "Host Setting" msgid "DEV host: api-dev.bambu-lab.com/v1" msgstr "DEV host: api-dev.bambu-lab.com/v1" @@ -3325,10 +3453,10 @@ msgid "Incompatible presets" msgstr "Inkompatible Voreinstellungen" msgid "AMS filaments" -msgstr "AMS Filament" +msgstr "AMS Materialien" msgid "Click to pick filament color" -msgstr "Klicken, um die Farbe des Filaments auszuwählen" +msgstr "Pressen um Materialfarbe zu wählen" msgid "Add/Remove presets" msgstr "Voreinstellungen hinzufügen/entfernen" @@ -3340,8 +3468,7 @@ msgid "Project-inside presets" msgstr "Projektinterne Voreinstellungen" msgid "Slice all plate to obtain time and filament estimation" -msgstr "" -"Slicen Sie alle Druckplatten, um Zeit- und Filamentschätzungen zu erhalten" +msgstr "Alle Bauplatten für Zeit- und Materialvorhersage slicen" msgid "Packing project data into 3mf file" msgstr "Packen der Projektdaten in eine 3mf-Datei" @@ -3453,12 +3580,6 @@ msgstr "Für \"%1%\", fügen Sie \"%2%\" als neue Voreinstellung hinzu" msgid "Simply switch to \"%1%\"" msgstr "Wechseln Sie einfach zu \"%1%\"" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - msgid "My Device" msgstr "Mein Gerät" @@ -3466,13 +3587,13 @@ msgid "Other Device" msgstr "Anderes Gerät" msgid "Input access code" -msgstr "Zugangscode eingeben" +msgstr "Input access code" msgid "Log out successful." msgstr "Abmeldung erfolgreich." msgid "Busy" -msgstr "Beschäftigt" +msgstr "Busy" msgid "Bambu Cool Plate" msgstr "Bambu kalte Druckplatte" @@ -3481,13 +3602,13 @@ msgid "Bamabu Engineering Plate" msgstr "Bambu technische Druckplatte" msgid "Bamabu High Temperature Plate" -msgstr "Bambu Hochtemperaturdruckplatte" +msgstr "Bambu Hochtemperatur-Druckplatte" msgid "Send print job to" msgstr "Druckauftrag senden an" msgid "Refresh" -msgstr "Aktualisieren" +msgstr "Refresh" msgid "Bed Leveling" msgstr "Druckbettnivellierung" @@ -3502,30 +3623,27 @@ msgid "send completed" msgstr "senden abgeschlossen" msgid "No login account, only printers in LAN mode are displayed" -msgstr "Kein Anmeldekonto, nur Drucker im LAN-Modus werden angezeigt" +msgstr "No login account, only printers in LAN mode are displayed" msgid "Connecting to server" -msgstr "Verbindung zum Server wird hergestellt" +msgstr "Connecting to server" msgid "Synchronizing device information" -msgstr "Geräteinformationen synchronisieren" +msgstr "Synchronizing device information" msgid "Synchronizing device information time out" -msgstr "Zeitüberschreitung bei der Synchronisierung von Geräteinformationen" +msgstr "Synchronizing device information time out" msgid "Cannot send the print task when the upgrade is in progress" -msgstr "" -"Die Druckaufgabe kann nicht gesendet werden, während das Upgrade ausgeführt " -"wird" +msgstr "Cannot send the print task when the upgrade is in progress" msgid "" "The printer is executing instructions. Please restart printing after it ends" msgstr "" -"Der Drucker führt gerade Anweisungen aus. Bitte starten Sie den Druckvorgang " -"nach deren Beendigung erneut" +"The printer is executing instructions. Please restart printing after it ends" msgid "The printer is busy on other print job" -msgstr "Der Drucker ist mit einem anderen Druckauftrag beschäftigt." +msgstr "The printer is busy with another print job." #, c-format, boost-format msgid "" @@ -3542,15 +3660,15 @@ msgid "" "Filaments to AMS slots mappings have been established. You can click a " "filament above to change its mapping AMS slot" msgstr "" -"Die Zuordnung von Filament zu AMS-Slots wurde eingerichtet. Sie können oben " -"auf ein Filament klicken, um dessen Zuordnung zum AMS-Steckplatz zu ändern" +"Filaments to AMS slots mappings have been established. You can click a " +"filament above to change its mapping AMS slot" msgid "" "Please click each filament above to specify its mapping AMS slot before " "sending the print job" msgstr "" -"Bitte klicken Sie oben auf jedes Filament, um den zugehörigen AMS-Slot " -"anzugeben, bevor Sie den Druckauftrag abschicken." +"Please click each filament above to specify its mapping AMS slot before " +"sending the print job" #, c-format, boost-format msgid "" @@ -3569,10 +3687,10 @@ msgid "" msgstr "" msgid "Preparing print job" -msgstr "Druckauftrag vorbereiten" +msgstr "Preparing print job" msgid "Modifying the device name" -msgstr "Den Gerätenamen ändern" +msgstr "Modifying the device name" msgid "Log in printer" msgstr "Drucker anmelden" @@ -3609,6 +3727,15 @@ msgstr "Speichere aktuelle %s" msgid "Delete this preset" msgstr "Lösche diese Voreinstellung" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3657,13 +3784,13 @@ msgid "Acceleration" msgstr "Beschleunigung" msgid "Support filament" -msgstr "Supportfilament" +msgstr "Supportmaterial" msgid "Prime tower" msgstr "Prime-Turm" msgid "Flush options" -msgstr "Optionen für die Druckdüsensäuberung" +msgstr "Flush options" msgid "Special mode" msgstr "Spezialmodus" @@ -3696,7 +3823,7 @@ msgid "Reserved keywords found" msgstr "Reservierte Schlüsselwörter gefunden" msgid "Setting Overrides" -msgstr "überschreiben der Einstellungen" +msgstr "Setting Overrides" msgid "Retraction" msgstr "Einzug" @@ -3731,9 +3858,8 @@ msgid "" "Bed temperature when cool plate is installed. Value 0 means the filament " "does not support to print on the Cool Plate" msgstr "" -"Dies ist die Betttemperatur, wenn die cool plate installiert ist. Ein Wert " -"von 0 bedeutet, dass das Filament das Drucken auf der cool plate nicht " -"unterstützt." +"This is the bed temperature when the cool plate is installed. A value of 0 " +"means the filament does not support printing on the Cool Plate." msgid "Engineering plate" msgstr "technische Druckplatte" @@ -3742,9 +3868,8 @@ msgid "" "Bed temperature when engineering plate is installed. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Dies ist die Betttemperatur, wenn die technische Druckplatte installiert " -"wird. Ein Wert von 0 bedeutet, dass das Filament das Drucken auf der " -"technischen Druckplatte nicht unterstützt." +"This is the bed temperature when the engineering plate is installed. A value " +"of 0 means the filament does not support printing on the Engineering Plate." msgid "High Temp Plate" msgstr "Hochtemperaturdruckplatte" @@ -3753,9 +3878,17 @@ msgid "" "Bed temperature when high temperature plate is installed. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Dies ist die Betttemperatur, wenn die Hochtemperaturdruckplatte installiert " -"ist. Ein Wert von 0 bedeutet, dass das Filament das Drucken auf der " -"Hochtemperaturdruckplatte nicht unterstützt." +"This is the bed temperature when the high temperature plate is installed. A " +"value of 0 means the filament does not support printing on the High Temp " +"Plate." + +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Volumetric speed limitation" msgstr "Volumetrische Geschwindigkeitsbegrenzung" @@ -3798,10 +3931,10 @@ msgid "Auxiliary part cooling fan" msgstr "Hilfslüfter" msgid "Filament start G-code" -msgstr "Filament Start G-Code" +msgstr "Material Start G-Code" msgid "Filament end G-code" -msgstr "Filament End G-Code" +msgstr "Material Ende G-Code" msgid "Printable space" msgstr "Druckbarer Raum" @@ -3825,7 +3958,7 @@ msgid "Layer change G-code" msgstr "Schichtwechsel G-Code" msgid "Change filament G-code" -msgstr "Filamentwechsel G-Code" +msgstr "Materialwechsel G-Code" msgid "Pause G-code" msgstr "Pausen G-Code" @@ -3906,7 +4039,7 @@ msgid "New Value" msgstr "Neuer Wert" msgid "Transfer" -msgstr "Übertragen" +msgstr "Transfer" msgid "Don't save" msgstr "Nicht sichern" @@ -3990,6 +4123,12 @@ msgstr "Allgemein" msgid "Capabilities" msgstr "Fähigkeiten" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Als Abdeckung einstellen" @@ -4001,7 +4140,7 @@ msgid "The name \"%1%\" already exists." msgstr "Der Name \"%1%\" existiert bereits." msgid "Basic Info" -msgstr "Basis-Info" +msgstr "Basic Info" msgid "Pictures" msgstr "Bilder" @@ -4015,15 +4154,15 @@ msgstr "Montageanleitung" msgid "Choose files" msgstr "Dateien auswählen" -msgid "Designer" -msgstr "Designer" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Modellname" #, c-format, boost-format msgid "%s Update" -msgstr "%s Aktualisieren" +msgstr "%s Update" msgid "A new version is available" msgstr "Eine neue Version ist verfügbar" @@ -4071,16 +4210,16 @@ msgid "The configuration is up to date." msgstr "Die Konfiguration ist auf dem neuesten Stand." msgid "Auto-Calc" -msgstr "Automatisch berechnen" +msgstr "Auto-Calc" msgid "Flushing volumes for filament change" -msgstr "Säuberungsvolumen für Filamentwechsel" +msgstr "Spülvolumen für Materialwechsel" msgid "Flushing volume (mm³) for each filament pair." -msgstr "Säuberungvolumen (mm³) für jedes Filamentpaar." +msgstr "Spülvolumen (mm³) für jedes Materialpaar." msgid "Flush multiplier" -msgstr "Multiplikator der Druckdüsensäuberung" +msgstr "Flush multiplier" msgid "unloaded" msgstr "entladen wird" @@ -4089,7 +4228,7 @@ msgid "loaded" msgstr "geladen wird" msgid "Filament #" -msgstr "Filament #" +msgstr "Material #" msgid "From" msgstr "Von" @@ -4098,7 +4237,7 @@ msgid "To" msgstr "Zu" msgid "Login" -msgstr "Anmelden" +msgstr "Login" msgid "The configuration package is changed in previous Config Guide" msgstr "Das Konfigurationspaket wurde im vorherigen Config Guide geändert" @@ -4121,6 +4260,9 @@ msgstr "Zu Zwischenablage kopieren" msgid "Paste from clipboard" msgstr "Aus Zwischenablage einfügen" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Liste der Tastaturkürzel anzeigen" @@ -4203,7 +4345,7 @@ msgid "Movement step set to 1 mm" msgstr "Bewegungsschritt auf 1 mm eingestellt" msgid "keyboard 1-9: set filament for object/part" -msgstr "Tastatur 1-9: Filament für Objekt/Teil einstellen" +msgstr "Tastatur 1-9: Material für Objekt/Teil einstellen" msgid "Camera view - Default" msgstr "Kameraperspektive - Standard" @@ -4262,6 +4404,9 @@ msgstr "⌘+Mausrad" msgid "Support/Color Painting: adjust pen radius" msgstr "Support/Farbmalen: Stiftradius einstellen" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Support/Farbmalerei: Position des Abschnitts anpassen" @@ -4451,7 +4596,7 @@ msgid "Overhang wall" msgstr "Überhang Wand" msgid "Sparse infill" -msgstr "Füllung" +msgstr "Spärliche Füllung" msgid "Internal solid infill" msgstr "Interne massive Füllung" @@ -4592,12 +4737,11 @@ msgstr "" #, boost-format msgid "%1% is too close to others, and collisions may be caused." -msgstr "" -"%1% ist zu nah an anderen, und es können Kollisionen verursacht werden." +msgstr "%1% is too close to others, and collisions may be caused." #, boost-format msgid "%1% is too tall, and collisions will be caused." -msgstr "%1% ist zu hoch und es kommt zu Kollisionen." +msgstr "%1% is too tall, and collisions will be caused." msgid " is too close to others, there will be collisions when printing.\n" msgstr " zu nahe an anderen, es kommt beim Drucken zu Kollisionen.\n" @@ -4610,17 +4754,17 @@ msgid "Prime Tower" msgstr "Prime Turm" msgid " is too close to others, and collisions may be caused.\n" -msgstr " ist zu nah an anderen und es können Kollisionen verursacht werden.\n" +msgstr " is too close to others, and collisions may be caused.\n" msgid " is too close to exclusion area, and collisions will be caused.\n" -msgstr " ist zu nahe am Sperrgebiet und es werden Kollisionen verursacht.\n" +msgstr " is too close to an exclusion area, and collisions will be caused.\n" msgid "" "Can not print multiple filaments which have large difference of temperature " "together. Otherwise, the extruder and nozzle may be blocked or damaged " "during printing" msgstr "" -"Es können nicht mehrere Filamente mit einem großen Temperaturunterschied " +"Es können nicht mehrere Materialien mit einem großen Temperaturunterschied " "zusammen gedruckt werden. Andernfalls können der Extruder und die Druckdüse " "während des Drucks blockiert oder beschädigt werden" @@ -4697,7 +4841,7 @@ msgstr "Schichthöhe kann Druckdüsendurchmesser nicht überschreiten" #, c-format, boost-format msgid "Plate %d: %s does not support filament %s.\n" -msgstr "Druckplatte %d: %s unterstützt kein Filament %s.\n" +msgstr "Druckplatte %d: %s unterstützt kein Material %s.\n" msgid "Generating skirt & brim" msgstr "Erzeugen von Schürze und Rand (skirt & brim)" @@ -4776,9 +4920,8 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Cool Plate" msgstr "" -"Dies ist die Betttemperatur für Schichten mit Ausnahme der Ersten. Ein Wert " -"von 0 bedeutet, dass das Filament das Drucken auf der kalten Druckplatte " -"nicht unterstützt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Cool Plate." msgid "°C" msgstr "°C" @@ -4790,17 +4933,20 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Dies ist die Betttemperatur für Schichten mit Ausnahme der Ersten. Ein Wert " -"von 0 bedeutet, dass das Filament das Drucken auf der technischen " -"Druckplatte nicht unterstützt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Engineering Plate." msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Dies ist die Betttemperatur für Schichten mit Ausnahme der Ersten. Ein Wert " -"von 0 bedeutet, dass das Filament das Drucken auf der " -"Hochtemperaturdruckplatte nicht unterstützt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Initial layer" msgstr "Erste Schicht" @@ -4812,24 +4958,27 @@ msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Cool Plate" msgstr "" -"Dies ist die Betttemperatur der Ausgangsschicht. Ein Wert von 0 bedeutet, " -"dass das Filament das Drucken auf der kalten Druckplatte nicht unterstützt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Cool Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Engineering Plate" msgstr "" -"Dies ist die Betttemperatur der Ausgangsschicht. Ein Wert von 0 bedeutet, " -"dass das Filament das Drucken auf der technischen Druckplatte nicht " -"unterstützt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Engineering Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the High Temp Plate" msgstr "" -"Dies ist die Betttemperatur der Ausgangsschicht. Ein Wert von 0 bedeutet, " -"dass das Filament das Drucken auf der Hochtemperaturdruckplatte nicht " -"unterstützt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" msgid "Bed types supported by the printer" msgstr "Vom Drucker unterstützte Druckbettypen" @@ -4921,14 +5070,14 @@ msgstr "" "die Brücke zu verringern und den Durchhang zu verbessern" msgid "Only one wall on top surfaces" -msgstr "Nur eine Wand auf den oberen Flächen" +msgstr "Only one wall on top surfaces" msgid "" "Use only one wall on flat top surface, to give more space to the top infill " "pattern" msgstr "" -"Verwenden Sie nur eine Wand auf der flachen Oberseite, um mehr Platz für das " -"obere Füllungsmuster zu schaffen." +"Use only one wall on flat top surfaces, to give more space to the top infill " +"pattern" msgid "Slow down for overhang" msgstr "Verlangsamen bei Überhängen" @@ -5026,10 +5175,10 @@ msgid "mm/s²" msgstr "mm/s²" msgid "Default filament profile" -msgstr "Standard-Filamentprofil" +msgstr "Standard-Materialprofil" msgid "Default filament profile when switch to this machine profile" -msgstr "Standard-Filamentprofil beim Wechsel zu diesem Maschinenprofil" +msgstr "Standard-Materialprofil beim Wechsel zu diesem Maschinenprofil" msgid "Default process profile" msgstr "Standard-Prozessprofil" @@ -5082,9 +5231,9 @@ msgid "" "bridges to be supported, and set it to a very large value if you don't want " "any bridges to be supported." msgstr "" -"Maximale Länge der Brücken, die keine Unterstützung benötigen. Setzen Sie " -"den Wert auf 0, wenn alle Brücken unterstützt werden sollen und legen Sie " -"einen sehr großen Wert fest, wenn keine Brücken unterstützt werden sollen." +"This is the maximum length of bridges that don't need support. Set it to 0 " +"if you want all bridges to be supported, and set it to a very large value if " +"you don't want any bridges to be supported." msgid "End G-code" msgstr "G-Code am Ende" @@ -5093,8 +5242,7 @@ msgid "End G-code when finish the whole printing" msgstr "End G-Code nach dem fertigstellen des kompletten Drucks" msgid "End G-code when finish the printing of this filament" -msgstr "" -"Fügen Sie den End-G-Code hinzu, wenn Sie den Druck dieses Filaments beenden." +msgstr "End G-Code nach Beendigung des Druckvorgangs mit diesem Material" msgid "Top surface pattern" msgstr "Muster der oberen Oberfläche" @@ -5112,7 +5260,7 @@ msgid "Monotonic" msgstr "Monotonisch" msgid "Monotonic line" -msgstr "Monotone Linie" +msgstr "Monotonic line" msgid "Bottom surface pattern" msgstr "Muster der unteren Oberfläche" @@ -5132,7 +5280,7 @@ msgstr "" "Qualität zu erzielen." msgid "Order of inner wall/outer wall/infil" -msgstr "Reihenfolge Innenwand/Außenwand/Füllung" +msgstr "Reihenfolge Innenwand/Außenwand/Infil" msgid "Print sequence of inner wall, outer wall and infill. " msgstr "Druckreihenfolge von Innenwand, Außenwand und Füllung. " @@ -5244,7 +5392,7 @@ msgstr "" "Diese Einstellung gibt an, wie viel Volumen an Material pro Sekunde " "geschmolzen und extrudiert werden kann. Die Druckgeschwindigkeit wird durch " "die maximale volumetrische Geschwindigkeit begrenzt, falls die Einstellung " -"zu hoch und unangemessen ist. Null bedeutet keine Begrenzung." +"zu hoch und unangemessen ist. Null bedeutet keine Begrenzung" msgid "mm³/s" msgstr "mm³/s" @@ -5256,33 +5404,33 @@ msgid "mm³" msgstr "mm³" msgid "Filament load time" -msgstr "Ladedauer des Filaments" +msgstr "Material Ladezeit" msgid "Time to load new filament when switch filament. For statistics only" msgstr "" -"Zeit zum Laden des neuen Filaments beim Wechseln des Filaments, nur für " -"statistische Zwecke." +"Zeit zum Laden eines neuen Materials beim Wechsel des Materials. Nur für " +"Statistiken" msgid "Filament unload time" -msgstr "Entladezeit des Filaments" +msgstr "Material Entladezeit" msgid "Time to unload old filament when switch filament. For statistics only" msgstr "" -"Zeit zum Entladen des alten Filaments beim Wechseln des Filaments, nur für " -"statistische Zwecke." +"Zeit zum Entladen des alten Materials beim Wechsel des Materials. Nur für " +"Statistiken" msgid "" "Filament diameter is used to calculate extrusion in gcode, so it's important " "and should be accurate" msgstr "" -"Der Filamentdurchmesser wird für die Berechnung der Extrusion im G-Code " +"Der Materialdurchmesser wird für die Berechnung der Extrusion im G-Code " "verwendet, er ist also wichtig und sollte genau sein" msgid "Density" msgstr "Dichte" msgid "Filament density. For statistics only" -msgstr "Filamentdichte. Nur für die Statistik" +msgstr "Materialdichte. Nur für die Statistik" msgid "g/cm³" msgstr "g/cm³" @@ -5291,7 +5439,7 @@ msgid "Type" msgstr "Typ" msgid "The material type of filament" -msgstr "Material des Filaments." +msgstr "Der Materialtyp des Materials" msgid "Soluble material" msgstr "Lösliches Material" @@ -5308,8 +5456,7 @@ msgstr "Stützmaterial" msgid "" "Support material is commonly used to print support and support interface" msgstr "" -"Stützmaterial wird üblicherweise zum Drucken von Stützen und " -"Stützschnittstellen verwendet." +"Support material is commonly used to print support and support interfaces." msgid "Temperature of vitrificaiton" msgstr "Verglasungstemperatur" @@ -5325,7 +5472,7 @@ msgid "Price" msgstr "Preis" msgid "Filament price. For statistics only" -msgstr "Filamentpreis, nur für statistische Zwecke." +msgstr "Preis des Materials. Nur für die Statistik" msgid "money/kg" msgstr "Kosten/kg" @@ -5340,21 +5487,22 @@ msgid "" "Angle for sparse infill pattern, which controls the start or main direction " "of line" msgstr "" -"Winkel für das Infill-Muster, das die Anfangs- oder Hauptrichtung der Linie " -"bestimmt" +"Winkel für das spärliche Infill-Muster, das die Anfangs- oder Hauptrichtung " +"der Linie bestimmt" msgid "Sparse infill density" -msgstr "Dichte der Füllung" +msgstr "Dichte der spärlichen Füllung" -#, fuzzy, c-format +#, c-format msgid "Density of internal sparse infill, 100% means solid throughout" -msgstr "Dichte des internen Infill, 100% bedeutet durchgehend fest" +msgstr "" +"Dichte der internen spärlichen Füllung, 100%% bedeutet durchgehend fest" msgid "Sparse infill pattern" -msgstr "Muster der Füllung" +msgstr "Muster der spärlichen Füllung" msgid "Line pattern for internal sparse infill" -msgstr "Linienmuster für interne Füllung." +msgstr "Linienmuster für interne spärliche Füllung" msgid "Grid" msgstr "Gitternetz" @@ -5381,9 +5529,8 @@ msgid "" "Acceleration of top surface infill. Using a lower value may improve top " "surface quality" msgstr "" -"Dies ist die Beschleunigung der Füllung der oberen Oberfläche. Die " -"Verwendung eines niedrigeren Werts kann die Qualität der oberen Oberfläche " -"verbessern." +"Acceleration of top surface infill. Using a lower value may improve top " +"surface quality" msgid "" "Acceleration of initial layer. Using a lower value can improve build plate " @@ -5436,7 +5583,7 @@ msgstr "Druckdüsentemperatur für die erste Schicht" msgid "Nozzle temperature to print initial layer when using this filament" msgstr "" "Druckdüsentemperatur zum Drucken der ersten Schicht bei Verwendung dieses " -"Filaments" +"Materials" msgid "Full fan speed at layer" msgstr "Volle Lüfterdrehzahl ab Schicht" @@ -5482,7 +5629,7 @@ msgstr "" "unregelmäßige Linienbreite und sollte langsamer gedruckt werden" msgid "Arc fitting" -msgstr "Bogenanpassung" +msgstr "Arc fitting" msgid "" "Enable this to get a G-code file which has G2 and G3 moves. And the fitting " @@ -5517,7 +5664,7 @@ msgid "" "nozzle, and what kind of filament can be printed" msgstr "" "Das metallische Material der Druckdüse. Dies bestimmt die Abriebfestigkeit " -"der Druckdüse und welche Art von Filament gedruckt werden kann" +"der Druckdüse und welche Art von Material gedruckt werden kann" msgid "Hardened steel" msgstr "Gehärteter Stahl" @@ -5546,18 +5693,18 @@ msgid "" "Automatically Combine sparse infill of several layers to print together to " "reduce time. Wall is still printed with original layer height." msgstr "" -"Kombinieren Sie automatisch das Infill aus mehreren Schichten, um gemeinsam " -"zu drucken und die Zeit zu reduzieren. Die Wand wird weiterhin mit der " -"ursprünglichen Schichthöhe gedruckt." +"Kombinieren Sie automatisch spärliche Füllung aus mehreren Schichten, um " +"gemeinsam zu drucken und die Zeit zu reduzieren. Die Wand wird weiterhin mit " +"der ursprünglichen Schichthöhe gedruckt." msgid "Filament to print internal sparse infill." -msgstr "Filament für den Druck von Infill." +msgstr "Filament für den Druck von spärlicher interner Füllung." msgid "Line width of internal sparse infill" -msgstr "Linienbreite der internen Füllung" +msgstr "Linienbreite der internen spärlichen Ausfüllung" msgid "Infill/Wall overlap" -msgstr "Überstand Füllung/Wand" +msgstr "Füllung/Wand überstand" msgid "" "Infill area is enlarged slightly to overlap with wall for better bonding. " @@ -5565,10 +5712,10 @@ msgid "" msgstr "" "Der Bereich der Füllung wird leicht vergrößert, damit er sich mit der Wand " "überschneidet, um eine bessere Haftung zu erreichen. Der Prozentwert bezieht " -"sich auf die Linienbreite der Füllung." +"sich auf die Linienbreite der spärlichen Füllung" msgid "Speed of internal sparse infill" -msgstr "Geschwindigkeit der internen Füllung." +msgstr "Geschwindigkeit der internen spärlichen Füllung" msgid "Ironing Type" msgstr "Glätten-Typ" @@ -5748,7 +5895,7 @@ msgstr "" "Teilelüfter" msgid "Max" -msgstr "Maximal" +msgstr "Max" msgid "" "The largest printable layer height for extruder. Used tp limits the maximum " @@ -5794,10 +5941,10 @@ msgid "Diameter of nozzle" msgstr "Druckdüsendurchmesser" msgid "Nozzle volume" -msgstr "Volumen der Druckdüse" +msgstr "Nozzle volume" msgid "Volume of nozzle between the cutter and the end of nozzle" -msgstr "Volumen der Düse zwischen dem Messer und dem Ende der Düse" +msgstr "Volume of nozzle between the filament cutter and the end of the nozzle" msgid "Reduce infill retraction" msgstr "Rückzug bei der Füllung verringern" @@ -5967,6 +6114,9 @@ msgstr "Ausgerichtet" msgid "Back" msgstr "Rückseite" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Abstand der Schürze" @@ -5989,14 +6139,14 @@ msgstr "" "für diese Schichten zu erreichen" msgid "Minimum sparse infill threshold" -msgstr "Mindestschwelle für Füllung" +msgstr "Mindestschwelle für spärliche Füllung" msgid "" "Sparse infill area which is smaller than threshold value is replaced by " "internal solid infill" msgstr "" -"Füllbereiche, die kleiner als der Schwellenwert sind, werden durch interne " -"massive Füllungen ersetzt" +"Spärliche Füllbereiche, die kleiner als der Schwellenwert sind, werden durch " +"interne massive Füllungen ersetzt" msgid "mm²" msgstr "mm²" @@ -6021,15 +6171,13 @@ msgstr "" "endgültig erzeugte Modell hat keine Naht" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Record timelapse video of printing without showing the toolhead. In this " -"mode the toolhead docks near the excess chute at each layer change, and then " -"a snapshot is taken with the chamber camera. When printing finishes, a " -"timelapse video is created from all the snapshots." msgid "Temperature variation" msgstr "Temperaturvariation" @@ -6041,7 +6189,7 @@ msgid "Start G-code when start the whole printing" msgstr "G-Code starten, wenn der gesamte Druckvorgang beginnt" msgid "Start G-code when start the printing of this filament" -msgstr "G-Code starten, wenn der Druck dieses Filaments beginnt" +msgstr "G-Code starten, wenn der Druck dieses Materials beginnt" msgid "Enable support" msgstr "Support aktivieren" @@ -6104,7 +6252,7 @@ msgid "" "Filament to print support and skirt. 0 means no specific filament for " "support and current filament is used" msgstr "" -"Filament für den Druck der Supports und der Umrandung. 0 bedeutet, dass kein " +"Material für den Druck der Supports und der Schürze. 0 bedeutet, dass kein " "spezielles Filament für den Support und das aktuelle Filament wird verwendet" msgid "Line width of support" @@ -6123,9 +6271,9 @@ msgid "" "Filament to print support interface. 0 means no specific filament for " "support interface and current filament is used" msgstr "" -"Filament zum Drucken der Support-Schnittstelle. 0 bedeutet, dass kein " -"spezielles Filament für die Support-Schnittstelle vorhanden ist und das " -"aktuelle Filament verwendet wird" +"Material zum Drucken der Support-Schnittstelle. 0 bedeutet, dass kein " +"spezielles Material für die Support-Schnittstelle vorhanden ist und das " +"aktuelle Material verwendet wird" msgid "Top interface layers" msgstr "Obere Schnittstellenschichten" @@ -6196,13 +6344,8 @@ msgstr "Unabhängige Support-Schichthöhe" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"Die Support-Schicht verwendet eine von der Objektschicht unabhängige " -"Schichthöhe. Dies dient der Unterstützung benutzerdefinierter Supportlücken, " -"kann aber zusätzliche Filamentwechsel verursachen, wenn die Supportschicht " -"von einem anderen Filament gedruckt wird" msgid "Threshold angle" msgstr "Schwellenwinkel" @@ -6291,7 +6434,7 @@ msgid "" "This gcode is inserted when change filament, including T command to trigger " "tool change" msgstr "" -"Dieser G-Code wird beim Filamentwechsel eingefügt, einschließlich des T-" +"Dieser G-Code wird beim Materialwechsel eingefügt, einschließlich des T-" "Befehls zum Auslösen des Werkzeugwechsels" msgid "Line width for top surfaces" @@ -6378,7 +6521,7 @@ msgid "Width of prime tower" msgstr "Breite des Prime-Turms" msgid "Flush into objects' infill" -msgstr "Druckdüse in der Füllung der Objekte säubern" +msgstr "Flush into objects' infill" msgid "" "Purging after filament change will be done inside objects' infills. This may " @@ -6386,33 +6529,31 @@ msgid "" "printed with transparent filament, the mixed color infill will be seen " "outside" msgstr "" -"Die Spülung der Druckdüse nach dem Filamentwechsel erfolgt innerhalb der " -"Füllungen der Objekte. Dies kann die Abfallmenge verringern und die " -"Druckzeit verkürzen. Wenn die Wände mit transparentem Filament gedruckt " -"werden, ist die gemischte Farbe der Füllung sichtbar." +"Purging after filament change will be done inside objects' infills. This may " +"lower the amount of waste and decrease the print time. If the walls are " +"printed with transparent filament, the mixed color infill will be visible." msgid "Flush into objects' support" -msgstr "Druckdüse in der Supportstruktur des Objekts säubern" +msgstr "Flush into objects' support" msgid "" "Purging after filament change will be done inside objects' support. This may " "lower the amount of waste and decrease the print time" msgstr "" -"Die Reinigung der Druckdüse nach dem Filamentwechsel erfolgt innerhalb des " -"Objektsupport. Dies kann die Abfallmenge verringern und die Druckzeit " -"verkürzen." +"Purging after filament change will be done inside objects' support. This may " +"lower the amount of waste and decrease the print time." msgid "Flush into this object" -msgstr "Druckdüse in diesem Objekt säubern" +msgstr "Flush into this object" msgid "" "This object will be used to purge the nozzle after a filament change to save " "filament and decrease the print time. Colours of the objects will be mixed " "as a result" msgstr "" -"Dieses Objekt wird verwendet, um die Düse nach einem Filamentwechsel zu " -"säubern, um Filament zu sparen und die Druckzeit zu verkürzen. Die Farben " -"der Objekte werden als Ergebnis gemischt" +"This object will be used to purge the nozzle after a filament change to save " +"filament and decrease the print time. Colors of the objects will be mixed as " +"a result." msgid "X-Y hole compensation" msgstr "X-Y-Loch-Kompensation" @@ -6489,10 +6630,10 @@ msgid "Arrange options: 0-disable, 1-enable, others-auto" msgstr "Anordnungsoptionen: 0-deaktiviert; 1-aktiviert; andere-automatisch" msgid "Convert Unit" -msgstr "Einheit umrechnen" +msgstr "Convert Unit" msgid "Convert the units of model" -msgstr "Einheiten des Modells umrechnen" +msgstr "Convert the units of model" msgid "Orient the model" msgstr "Das Modell ausrichten" @@ -6515,10 +6656,10 @@ msgid "Load process/machine settings from the specified file" msgstr "Laden von Prozess-/Maschineneinstellungen aus der angegebenen Datei" msgid "Load Filament Settings" -msgstr "Filamenteinstellungen laden" +msgstr "Lade Materialeinstellungen" msgid "Load filament settings from the specified file list" -msgstr "Filamenteinstellungen aus der angegebenen Dateiliste laden" +msgstr "Materialeinstellungen aus der angegebenen Dateiliste laden" msgid "Output directory" msgstr "Ausgabeverzeichnis" @@ -6543,7 +6684,7 @@ msgid "Generating walls" msgstr "Erzeugen von Wänden" msgid "Generating infill regions" -msgstr "Generierung von Füllbereichen" +msgstr "Erzeugung von Füllregionen" msgid "Generating infill toolpath" msgstr "Füllwerkzeugweg generieren" @@ -6556,10 +6697,14 @@ msgstr "Überprüfung der Notwendigkeit der Supports" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Es scheint, dass Objekt %s Support zum Drucken benötigt. Bitte aktivieren " -"Sie die Support-Generierung." msgid "Optimizing toolpath" msgstr "Optimieren des Werkzeugwegs" @@ -6569,14 +6714,8 @@ msgstr "" "Die leeren Ebenen im unteren Bereich werden durch die nächstgelegenen " "normalen Ebenen ersetzt." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"Das Modell hat überlappende oder sich selbst überschneidende Facetten. Ich " -"habe versucht, es zu reparieren, aber vielleicht möchten Sie die Ergebnisse " -"überprüfen oder die Eingabedatei reparieren und es erneut versuchen." msgid "Slicing mesh" msgstr "Slicen des Netzes" @@ -6590,34 +6729,117 @@ msgstr "Fehler auf Zeile %1%:\n" #, c-format, boost-format msgid "Support: generate toolpath at layer %d" -msgstr "Support: Werkzeugpfad auf Ebene %d erzeugen" +msgstr "Support: generate toolpath at layer %d" msgid "Support: detect overhangs" -msgstr "Support: Überhänge erkennen" +msgstr "Support: detect overhangs" msgid "Support: generate contact points" -msgstr "Support: Kontaktstellen erstellen" +msgstr "Support: generate contact points" msgid "Support: propagate branches" -msgstr "Support: Zweige vermehren" +msgstr "Support: propagate branches" msgid "Support: draw polygons" -msgstr "Support: Polygone zeichnen" +msgstr "Support: draw polygons" msgid "Support: generate toolpath" -msgstr "Support: Werkzeugweg generieren" +msgstr "Support: generate toolpath" #, c-format, boost-format msgid "Support: generate polygons at layer %d" -msgstr "Support: Polygone auf Ebene %d erzeugen" +msgstr "Support: generate polygons at layer %d" #, c-format, boost-format msgid "Support: fix holes at layer %d" -msgstr "Support: Löcher in Schicht %d repairieren" +msgstr "Support: fix holes at layer %d" #, c-format, boost-format msgid "Support: propagate branches at layer %d" -msgstr "Support: Verbreiten von Zweigen auf Ebene %d" +msgstr "Support: propagate branches at layer %d" + +#~ msgid "the 3mf is not compatible, load geometry data only!" +#~ msgstr "die 3mf ist nicht kompatibel, laden Sie nur Geometriedaten!" + +#~ msgid "Save configuration as:" +#~ msgstr "Konfiguration speichern unter:" + +#~ msgid "Line type" +#~ msgstr "Linientyp" + +#~ msgid "Designer" +#~ msgstr "Designer" + +#~ msgid "Report" +#~ msgstr "Bericht" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Gerät:" + +#~ msgid "Translation" +#~ msgstr "Übersetzung" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "" +#~ "Es scheint, dass Objekt %s Support zum Drucken benötigt. Bitte aktivieren " +#~ "Sie die Support-Generierung." + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "Das Modell hat überlappende oder sich selbst überschneidende Facetten. " +#~ "Ich habe versucht, es zu reparieren, aber vielleicht möchten Sie die " +#~ "Ergebnisse überprüfen oder die Eingabedatei reparieren und es erneut " +#~ "versuchen." + +#~ msgid "" +#~ "Auto orientates selected objects or all objects.If there are selected " +#~ "objects, it just orientates the selected ones.Otherwise, it will " +#~ "orientates all objects in the project." +#~ msgstr "" +#~ "Wenn es ausgewählte Objekte gibt, werden nur die ausgewählten Objekte " +#~ "ausgerichtet, ansonsten werden alle Objekte im Projekt ausgerichtet." + +#~ msgid "The Config is not compatible and can not be loaded." +#~ msgstr "" +#~ "Die Konfiguration ist nicht kompatibel und kann nicht geladen werden." + +#~ msgid "Creating" +#~ msgstr "Creating" + +#~ msgid "Uploading" +#~ msgstr "Lade hoch" + +#~ msgid "Sending" +#~ msgstr "Sending" + +#~ msgid "Please fill report first." +#~ msgstr "Bitte füllen Sie zuerst den Bericht aus." + +#~ msgid "Unable to create zip file" +#~ msgstr "Unable to create zip file" + +#~ msgid "Filaments Selection" +#~ msgstr "Auswahl der Materialien" + +#~ msgid "Printer Selection" +#~ msgstr "Auswahl der Drucker" + +#~ msgid "Auto arrange" +#~ msgstr "Automatische Anordnung" + +#~ msgid "Spiral mode" +#~ msgstr "Spiralförmiger Modus" #~ msgid "Alt + Mouse wheel" #~ msgstr "Alt + Mausrad" @@ -6630,31 +6852,14 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ "Lösen Sie das Problem, indem Sie es vollständig innerhalb oder außerhalb " #~ "der Druckplatte verschieben." -#~ msgid "Auto arrange" -#~ msgstr "Automatische Anordnung" - -#~ msgid "" -#~ "Auto orientates selected objects or all objects.If there are selected " -#~ "objects, it just orientates the selected ones.Otherwise, it will " -#~ "orientates all objects in the project." -#~ msgstr "" -#~ "Wenn es ausgewählte Objekte gibt, werden nur die ausgewählten Objekte " -#~ "ausgerichtet, ansonsten werden alle Objekte im Projekt ausgerichtet." - #~ msgid "Clear all" #~ msgstr "Alles löschen" -#~ msgid "Creating" -#~ msgstr "Wird erstellt..." - #~ msgid "Ctrl + Any arrow" #~ msgstr "Strg + beliebiger Pfeil" #~ msgid "Ctrl + Left mouse button" -#~ msgstr "Strg + Linke Maustaste" - -#~ msgid "Debug" -#~ msgstr "Debuggen" +#~ msgstr "Ctrl + Left mouse button" #~ msgid "Display printable box" #~ msgstr "Bedruckbare Box anzeigen" @@ -6672,12 +6877,11 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ "2. The Filament presets\n" #~ "3. The Printer presets\n" #~ msgstr "" -#~ "Möchten Sie Ihre persönlichen Daten aus der Bambu Cloud " -#~ "synchronisieren? \n" -#~ "Enthält die folgenden Informationen:\n" -#~ "1. Prozess-Voreinstellungen\n" -#~ "2. Filament-Voreinstellungen\n" -#~ "3. Drucker-Voreinstellungen\n" +#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" +#~ "Contains the following information:\n" +#~ "1. Process presets\n" +#~ "2. Filament presets\n" +#~ "3. Printer presets\n" #~ msgid "" #~ "Don't retract when the travel is in infill area absolutely. That means " @@ -6686,15 +6890,6 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ "Ziehen Sie nicht zurück, wenn sich der Weg im Füllbereich befindet. Das " #~ "bedeutet, dass man die Quellung nicht sehen kann" -#~ msgid "Enter a search term" -#~ msgstr "Suchbegriff eingeben" - -#~ msgid "Filaments Selection" -#~ msgstr "Auswahl der Filamente" - -#~ msgid "Finished" -#~ msgstr "Fertig" - #~ msgid "Fix model locally" #~ msgstr "Modell lokal reparieren" @@ -6702,13 +6897,13 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ msgstr "Modell durch die Cloud reparieren" #~ msgid "Fragment Filter" -#~ msgstr "Fragment-Filter" +#~ msgstr "Fragment Filter" #~ msgid "Fragment area" -#~ msgstr "Fragment-Bereich" +#~ msgstr "Fragment area" #~ msgid "Fragment filter" -#~ msgstr "Fragment-Filter" +#~ msgstr "Fragment filter" #~ msgid "" #~ "Heat the nozzle to target \n" @@ -6716,10 +6911,10 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ msgstr "Die Druckdüse auf die Zieltemperatur heitzen" #~ msgid "In the calibration of extrusion flow" -#~ msgstr "Kalibrierung des Materialflusses" +#~ msgstr "In the calibration of extrusion flow" #~ msgid "In the calibration of laser scanner" -#~ msgstr "Kalibrierung des Laser-Scanner" +#~ msgstr "In the calibration of laser scanner" #~ msgid "Module" #~ msgstr "Modul" @@ -6731,19 +6926,16 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ msgstr "Ausgabedatei" #~ msgid "Pause(heated bed temperature error)" -#~ msgstr "Pause (Temperaturfehler beim Heizbett)" +#~ msgstr "Pause(heated bed temperature error)" #~ msgid "Pause(hotend temperature error)" -#~ msgstr "Pause (Temperaturfehler im Hotend)" +#~ msgstr "Pause(hotend temperature error)" #~ msgid "Pause(toolhead shell off)" -#~ msgstr "Pause (Werkzeugkopfabdeckung abgefallen)" - -#~ msgid "Please fill report first." -#~ msgstr "Bitte füllen Sie zuerst den Bericht aus." +#~ msgstr "Pause(toolhead shell off)" #~ msgid "Please upgrade your printer first" -#~ msgstr "Bitte aktualisieren Sie zuerst Ihren Drucker" +#~ msgstr "Please upgrade your printer first" #~ msgid "Position:" #~ msgstr "Position:" @@ -6752,23 +6944,17 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ "Preview only mode:\n" #~ "The loaded file contains gcode only." #~ msgstr "" -#~ "Nur Vorschaumodus:\n" -#~ "Die geladene Datei enthält nur G-Code." +#~ "Preview only mode:\n" +#~ "The loaded file contains G-code only." #~ msgid "Preview only mode for gcode file." -#~ msgstr "Nur Vorschaumodus für Gcode-Datei." - -#~ msgid "Printer Selection" -#~ msgstr "Auswahl der Drucker" +#~ msgstr "Preview only mode for G-code file." #~ msgid "" #~ "Push new filament \n" #~ "into extruder" #~ msgstr "Neues Filament in den Extruder drücken" -#~ msgid "Sending" -#~ msgstr "Senden" - #~ msgid "Shift + Any arrow" #~ msgstr "Umschalttaste + beliebiger Pfeil" @@ -6784,38 +6970,19 @@ msgstr "Support: Verbreiten von Zweigen auf Ebene %d" #~ msgid "Show Printable Box(TODO)" #~ msgstr "Druckbare Box anzeigen(TODO)" -#~ msgid "Spiral mode" -#~ msgstr "Spiralförmiger Modus" - #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" -#~ msgstr "Erfolgreich gesendet, springt automatisch zur Geräteseite in %s" +#~ msgstr "" +#~ "Successfully sent. Will automatically jump to the device page in %s s" #~ msgid "Swith cloud environment, Please login again!" #~ msgstr "Cloud-Umgebung wechseln, bitte erneut anmelden!" -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "" -#~ "Die Konfiguration ist nicht kompatibel und kann nicht geladen werden." - #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" #~ msgstr "" -#~ "Die Firmware-Versionen von Drucker und AMS sind zu niedrig. Bitte " -#~ "aktualisieren Sie auf die neueste Version, bevor Sie den Druckauftrag " -#~ "senden" - -#~ msgid "Unable to create zip file" -#~ msgstr "ZIP-Datei kann nicht erstellt werden" - -#~ msgid "Uploading" -#~ msgstr "Lade hoch" +#~ "The firmware versions of the printer and AMS are too low. Please update " +#~ "them to the latest version before sending any print jobs." #~ msgid "User pause" -#~ msgstr "Benutzerpause" - -#~ msgid "Waiting" -#~ msgstr "Warten" - -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "die 3mf ist nicht kompatibel, laden Sie nur Geometriedaten!" +#~ msgstr "User pause" diff --git a/bbl/i18n/en/BambuStudio_en.po b/bbl/i18n/en/BambuStudio_en.po index f5dc875dda..606d5c28e4 100644 --- a/bbl/i18n/en/BambuStudio_en.po +++ b/bbl/i18n/en/BambuStudio_en.po @@ -2,16 +2,13 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Localazy (https://localazy.com)\n" "Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" -"X-Generator: Poedit 3.0.1\n" msgid "Supports Painting" msgstr "Support Painting" @@ -50,7 +47,7 @@ msgid "Gap fill" msgstr "" msgid "Perform" -msgstr "Perform" +msgstr "Apply" msgid "Gap area" msgstr "" @@ -99,7 +96,7 @@ msgid "" "Filament count exceeds the maximum number that painting tool supports. only " "the first %1% filaments will be available in painting tool." msgstr "" -"Filament count exceeds the maximum number that painting tool supports. only " +"Filament count exceeds the maximum number that painting tool supports. Only " "the first %1% filaments will be available in painting tool." msgid "Color Painting" @@ -366,6 +363,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Add" + msgid "Notice" msgstr "Notice" @@ -416,7 +428,7 @@ msgid "" "It will be appreciated if you report the issue to our team." msgstr "" "Bambu Studio has run out of memory and will close. This may be a bug. Please " -"report this issue to our team." +"report this error to Technical Support." msgid "Fatal error" msgstr "Fatal error" @@ -447,8 +459,8 @@ msgid "" "BambuStudio configuration file may be corrupted and is not abled to be " "parsed.Please delete the file and try again." msgstr "" -"Bambu Studio configuration file may be corrupted and is not abled to be " -"parsed. Please delete the file and try again." +"Bambu Studio configuration file is not able to be parsed and may be " +"corrupted. Please delete the file and try again." #, c-format, boost-format msgid "" @@ -521,7 +533,7 @@ msgid "" "The version of Bambu studio is too low and needs to be updated to the latest " "version before it can be used normally" msgstr "" -"The version of Bambu studio is too low and needs to be updated to the latest " +"The version of Bambu Studio is too low and needs to be updated to the latest " "version before it can be used normally" msgid "Login information expired. Please login again." @@ -553,7 +565,7 @@ msgstr "Bambu Studio GUI initialization failed" #, boost-format msgid "Fatal error, exception catched: %1%" -msgstr "Fatal error, exception catched: %1%" +msgstr "Fatal error, exception: %1%" msgid "Quality" msgstr "Quality" @@ -642,9 +654,6 @@ msgstr "Cylinder" msgid "Cone" msgstr "Cone" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse Wipe Tower" - msgid "Add settings" msgstr "Add Settings" @@ -713,13 +722,13 @@ msgid "Assemble" msgstr "Assemble" msgid "Assemble the selected objects to an object with multiple parts" -msgstr "Assemble the selected objects to an object with multiple parts" +msgstr "Assemble the selected objects into an object with multiple parts" msgid "Assemble the selected objects to an object with single part" -msgstr "Assemble the selected objects to an object with single part" +msgstr "Assemble the selected objects into an object with single part" msgid "Assemble the selected parts to a single part" -msgstr "Assemble the selected parts to a single part" +msgstr "Assemble the selected parts into a single part" msgid "Along X axis" msgstr "Along X Axis" @@ -782,13 +791,13 @@ msgid "Select All" msgstr "Select All" msgid "select all objects on current plate" -msgstr "Select all objects on current plate" +msgstr "Select all objects on the current plate" msgid "Delete All" msgstr "Delete All" msgid "delete all objects on current plate" -msgstr "Delete all objects on current plate" +msgstr "Delete all objects on the current plate" msgid "Arrange" msgstr "Arrange" @@ -869,13 +878,13 @@ msgid "Right click the icon to fix model object" msgstr "Right click the icon to fix model object" msgid "Right button click the icon to drop the object settings" -msgstr "Right button click the icon to drop the object settings" +msgstr "Right click the icon to drop the object settings" msgid "Click the icon to reset all settings of the object" msgstr "Click the icon to reset all settings of the object" msgid "Right button click the icon to drop the object printable property" -msgstr "Right button click the icon to drop the object printable property" +msgstr "Right click the icon to drop the object printable property" msgid "Click the icon to toggle printable property of the object" msgstr "Click the icon to toggle printable property of the object" @@ -902,7 +911,7 @@ msgid "Deleting the last solid part is not allowed." msgstr "Deleting the last solid part is not allowed." msgid "The target object contains only one part and can not be splited." -msgstr "The target object contains only one part and can not be split." +msgstr "The target object contains only one part and cannot be split." msgid "Assembly" msgstr "Assembly" @@ -964,13 +973,13 @@ msgstr "Repairing model object" msgid "Following model object has been repaired" msgid_plural "Following model objects have been repaired" -msgstr[0] "Following model object has been repaired" -msgstr[1] "Following model objects have been repaired" +msgstr[0] "The following model object has been repaired" +msgstr[1] "The following model objects have been repaired" msgid "Failed to repair folowing model object" msgid_plural "Failed to repair folowing model objects" -msgstr[0] "Failed to repair folowing model object" -msgstr[1] "Failed to repair folowing model objects" +msgstr[0] "Failed to repair the following model object" +msgstr[1] "Failed to repair the following model objects" msgid "Repairing was canceled" msgstr "Repairing was canceled" @@ -1034,7 +1043,7 @@ msgid "Multicolor Print" msgstr "Multicolor Print" msgid "Line Type" -msgstr "Line type" +msgstr "Line Type" msgid "No printer" msgstr "No printer" @@ -1046,7 +1055,7 @@ msgid "Cut filament" msgstr "Cut filament" msgid "Pull back current filament" -msgstr "Pull back current filament" +msgstr "Pull back the current filament" msgid "Push new filament into extruder" msgstr "" @@ -1112,7 +1121,7 @@ msgid "" "We can not do auto-arrange on this plate." msgstr "" "This plate is locked.\n" -"We can not auto-arrange this plate." +"We cannot auto-arrange this plate." msgid "Arranging..." msgstr "Arranging..." @@ -1151,15 +1160,15 @@ msgid "" "All the selected objects are on the locked plate,\n" "We can not do auto-orient on these objects." msgstr "" -"All the selected objects are on the locked plate,\n" -"We can not do auto-orient on these objects." +"All the selected objects are on a locked plate,\n" +"We cannot auto-orient these objects." msgid "" "This plate is locked,\n" "We can not do auto-orient on this plate." msgstr "" "This plate is locked.\n" -"We can not auto-orient this plate." +"We cannot auto-orient this plate." msgid "Orienting..." msgstr "Orienting..." @@ -1183,7 +1192,7 @@ msgid "The region parameter is incorrrect" msgstr "The region parameter is incorrrect." msgid "Failure of printer login" -msgstr "Failure of printer login" +msgstr "Printer login failure" msgid "Failed to get ticket" msgstr "Failed to get ticket" @@ -1192,7 +1201,7 @@ msgid "User authorization timeout" msgstr "User authorization timeout" msgid "Failure of bind" -msgstr "Failure of bind" +msgstr "Binding failure" msgid "Unknown Failure" msgstr "Unknown Failure" @@ -1204,7 +1213,7 @@ msgid "Task canceled" msgstr "Task canceled" msgid "Upload task timed out. Please check the network problem and try again" -msgstr "Upload task timed out. Please check the network problem and try again" +msgstr "Upload task timed out. Please check the network and try again" msgid "Cloud service connection failed. Please try again." msgstr "Cloud service connection failed. Please try again." @@ -1237,6 +1246,9 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" msgstr "Sending print configuration" @@ -1284,8 +1296,8 @@ msgid "" "Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " "by Alessandro Ranellucci and the RepRap community" msgstr "" -"Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " -"by Alessandro Ranellucci and the RepRap community" +"Bambu Studio is based on PrusaSlicer by Prusa Research, which is based on " +"Slic3r by Alessandro Ranellucci and the RepRap community" msgid "Libraries" msgstr "Libraries" @@ -1327,7 +1339,7 @@ msgid "AMSMaterialsSetting" msgstr "" msgid "Colour" -msgstr "Colour" +msgstr "Color" msgid "" "Nozzle\n" @@ -1362,6 +1374,18 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" msgstr "Insertion update" @@ -1370,14 +1394,14 @@ msgid "" "new Bambu Lab filament. This takes about 20 seconds." msgstr "" "The AMS will automatically read the filament information when inserting a " -"new Bambu Lab filament. This takes about 20 seconds." +"new Bambu Lab filament spool. This takes about 20 seconds." msgid "" "Note: if new filament is inserted during printing, the AMS will not " "automatically read any information until printing is completed." msgstr "" "Note: if new filament is inserted during printing, the AMS will not " -"automatically read any information until printing is completed." +"automatically read any information until printing has finished." msgid "" "When inserting a new filament, the AMS will not automatically read its " @@ -1395,8 +1419,8 @@ msgid "" "spools." msgstr "" "The AMS will automatically read the information of inserted filament on " -"start-up. It will take about 1 minute.The reading process will roll filament " -"spools." +"start-up. It will take about 1 minute.The reading process will rotate the " +"filament spools." msgid "" "The AMS will not automatically read information from inserted filament " @@ -1456,7 +1480,7 @@ msgid "" "Error message: %1%.\n" "Source file %2%." msgstr "" -"Failed to save gcode file.\n" +"Failed to save G-code file.\n" "Error message: %1%.\n" "Source file %2%." @@ -1548,8 +1572,9 @@ msgid "" "Please make sure whether to use the temperature to print.\n" "\n" msgstr "" -"Nozzle may be blocked when the temperature is out of recommended range.\n" -"Please make sure whether to use the temperature to print.\n" +"The nozzle may become clogged when the temperature is out of the recommended " +"range.\n" +"Please make sure whether to use this temperature to print.\n" "\n" #, c-format, boost-format @@ -1557,7 +1582,7 @@ msgid "" "Recommended nozzle temperature of this filament type is [%d, %d] degree " "centigrade" msgstr "" -"Recommended nozzle temperature of this filament type is [%d, %d] degree " +"The recommended nozzle temperature for this filament type is [%d, %d] degree " "centigrade" #, c-format, boost-format @@ -1566,8 +1591,8 @@ msgid "" "layer for more than %d degree centigrade.\n" "This may cause model broken free from build plate during printing" msgstr "" -"The bed temperature of other layers is lower than bed temperature of initial " -"layer by more than %d degree centigrade.\n" +"The bed temperature of other layers is lower than the bed temperature of the " +"first layer by more than %d degree centigrade.\n" "This may cause models to break free from the build plate during printing." msgid "" @@ -1597,7 +1622,7 @@ msgid "" "Reset to 0.1" msgstr "" "Ironing spacing too small\n" -"Reset to 0.1" +"It has been reset to 0.1" msgid "" "Zero initial layer height is invalid.\n" @@ -1616,10 +1641,9 @@ msgid "" "\n" "The value will be reset to 0." msgstr "" -"This setting is only used for model size tunning with small value in some " -"cases.\n" -"For example, when model size has small error and hard to be assembled.\n" -"For large size tuning, please use model scale function.\n" +"This setting is only used for tuning model size by small amounts.\n" +"For example, when the model size has small errors or when tolerances are " +"incorrect. For large adjustments, please use the model scale function.\n" "\n" "The value will be reset to 0." @@ -1630,9 +1654,9 @@ msgid "" "\n" "The value will be reset to 0." msgstr "" -"Too large elefant foot compensation is unreasonable.\n" -"If really have serious elephant foot effect, please check other settings.\n" -"For example, whether bed temperature is too high.\n" +"The elephant foot compensation value is too large.\n" +"If there are significant elephant foot issues, please check other settings.\n" +"The bed temperature may be too high, for example.\n" "\n" "The value will be reset to 0." @@ -1640,8 +1664,8 @@ msgid "" "Spiral mode only works when wall loops is 1, \n" "support is disabled, top shell layers is 0 and sparse infill density is 0\n" msgstr "" -"Spiral mode only works when wall loops is 1, \n" -"support is disabled, top shell layers is 0 and sparse infill density is 0\n" +"Spiral mode only works when wall loops is set to 1, \n" +"support is disabled, top shell layers is 0, and sparse infill density is 0\n" msgid "" "Change these settings automatically? \n" @@ -1650,7 +1674,7 @@ msgid "" msgstr "" "Change these settings automatically? \n" "Yes - Change these settings and enable spiral mode automatically\n" -"No - Give up using spiral mode this time" +"No - Cancel enabling spiral mode" msgid "" "Prime tower does not work when Adaptive Layer Height or Independent Support " @@ -1896,9 +1920,6 @@ msgstr "Time" msgid "Display" msgstr "Display" -msgid "Line type" -msgstr "Line type" - msgid "Layer Height (mm)" msgstr "Layer height (mm)" @@ -1986,6 +2007,9 @@ msgstr "Total estimation" msgid "Normal mode" msgstr "Normal mode" +msgid "Cost" +msgstr "Cost" + msgid "Prepare time" msgstr "Prepare time" @@ -2040,9 +2064,6 @@ msgstr "Allow multiple materials on same plate" msgid "Avoid extrusion calibration region" msgstr "Avoid extrusion calibration region" -msgid "Add" -msgstr "Add" - msgid "Add plate" msgstr "Add Plate" @@ -2140,7 +2161,7 @@ msgid "Monitoring Recording" msgstr "Monitoring Recording" msgid "ConnectPrinter(LAN)" -msgstr "ConnectPrinter(LAN)" +msgstr "Connect Printer (LAN)" msgid "Please input the printer access code:" msgstr "Please input the printer access code:" @@ -2155,6 +2176,15 @@ msgstr "" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Enter a search term" + +msgid "Online" +msgstr "Online" + +msgid "Offline" +msgstr "Offline" + msgid "Application is closing" msgstr "Closing application" @@ -2176,6 +2206,9 @@ msgstr "Device" msgid "Project" msgstr "Project" +msgid "Debug" +msgstr "Debug" + msgid "Slice" msgstr "Slice" @@ -2198,7 +2231,7 @@ msgid "Keyboard Shortcuts" msgstr "Keyboard Shortcuts" msgid "Show the list of the keyboard shortcuts" -msgstr "Show the list of the keyboard shortcuts" +msgstr "Show the list of keyboard shortcuts" msgid "Setup Wizard" msgstr "Setup Wizard" @@ -2213,6 +2246,12 @@ msgstr "Check for Updates" msgid "&About %s" msgstr "&About %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Default View" @@ -2284,11 +2323,26 @@ msgstr "Import 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Load a model" +msgid "Import Configs" +msgstr "Import Presets" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" -msgstr "Export All Object as STL" +msgstr "Export All Objects as STL" + +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" msgid "Export current Sliced file" -msgstr "Export current Sliced file" +msgstr "Export Sliced File" msgid "Export G-code" msgstr "Export G-code" @@ -2296,6 +2350,12 @@ msgstr "Export G-code" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "Export Presets" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Export" @@ -2362,27 +2422,12 @@ msgstr "Use Orthogonal View" msgid "Preferences" msgstr "Preferences" -msgid "About" -msgstr "" - msgid "View" msgstr "View" msgid "Help" msgstr "Help" -msgid "&File" -msgstr "&File" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&View" - -msgid "&Help" -msgstr "&Help" - msgid "&Open G-code" msgstr "&Open G-code" @@ -2414,8 +2459,48 @@ msgstr "&Quit" msgid "Quit %s" msgstr "Quit %s" -msgid "Save configuration as:" -msgstr "Save configuration as:" +msgid "&File" +msgstr "&File" + +msgid "&View" +msgstr "&View" + +msgid "&Help" +msgstr "&Help" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "There is %d preset exported. (Only non-system and currently used presets)" +msgstr[1] "There are %d presets exported. (Only non-system and currently used presets)" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "There is %d preset imported. (Only non-system and compatible presets)" +msgstr[1] "There are %d presets imported. (Only non-system and compatible presets)" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "File is missing" @@ -2460,47 +2545,93 @@ msgstr "Playing..." msgid "Load failed [%d]!" msgstr "Loading failed [%d]!" -msgid "3Dconnexion settings" -msgstr "3Dconnexion settings" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Device:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Download" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Waiting" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Finished" msgid "Speed:" msgstr "Speed:" -msgid "Translation" -msgstr "Translation" - -msgid "Zoom" -msgstr "Zoom" - msgid "Deadzone:" msgstr "Deadzone:" msgid "Options:" msgstr "Options:" +msgid "Zoom" +msgstr "Zoom" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion settings" + msgid "Swap Y/Z axes" msgstr "Swap Y/Z axes" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Printing progress" -msgid "Report" -msgstr "Report" +msgid "Resume" +msgstr "Resume" msgid "Stop" msgstr "Stop" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" @@ -2538,9 +2669,6 @@ msgstr "Printing list" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Resume" - msgid "Silent" msgstr "Silent" @@ -2571,9 +2699,6 @@ msgstr "Failed to connect to the server" msgid "Failed to connect to the printer" msgstr "Failed to connect to the printer" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "OK" @@ -2607,9 +2732,6 @@ msgstr "%s info" msgid "%s information" msgstr "%s information" -msgid "Download" -msgstr "Download" - msgid "Skip" msgstr "Skip" @@ -2802,9 +2924,6 @@ msgstr "Used Filament (g)" msgid "Used Materials" msgstr "Used Materials" -msgid "Cost" -msgstr "Cost" - msgid "Estimated time" msgstr "Estimated time" @@ -2828,7 +2947,8 @@ msgid "Do you want to save changes to \"%1%\"?" msgstr "Do you want to save changes to \"%1%\"?" msgid "Previous unsaved project detected, do you want to restore it?" -msgstr "Previously unsaved items have been detected. Do you want to restore?" +msgstr "" +"Previously unsaved items have been detected. Do you want to restore them?" msgid "Restore" msgstr "Restore" @@ -2854,8 +2974,8 @@ msgid "" "The 3mf's version %s is newer than %s's version %s, Found following keys " "unrecognized:\n" msgstr "" -"The 3mf's version %s is newer than %s's version %s, Found following keys " -"unrecognized:\n" +"The 3mf file's version %s is newer than %s's version %s, Found the following " +"unrecognized keys:\n" msgid "You'd better upgrade your software.\n" msgstr "You'd better upgrade your software.\n" @@ -2863,6 +2983,12 @@ msgstr "You'd better upgrade your software.\n" msgid "Newer 3mf version" msgstr "Newer 3mf version" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -2958,8 +3084,6 @@ msgid "" "Preview only mode:\n" "The loaded file contains gcode only, Can not enter the Prepare page" msgstr "" -"Preview only mode:\n" -"The loaded file contains G-code only and can not enter the Prepare page" msgid "You can keep the modified presets to the new project or discard them" msgstr "You can keep the modified presets for the new project or discard them" @@ -3034,7 +3158,7 @@ msgid "" "Suggest to use auto-arrange to avoid collisions when printing." msgstr "" "Print By Object: \n" -"Suggest to use auto-arrange to avoid collisions when printing." +"We suggest using auto-arrange to avoid collisions when printing." msgid "Send G-code" msgstr "Send G-code" @@ -3134,7 +3258,7 @@ msgid "User sync" msgstr "User sync" msgid "Auto sync user presets(Printer/Filament/Process)" -msgstr "Auto sync user presets(Printer/Filament/Process)" +msgstr "Auto sync user presets (Printer/Filament/Process)" msgid "User Sync" msgstr "User Sync" @@ -3159,7 +3283,7 @@ msgstr "" "files." msgid "Associate .step/.stp files to BambuStudio" -msgstr "Associate .step/.stp files to BambuStudio" +msgstr "Associate .step/.stp files to Bambu Studio" msgid "If enabled, sets BambuStudio as default application to open .step files" msgstr "" @@ -3206,7 +3330,7 @@ msgid "Other" msgstr "Other" msgid "Mouse wheel reverses when zooming" -msgstr "Reverse Scroll Direction while Zooming" +msgstr "Reverse scroll direction while zooming" msgid "Develop mode" msgstr "Developer mode" @@ -3275,7 +3399,7 @@ msgid "AMS filaments" msgstr "AMS filament" msgid "Click to pick filament color" -msgstr "Click to pick filament color" +msgstr "Click to select filament color" msgid "Add/Remove presets" msgstr "Add/Remove presets" @@ -3348,7 +3472,7 @@ msgstr "Preset \"%1%\" already exists." #, boost-format msgid "Preset \"%1%\" already exists and is incompatible with current printer." msgstr "" -"Preset \"%1%\" already exists and is incompatible with current printer." +"Preset \"%1%\" already exists and is incompatible with the current printer." msgid "Please note that saving action will replace this preset" msgstr "Please note that saving will overwrite the current preset." @@ -3392,12 +3516,6 @@ msgstr "For \"%1%\", add \"%2%\" as a new preset" msgid "Simply switch to \"%1%\"" msgstr "Simply switch to \"%1%\"" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - msgid "My Device" msgstr "My Device" @@ -3542,6 +3660,15 @@ msgstr "Save current %s" msgid "Delete this preset" msgstr "Delete this preset" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3617,12 +3744,12 @@ msgid_plural "" "estimation." msgstr[0] "" "Following line %s contains reserved keywords.\n" -"Please remove it, or will break G-code visualization and printing time " -"estimation." +"Please remove it, or G-code visualization and print time estimation will be " +"broken." msgstr[1] "" "Following lines %s contain reserved keywords.\n" -"Please remove them, or will break G-code visualization and printing time " -"estimation." +"Please remove them, or G-code visualization and print time estimation will " +"be broken." msgid "Reserved keywords found" msgstr "Reserved keywords found" @@ -3640,7 +3767,7 @@ msgid "Recommended nozzle temperature" msgstr "Recommended nozzle temperature" msgid "Recommended nozzle temperature range of this filament. 0 means no set" -msgstr "Recommended nozzle temperature range of this filament. 0 means no set" +msgstr "Recommended nozzle temperature range of this filament. 0 means not set" msgid "Recommended temperature range" msgstr "Recommended temperature range" @@ -3685,6 +3812,14 @@ msgstr "" "value of 0 means the filament does not support printing on the High Temp " "Plate." +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Volumetric speed limitation" msgstr "Volumetric speed limitation" @@ -3706,10 +3841,10 @@ msgid "" "shorter than threshold, fan speed is interpolated between the minimum and " "maximum fan speed according to layer printing time" msgstr "" -"Part cooling fan speed will start to run at min speed when the estimated " -"layer time is no longer than the layer time in setting. When layer time is " -"shorter than threshold, fan speed is interpolated between the minimum and " -"maximum fan speed according to layer printing time" +"The part cooling fan will run at the minimum fan speed when the estimated " +"layer time is longer than the threshold value. When the layer time is " +"shorter than the threshold, the fan speed will be interpolated between the " +"minimum and maximum fan speed according to layer printing time." msgid "Max fan speed threshold" msgstr "Max fan speed threshold" @@ -3718,8 +3853,8 @@ msgid "" "Part cooling fan speed will be max when the estimated layer time is shorter " "than the setting value" msgstr "" -"Part cooling fan speed will be max when the estimated layer time is shorter " -"than the set value." +"The part cooling fan will run at maximum speed when the estimated layer time " +"is shorter than the threshold value." msgid "Auxiliary part cooling fan" msgstr "Auxiliary part cooling fan" @@ -3783,12 +3918,12 @@ msgstr "Detached" msgid "Following preset will be deleted too." msgid_plural "Following presets will be deleted too." -msgstr[0] "Following preset will be deleted too." -msgstr[1] "Following presets will be deleted too." +msgstr[0] "The following preset will be deleted too:" +msgstr[1] "The following presets will be deleted too:" #, boost-format msgid "Are you sure to %1% the selected preset?" -msgstr "Are you sure to %1% the selected preset?" +msgstr "Are you sure you want to %1% the selected preset?" #. TRN Remove/Delete #, boost-format @@ -3808,7 +3943,7 @@ msgid "Click to reset current value and attach to the global value." msgstr "Click to reset current value and attach to the global value." msgid "Click to drop current modify and reset to saved value." -msgstr "Click to drop current modify and reset to saved value." +msgstr "Click to drop current modifications and reset to saved value." msgid "Process Settings" msgstr "Process Settings" @@ -3820,7 +3955,7 @@ msgid "Unsaved Changes" msgstr "unsaved changes" msgid "Discard or Keep changes" -msgstr "Discard or Keep changes" +msgstr "Discard or keep changes" msgid "Old Value" msgstr "Old value" @@ -3896,10 +4031,10 @@ msgid "" "Would you like to keep these changed settings after switching preset?" msgstr "" "You have changed some preset settings. \n" -"Would you like to keep these changed settings after switching preset?" +"Would you like to keep these changed settings after switching presets?" msgid "Extruders count" -msgstr "Extruders count" +msgstr "Extruder count" msgid "General" msgstr "General" @@ -3907,6 +4042,12 @@ msgstr "General" msgid "Capabilities" msgstr "Capabilities" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Set as cover" @@ -3932,8 +4073,8 @@ msgstr "Assembly Guide" msgid "Choose files" msgstr "Choose files" -msgid "Designer" -msgstr "Designer" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Model Name" @@ -3958,16 +4099,16 @@ msgid "Configuration incompatible" msgstr "Configuration incompatible" msgid "the configuration package is incompatible with current application." -msgstr "the configuration package is incompatible with current application." +msgstr "" +"the configuration package is incompatible with the current application." #, c-format, boost-format msgid "" "The configuration package is incompatible with current application.\n" "%s will update the configuration package, Otherwise it won't be able to start" msgstr "" -"The configuration package is incompatible with current application.\n" -"%s will update the configuration package. Otherwise, it won’t be able to " -"start." +"The configuration package is incompatible with the current application.\n" +"%s will update the configuration package to allow the application to start." #, c-format, boost-format msgid "Exit %s" @@ -4038,6 +4179,9 @@ msgstr "Copy to clipboard" msgid "Paste from clipboard" msgstr "Paste from clipboard" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Show keyboard shortcuts list" @@ -4049,9 +4193,9 @@ msgid "" "objects, it just orientates the selected ones.Otherwise, it will orientates " "all objects in the current disk." msgstr "" -"Auto orientates selected objects or all objects.If there are selected " -"objects, it just orientates the selected ones.Otherwise, it will orientates " -"all objects in the current disk." +"Auto orients selected objects or all objects.If there are selected objects, " +"it just orients the selected ones.Otherwise, it will orient all objects in " +"the current disk." msgid "Collapse/Expand the sidebar" msgstr "Collapse/Expand the sidebar" @@ -4093,34 +4237,34 @@ msgid "Arrow Up" msgstr "Arrow Up" msgid "Move selection 10 mm in positive Y direction" -msgstr "Move selection 10 mm in positive Y direction" +msgstr "Move selection 10mm in positive Y direction" msgid "Arrow Down" msgstr "Arrow Down" msgid "Move selection 10 mm in negative Y direction" -msgstr "Move selection 10 mm in negative Y direction" +msgstr "Move selection 10mm in negative Y direction" msgid "Arrow Left" msgstr "Arrow Left" msgid "Move selection 10 mm in negative X direction" -msgstr "Move selection 10 mm in negative X direction" +msgstr "Move selection 10mm in negative X direction" msgid "Arrow Right" msgstr "Arrow Right" msgid "Move selection 10 mm in positive X direction" -msgstr "Move selection 10 mm in positive X direction" +msgstr "Move selection 10mm in positive X direction" msgid "Shift+Any arrow" msgstr "" msgid "Movement step set to 1 mm" -msgstr "Movement step set to 1 mm" +msgstr "Movement step set to 1mm" msgid "keyboard 1-9: set filament for object/part" -msgstr "keyboard 1-9: set filament for object/part" +msgstr "Keyboard 1-9: set filament for object/part" msgid "Camera view - Default" msgstr "Camera view - Default" @@ -4179,6 +4323,9 @@ msgstr "" msgid "Support/Color Painting: adjust pen radius" msgstr "Support/Color Painting: adjust pen radius" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Support/Color Painting: adjust section position" @@ -4195,7 +4342,7 @@ msgid "Set extruder number for the objects and parts" msgstr "Set extruder number for the objects and parts" msgid "Delete objects, parts, modifiers " -msgstr "Delete objects, parts, modifiers " +msgstr "Delete objects, parts, modifiers" msgid "Space" msgstr "Space" @@ -4394,7 +4541,7 @@ msgid "too many files" msgstr "too many files" msgid "file too large" -msgstr "file too large" +msgstr "File too large" msgid "unsupported method" msgstr "unsupported method" @@ -4463,7 +4610,7 @@ msgid "invalid filename" msgstr "invalid filename" msgid "buffer too small" -msgstr "buffer too small" +msgstr "Buffer too small" msgid "internal error" msgstr "internal error" @@ -4472,7 +4619,7 @@ msgid "file not found" msgstr "file not found" msgid "archive too large" -msgstr "archive too large" +msgstr "Archive too large" msgid "validation failed" msgstr "validation failed" @@ -4484,7 +4631,8 @@ msgstr "write callback failed" msgid "" "%1% is too close to exclusion area, there will be collisions when printing." msgstr "" -"%1% is too close to exclusion area, there will be collisions when printing." +"%1% is too close to an exclusion area; there will be collisions when " +"printing." #, boost-format msgid "" @@ -4492,7 +4640,8 @@ msgid "" "%1% is too close to exclusion area, there will be collisions when printing." msgstr "" "\n" -"%1% is too close to exclusion area, there will be collisions when printing." +"%1% is too close to an exclusion area; there will be collisions when " +"printing." #, boost-format msgid "%1% is too close to others, and collisions may be caused." @@ -4508,7 +4657,7 @@ msgstr " is too close to others, there will be collisions when printing.\n" msgid "" " is too close to exclusion area, there will be collisions when printing.\n" msgstr "" -" is too close to exclusion area, there will be collisions when printing.\n" +" is too close to an exclusion area, there will be collisions when printing.\n" msgid "Prime Tower" msgstr "Prime Tower" @@ -4517,7 +4666,7 @@ msgid " is too close to others, and collisions may be caused.\n" msgstr " is too close to others, and collisions may be caused.\n" msgid " is too close to exclusion area, and collisions will be caused.\n" -msgstr " is too close to exclusion area, and collisions will be caused.\n" +msgstr " is too close to an exclusion area, and collisions will be caused.\n" msgid "" "Can not print multiple filaments which have large difference of temperature " @@ -4577,10 +4726,10 @@ msgstr "" "height." msgid "Too small line width" -msgstr "Too small line width" +msgstr "Line width too small" msgid "Too large line width" -msgstr "Too large line width" +msgstr "Line width too large" msgid "" "The prime tower requires that support has the same layer height with object." @@ -4645,7 +4794,8 @@ msgstr "Printable height" msgid "Maximum printable height which is limited by mechanism of printer" msgstr "" -"This is the maximum printable height which is limited by printer mechanisms." +"This is the maximum printable height which is limited by the height of the " +"build area." msgid "Printer preset names" msgstr "Printer preset names" @@ -4675,8 +4825,8 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Cool Plate" msgstr "" -"This is the bed temperature for layers except for the initial one. A value " -"of 0 means the filament does not support printing on the Cool Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Cool Plate." msgid "°C" msgstr "°C" @@ -4688,15 +4838,20 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"This is the bed temperature for layers except for the initial one. A value " -"of 0 means the filament does not support printing on the Engineering Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Engineering Plate." msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"This is the bed temperature for layers except for the initial one. A value " -"of 0 means the filament does not support printing on the High Temp Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Initial layer" msgstr "First layer" @@ -4708,23 +4863,28 @@ msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Cool Plate" msgstr "" -"This is the bed temperature of the initial layer. A value of 0 means the " +"This is the bed temperature of the first layer. A value of 0 means the " "filament does not support printing on the Cool Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Engineering Plate" msgstr "" -"This is the bed temperature of the initial layer. A value of 0 means the " +"This is the bed temperature of the first layer. A value of 0 means the " "filament does not support printing on the Engineering Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the High Temp Plate" msgstr "" -"This is the bed temperature of the initial layer. A value of 0 means the " +"This is the bed temperature of the first layer. A value of 0 means the " "filament does not support printing on the High Temp Plate." +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" + msgid "Bed types supported by the printer" msgstr "Bed types supported by the printer" @@ -4761,12 +4921,12 @@ msgid "" msgstr "" "The number of bottom solid layers is increased when slicing if the thickness " "calculated by bottom shell layers is thinner than this value. This can avoid " -"having too thin shell when layer height is small. 0 means that this setting " -"is disabled and thickness of bottom shell is absolutely determained by " -"bottom shell layers" +"having too thin a shell when layer height is small. 0 means that this " +"setting is disabled and the thickness of the bottom shell is determined " +"simply by the number of bottom shell layers." msgid "Force cooling for overhang and bridge" -msgstr "Force cooling for overhang and bridge" +msgstr "Force cooling for overhangs and bridges" msgid "" "Enable this option to optimize part cooling fan speed for overhang and " @@ -4776,16 +4936,16 @@ msgstr "" "bridges to get better cooling" msgid "Fan speed for overhang" -msgstr "Fan speed for overhang" +msgstr "Fan speed for overhangs" msgid "" "Force part cooling fan to be this speed when printing bridge or overhang " "wall which has large overhang degree. Forcing cooling for overhang and " "bridge can get better quality for these part" msgstr "" -"Force part cooling fan to be this speed when printing bridge or overhang " -"wall which has large overhang degree. Forcing cooling for overhang and " -"bridge can get better quality for these part" +"Force part cooling fan to be this speed when printing bridges or overhang " +"walls which have a large overhang degree. Forcing cooling for overhangs and " +"bridges can achieve better quality for these parts." msgid "Cooling overhang threshold" msgstr "Cooling overhang threshold" @@ -4795,9 +4955,9 @@ msgid "" "exceeds this value. Expressed as percentage which indicides how much width " "of the line without support from lower layer" msgstr "" -"Force cooling fan to be specific speed when overhang degree of printed part " -"exceeds this value. Expressed as percentage which indicides how much width " -"of the line without support from lower layer" +"This forces the cooling fan to use a specific speed when overhang degrees of " +"parts exceed the set value. It is expressed as percentage which indicates " +"how much line is acceptable without support from lower layers." msgid "Bridge flow" msgstr "Bridge flow" @@ -4806,8 +4966,8 @@ msgid "" "Decrease this value slightly(for example 0.9) to reduce the amount of " "material for bridge, to improve sag" msgstr "" -"Decrease this value slightly(for example 0.9) to reduce the amount of " -"material for bridges, to avoid sagging." +"Decrease this value slightly (for example 0.9) to reduce the amount of " +"material extruded for bridges to avoid sagging." msgid "Only one wall on top surfaces" msgstr "Only one wall on top surfaces" @@ -4816,14 +4976,16 @@ msgid "" "Use only one wall on flat top surface, to give more space to the top infill " "pattern" msgstr "" -"Use only one wall on flat top surface, to give more space to the top infill " +"Use only one wall on flat top surfaces, to give more space to the top infill " "pattern" msgid "Slow down for overhang" -msgstr "Slow down for overhang" +msgstr "Slow down for overhangs" msgid "Enable this option to slow printing down for different overhang degree" -msgstr "Enable this option to slow printing down for different overhang degree" +msgstr "" +"Enable this option to slow down when printing overhangs. The speeds for " +"different overhang percentages are set below." msgid "mm/s" msgstr "mm/s" @@ -4846,8 +5008,8 @@ msgid "" "and calculated automatically" msgstr "" "This controls brim position including outer side of models, inner side of " -"holes or both. Auto means both the brim position and brim width are analyzed " -"and calculated automatically." +"holes, or both. Auto means both the brim position and brim width are " +"analyzed and calculated automatically." msgid "Brim-object gap" msgstr "Brim-object gap" @@ -4897,7 +5059,7 @@ msgstr "" "Enable this option to slow printing speed down to ensure that the final " "layer time is not shorter than the layer time threshold in \"Max fan speed " "threshold\", so that the layer can be cooled for a longer time. This can " -"improve the cooling quality for needle and small details" +"improve the quality for small details." msgid "Normal printing" msgstr "Normal printing" @@ -4931,8 +5093,8 @@ msgid "" "Close all cooling fan for the first certain layers. Cooling fan of the first " "layer used to be closed to get better build plate adhesion" msgstr "" -"Close all cooling fan for the first certain layers. Cooling fan of the first " -"layer used to be closed to get better build plate adhesion" +"Turn off all cooling fans for the first few layers. This can be used to " +"improve bed adhesion." msgid "layers" msgstr "layers" @@ -4944,9 +5106,9 @@ msgid "" "Don't support the whole bridge area which make support very large. Bridge " "usually can be printing directly without support if not very long" msgstr "" -"This disables supporting bridge areas, which can make support very large. " -"Bridges can usually be printed directly without support if they are not very " -"long." +"This disables supporting bridges, which decreasing the mount of support " +"required. Bridges can usually be printed directly without support for a " +"reasonable distance." msgid "Thick bridges" msgstr "" @@ -4968,9 +5130,9 @@ msgid "" "bridges to be supported, and set it to a very large value if you don't want " "any bridges to be supported." msgstr "" -"Max length of bridges that don't need support. Set it to 0 if you want all " -"bridges to be supported, and set it to a very large value if you don't want " -"any bridges to be supported." +"This is the maximum length of bridges that don't need support. Set it to 0 " +"if you want all bridges to be supported, and set it to a very large value if " +"you don't want any bridges to be supported." msgid "End G-code" msgstr "End G-code" @@ -5004,7 +5166,8 @@ msgstr "Bottom surface pattern" msgid "Line pattern of bottom surface infill, not bridge infill" msgstr "" -"This is the line pattern of bottom surface infill, but not bridge infill." +"This is the line pattern of bottom surface infill, not including bridge " +"infill." msgid "Line width of outer wall" msgstr "Line width of outer wall" @@ -5013,8 +5176,8 @@ msgid "" "Speed of outer wall which is outermost and visible. It's used to be slower " "than inner wall speed to get better quality." msgstr "" -"Speed of outer wall which is outermost and visible. It's used to be slower " -"than inner wall speed to get better quality." +"This is the printing speed for the outer walls of parts. These are generally " +"printed slower than inner walls for higher quality." msgid "Order of inner wall/outer wall/infil" msgstr "Order of inner wall/outer wall/infill" @@ -5092,8 +5255,9 @@ msgid "" "If enable this setting, part cooling fan will never be stoped and will run " "at least at minimum speed to reduce the frequency of starting and stoping" msgstr "" -"If enable this setting, part cooling fan will never be stoped and will run " -"at least at minimum speed to reduce the frequency of starting and stoping" +"Enabling this setting means that part cooling fan will never stop entirely " +"and will instead run at least at minimum speed to reduce the frequency of " +"starting and stopping." msgid "Layer time" msgstr "Layer time" @@ -5103,7 +5267,7 @@ msgid "" "shorter than this value. Fan speed is interpolated between the minimum and " "maximum fan speeds according to layer printing time" msgstr "" -"Part cooling fan will be enabled for layers where the estimated time is " +"The part cooling fan will be enabled for layers where the estimated time is " "shorter than this value. Fan speed is interpolated between the minimum and " "maximum fan speeds according to layer printing time." @@ -5121,9 +5285,9 @@ msgid "" "extruded per second. Printing speed is limited by max volumetric speed, in " "case of too high and unreasonable speed setting. Zero means no limit" msgstr "" -"This setting stands for the volume of filament that can be melted and " -"extruded per second. Printing speed is limited by max volumetric speed in " -"case of too high and unreasonable speed setting. 0 means no limit." +"Use this to set the maximum volume of filament that can be melted and " +"extruded per second. Printing speed is limited by maximum volumetric speed " +"if settings are unreasonably high. 0 means there is no limit." msgid "mm³/s" msgstr "mm³/s" @@ -5154,8 +5318,8 @@ msgid "" "Filament diameter is used to calculate extrusion in gcode, so it's important " "and should be accurate" msgstr "" -"Filament diameter is used to calculate extrusion in G-code, so it is " -"important and should be accurate" +"Filament diameter is used to calculate extrusion variables in G-code, so it " +"is important that this is accurate and precise." msgid "Density" msgstr "Density" @@ -5170,7 +5334,7 @@ msgid "Type" msgstr "Type" msgid "The material type of filament" -msgstr "Filament material." +msgstr "Filament material type" msgid "Soluble material" msgstr "Soluble material" @@ -5186,10 +5350,10 @@ msgstr "Support material" msgid "" "Support material is commonly used to print support and support interface" msgstr "" -"Support material is commonly used to print support and support interface" +"Support material is commonly used to print support and support interfaces." msgid "Temperature of vitrificaiton" -msgstr "Temperature of vitrificaiton" +msgstr "Temperature of vitrification" msgid "" "Material becomes soft at this temperature. Thus the heatbed cannot be hotter " @@ -5271,7 +5435,7 @@ msgstr "" "acceleration can improve build plate adhesion." msgid "Line width of initial layer" -msgstr "Line width of initial layer" +msgstr "Line width of first layer" msgid "Initial layer height" msgstr "First layer height" @@ -5280,7 +5444,7 @@ msgid "" "Height of initial layer. Making initial layer height to be thick slightly " "can improve build plate adhension" msgstr "" -"This is the height of the first layer. Making the first layer hight higher " +"This is the height of the first layer. Making the first layer height thicker " "can improve build plate adhesion." msgid "Adaptive layer height" @@ -5296,7 +5460,7 @@ msgstr "" "Enabling this option means that the height of each layer after the first " "will be automatically calculated according to the slope of the model’s " "surface.\n" -"Please not that this option only takes effect if there is no prime tower " +"Please note that this option only takes effect if there is no prime tower " "generated on the current plate." msgid "Speed of initial layer except the solid infill part" @@ -5313,7 +5477,7 @@ msgid "Initial layer nozzle temperature" msgstr "First layer nozzle temperature" msgid "Nozzle temperature to print initial layer when using this filament" -msgstr "Nozzle temperature to print first layer when using this filament" +msgstr "Nozzle temperature for printing the first layer with this filament" msgid "Full fan speed at layer" msgstr "Full fan speed at layer" @@ -5323,7 +5487,8 @@ msgid "" "look. This setting controls the fuzzy position" msgstr "" "This setting makes the toolhead randomly jitter while printing walls so that " -"the surface has a rough look. This setting controls the fuzzy position." +"the surface has a rough textured look. This setting controls the fuzzy " +"position." msgid "None" msgstr "None" @@ -5489,7 +5654,7 @@ msgid "Print speed of ironing lines" msgstr "This is the print speed for ironing lines." msgid "This gcode part is inserted at every layer change after lift z" -msgstr "This G-code is inserted at every layer change after lift z." +msgstr "This G-code is inserted at every layer change after the z lift." msgid "Supports silent mode" msgstr "Silent Mode" @@ -5498,8 +5663,8 @@ msgid "" "Whether the machine supports silent mode in which machine use lower " "acceleration to print" msgstr "" -"Whether the machine supports silent mode in which machine use lower " -"acceleration to print" +"Whether the machine supports silent mode in which machine uses lower " +"acceleration to print more quietly" msgid "Maximum speed X" msgstr "Maximum speed X" @@ -5613,8 +5778,8 @@ msgid "" "Part cooling fan speed may be increased when auto cooling is enabled. This " "is the maximum speed limitation of part cooling fan" msgstr "" -"Part cooling fan speed may be increased when auto cooling is enabled. This " -"is the maximum speed limitation of the part cooling fan." +"The part cooling fan speed may be increased when auto cooling is enabled. " +"This is the maximum speed for the part cooling fan." msgid "Max" msgstr "Max" @@ -5634,9 +5799,9 @@ msgid "" "during printing except the first several layers which is defined by no " "cooling layers" msgstr "" -"Speed of auxiliary part cooling fan. Auxiliary fan will run at this speed " -"during printing except the first several layers which is defined by no " -"cooling layers" +"This is the speed of auxiliary part cooling fan. The auxiliary fan will run " +"at this speed during printing except for during the first several layers " +"which may be set to have no part cooling." msgid "Min" msgstr "Min" @@ -5645,8 +5810,8 @@ msgid "" "The lowest printable layer height for extruder. Used tp limits the minimum " "layer hight when enable adaptive layer height" msgstr "" -"The lowest printable layer height for extruder. Used tp limits the minimum " -"layer hight when enable adaptive layer height" +"The lowest printable layer height for the extruder. This is used to limit " +"the minimum layer height when adaptive layer height is enabled." msgid "Min print speed" msgstr "Min print speed" @@ -5664,7 +5829,7 @@ msgid "Nozzle volume" msgstr "Nozzle volume" msgid "Volume of nozzle between the cutter and the end of nozzle" -msgstr "Volume of nozzle between the cutter and the end of nozzle" +msgstr "Volume of nozzle between the filament cutter and the end of the nozzle" msgid "Reduce infill retraction" msgstr "Reduce infill retraction" @@ -5685,7 +5850,7 @@ msgid "User can self-define the project file name when export" msgstr "Users can decide project file names when exporting." msgid "Detect overhang wall" -msgstr "Detect overhang wall" +msgstr "Detect overhang walls" #, c-format, boost-format msgid "" @@ -5696,7 +5861,7 @@ msgstr "" "different speed to print. For 100%% overhang, bridging speed is used." msgid "Line width of inner wall" -msgstr "Line width of inner wall" +msgstr "Line width of inner walls" msgid "Speed of inner wall" msgstr "This is the speed for inner walls." @@ -5787,8 +5952,8 @@ msgid "" "Some amount of material in extruder is pulled back to avoid ooze during long " "travel. Set zero to disable retraction" msgstr "" -"Some amount of the material in the extruder is pulled back to avoid oozing " -"during long travel. Set to 0 to disable retraction." +"This is the amount of filament in the extruder that is pulled back to avoid " +"oozing during long travel distances. Set to 0 to disable retraction." msgid "Z hop when retract" msgstr "Z hop when retracting" @@ -5834,6 +5999,9 @@ msgstr "Aligned" msgid "Back" msgstr "Back" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Skirt distance" @@ -5873,7 +6041,7 @@ msgstr "Line width of internal solid infill" msgid "Speed of internal solid infill, not the top and bottom surface" msgstr "" -"This is the speed for internal solid infill, but not the top or bottom " +"This is the speed for internal solid infill, not including the top or bottom " "surface." msgid "Spiral vase" @@ -5889,10 +6057,12 @@ msgstr "" "The final generated model has no seam." msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" msgid "Temperature variation" @@ -5902,10 +6072,10 @@ msgid "Start G-code" msgstr "Start G-code" msgid "Start G-code when start the whole printing" -msgstr "Start G-code when starting a print" +msgstr "G-code added when starting a print" msgid "Start G-code when start the printing of this filament" -msgstr "Start G-code when starting printing with this filament" +msgstr "G-code added when the printer starts using this filament" msgid "Enable support" msgstr "Enable support" @@ -5959,15 +6129,14 @@ msgid "Top Z distance" msgstr "Top Z distance" msgid "The z gap between the top support interface and object" -msgstr "" -"This determines the Z gap between the top support interface and the object." +msgstr "This determines the Z gap between top support interfaces and objects." msgid "" "Filament to print support and skirt. 0 means no specific filament for " "support and current filament is used" msgstr "" -"Filament to print support and skirt. 0 means no specific filament for " -"support and current filament is used" +"This is the filament used to print supports and skirts. 0 means no specific " +"filament for support and the current filament is used." msgid "Line width of support" msgstr "Line width of support" @@ -5985,8 +6154,8 @@ msgid "" "Filament to print support interface. 0 means no specific filament for " "support interface and current filament is used" msgstr "" -"Filament to print support interface. 0 means no specific filament for " -"support interface and current filament is used" +"This is the filament to print support interfaces. 0 means no specific " +"filament for support interfaces and the current filament is used" msgid "Top interface layers" msgstr "Top interface layers" @@ -6033,9 +6202,9 @@ msgid "" "interface is Rectilinear, while default pattern for soluble support " "interface is Concentric" msgstr "" -"This is the line pattern for support interface. The default pattern for non-" -"soluble support interface is Rectilinear while the default pattern for " -"soluble support interface is Concentric." +"This is the line pattern for support interfaces. The default pattern for non-" +"soluble support interfaces is Rectilinear while the default pattern for " +"soluble support interfaces is Concentric." msgid "Base pattern spacing" msgstr "Base pattern spacing" @@ -6057,12 +6226,8 @@ msgstr "Independent support layer height" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"The support layer uses layer height independent of object layers. This is to " -"support custom support gaps, but may cause extra filament switches if " -"support is specified as a different extruder from the object." msgid "Threshold angle" msgstr "Threshold angle" @@ -6131,8 +6296,8 @@ msgid "" "may cause the model broken free from build plate" msgstr "" "It is not recommended to have the bed temperature of other layers to be " -"lower than initial layer for more than this threshold. Bed temperatures that " -"are too low may cause models to break free from the build plate." +"lower than the first layer by more than this threshold. Bed temperatures " +"that are too low may cause models to break free from the build plate." msgid "Detect thin wall" msgstr "Detect thin walls" @@ -6166,8 +6331,8 @@ msgid "" "thickness, the top shell layers will be increased" msgstr "" "This is the number of solid layers of top shell, including the top surface " -"layer. When the thickness calculated by this value is thinner than top shell " -"thickness, the top shell layers will be increased" +"layer. When the thickness calculated by this value is thinner than the top " +"shell thickness, the top shell layers will be increased" msgid "Top solid layers" msgstr "Top solid layers" @@ -6184,9 +6349,9 @@ msgid "" msgstr "" "The number of top solid layers is increased when slicing if the thickness " "calculated by top shell layers is thinner than this value. This can avoid " -"having too thin shell when layer height is small. 0 means that this setting " -"is disabled and thickness of top shell is absolutely determained by top " -"shell layers" +"having too thin a shell when layer height is small. 0 means that this " +"setting is disabled and thickness of top shell is determined simply by the " +"number of top shell layers." msgid "Speed of travel which is faster and without extrusion" msgstr "This is the speed at which traveling is done." @@ -6224,7 +6389,8 @@ msgid "Prime volume" msgstr "Prime volume" msgid "The volume of material to prime extruder on tower." -msgstr "This is the volume of material to prime the extruder on the tower." +msgstr "" +"This is the volume of material to prime the extruder with on the tower." msgid "Width" msgstr "Width" @@ -6264,8 +6430,8 @@ msgid "" "as a result" msgstr "" "This object will be used to purge the nozzle after a filament change to save " -"filament and decrease the print time. Colours of the objects will be mixed " -"as a result" +"filament and decrease the print time. Colors of the objects will be mixed as " +"a result." msgid "X-Y hole compensation" msgstr "X-Y hole compensation" @@ -6310,7 +6476,7 @@ msgid "Export 3MF" msgstr "Export 3mf" msgid "Export project as 3MF." -msgstr "This exports the project as a 3mf." +msgstr "This exports the project as a 3mf file." msgid "Slice the plates: 0-all plates, i-plate i, others-invalid" msgstr "Slice the plates: 0-all plates, i-plate i, others-invalid" @@ -6402,9 +6568,14 @@ msgstr "Checking support necessity" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"It seems object %s needs support to print. Please enable support generation." msgid "Optimizing toolpath" msgstr "Optimizing toolpath" @@ -6412,14 +6583,8 @@ msgstr "Optimizing toolpath" msgid "Empty layers around bottom are replaced by nearest normal layers." msgstr "Empty layers around bottom are replaced by nearest normal layers." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." msgid "Slicing mesh" msgstr "Slicing mesh" @@ -6465,35 +6630,57 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "the 3mf is not compatible, load geometry data only!" #~ msgstr "The 3mf is not compatible, loading geometry data only!" +#~ msgid "Save configuration as:" +#~ msgstr "Save configuration as:" + +#~ msgid "Line type" +#~ msgstr "Line type" + +#~ msgid "Designer" +#~ msgstr "Designer" + +#~ msgid "Report" +#~ msgstr "Report" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Device:" + +#~ msgid "Translation" +#~ msgstr "Translation" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "The model has overlapping or self-intersecting facets. Repair was " +#~ "attempted, however we recommend checking the results or repairing the " +#~ "input file and retrying." + #~ msgid "" #~ "Auto orientates selected objects or all objects.If there are selected " #~ "objects, it just orientates the selected ones.Otherwise, it will " #~ "orientates all objects in the project." #~ msgstr "" -#~ "Auto orientates selected objects or all objects.If there are selected " -#~ "objects, it just orientates the selected ones.Otherwise, it will " -#~ "orientates all objects in the project." +#~ "Auto orients selected objects or all objects.If there are selected " +#~ "objects, it just orients the selected ones.Otherwise, it will orient all " +#~ "objects in the project." #~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "The configuration is not compatible; it cannot be loaded!" - -#~ msgid "Auto arrange" -#~ msgstr "Auto Arrange" - -#~ msgid "Filaments Selection" -#~ msgstr "Filaments selection" - -#~ msgid "Printer Selection" -#~ msgstr "Printer Selection" - -#~ msgid "Spiral mode" -#~ msgstr "Spiral mode" - -#~ msgid "Fragment area" -#~ msgstr "Fragment area" - -#~ msgid "Clear all" -#~ msgstr "Clear all" +#~ msgstr "The configuration is not compatible and cannot be loaded!" #~ msgid "Creating" #~ msgstr "Creating" @@ -6501,38 +6688,26 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Uploading" #~ msgstr "Uploading" -#~ msgid "Waiting" -#~ msgstr "Waiting" - #~ msgid "Sending" #~ msgstr "Sending" -#~ msgid "Finished" -#~ msgstr "Finished" - #~ msgid "Please fill report first." #~ msgstr "Please fill report first." #~ msgid "Unable to create zip file" #~ msgstr "Unable to create zip file" -#~ msgid "Enter a search term" -#~ msgstr "Enter a search term" +#~ msgid "Filaments Selection" +#~ msgstr "Filaments selection" -#~ msgid "Debug" -#~ msgstr "Debug" +#~ msgid "Printer Selection" +#~ msgstr "Printer Selection" -#~ msgid "Monitoring" -#~ msgstr "Monitoring" +#~ msgid "Auto arrange" +#~ msgstr "Auto Arrange" -#~ msgid "Fragment filter" -#~ msgstr "Fragment filter" - -#~ msgid "Fragment Filter" -#~ msgstr "Fragment Filter" - -#~ msgid "Position:" -#~ msgstr "Position:" +#~ msgid "Spiral mode" +#~ msgstr "Spiral mode" #~ msgid "Alt + Mouse wheel" #~ msgstr "Alt + Mouse wheel" @@ -6546,6 +6721,9 @@ msgstr "Support: propagate branches at layer %d" #~ "Please solve the problem by moving it totally on or off the plate, and " #~ "confirming that the height is within the build volume." +#~ msgid "Clear all" +#~ msgstr "Clear all" + #~ msgid "Ctrl + Any arrow" #~ msgstr "Ctrl + Any arrow" @@ -6587,11 +6765,20 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Fix model through cloud" #~ msgstr "Fix model through cloud" +#~ msgid "Fragment Filter" +#~ msgstr "Fragment Filter" + +#~ msgid "Fragment area" +#~ msgstr "Fragment area" + +#~ msgid "Fragment filter" +#~ msgstr "Fragment filter" + #~ msgid "" #~ "Heat the nozzle to target \n" #~ "temperature" #~ msgstr "" -#~ "Heat the nozzle to target \n" +#~ "Heat the nozzle to the target \n" #~ "temperature" #~ msgid "In the calibration of extrusion flow" @@ -6603,6 +6790,9 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Module" #~ msgstr "Module" +#~ msgid "Monitoring" +#~ msgstr "Monitoring" + #~ msgid "Output file" #~ msgstr "Output file" @@ -6618,15 +6808,18 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Please upgrade your printer first" #~ msgstr "Please upgrade your printer first" +#~ msgid "Position:" +#~ msgstr "Position:" + #~ msgid "" #~ "Preview only mode:\n" #~ "The loaded file contains gcode only." #~ msgstr "" #~ "Preview only mode:\n" -#~ "The loaded file contains gcode only." +#~ "The loaded file contains G-code only." #~ msgid "Preview only mode for gcode file." -#~ msgstr "Preview only mode for gcode file." +#~ msgstr "Preview only mode for G-code file." #~ msgid "" #~ "Push new filament \n" @@ -6652,17 +6845,17 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" #~ msgstr "" -#~ "Successfully sent.Will automatically jump to the device page in %s s" +#~ "Successfully sent. Will automatically jump to the device page in %s s" #~ msgid "Swith cloud environment, Please login again!" -#~ msgstr "Swith cloud environment, Please login again!" +#~ msgstr "Switch cloud environment, Please login again!" #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" #~ msgstr "" -#~ "The firmware versions of printer and AMS are too low.Please update to the " -#~ "latest version before sending the print job" +#~ "The firmware versions of the printer and AMS are too low. Please update " +#~ "them to the latest version before sending any print jobs." #~ msgid "User pause" #~ msgstr "User pause" diff --git a/bbl/i18n/es/BambuStudio_es.po b/bbl/i18n/es/BambuStudio_es.po index fe5cae4c0d..f5f43dc00e 100644 --- a/bbl/i18n/es/BambuStudio_es.po +++ b/bbl/i18n/es/BambuStudio_es.po @@ -2,13 +2,16 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Localazy (https://localazy.com)\n" "Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" +"X-Generator: Poedit 3.1\n" msgid "Supports Painting" msgstr "Pintando Soportes" @@ -74,7 +77,7 @@ msgid "Sphere" msgstr "Esfera" msgid "Fill" -msgstr "Llenar" +msgstr "Fill" msgid "Gap Fill" msgstr "" @@ -143,10 +146,10 @@ msgid "Shortcut Key " msgstr "Tecla de acceso directo " msgid "Triangle" -msgstr "Triángulo" +msgstr "Triangle" msgid "Height Range" -msgstr "Rango de altura" +msgstr "Height Range" msgid "Remove painted color" msgstr "Eliminar color pintado" @@ -331,10 +334,10 @@ msgid "Operation already cancelling. Please wait few seconds." msgstr "Operación ya cancelada. Por favor, espere unos segundos." msgid "Face recognition" -msgstr "Reconocimiento facial" +msgstr "Face recognition" msgid "Perform Recognition" -msgstr "Realizar el reconocimiento" +msgstr "Perform Recognition" msgid "Reset direction" msgstr "" @@ -366,6 +369,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Añadir" + msgid "Notice" msgstr "Date cuenta" @@ -528,8 +546,8 @@ msgid "" "The version of Bambu studio is too low and needs to be updated to the latest " "version before it can be used normally" msgstr "" -"La versión de Bambu Studio es una versión demasiado antigua y necesita ser " -"actualizada a la última versión antes de poder utilizarla con normalidad" +"The version of Bambu Studio is too low and needs to be updated to the latest " +"version before it can be used normally" msgid "Login information expired. Please login again." msgstr "Los datos de acceso han caducado. Por favor, inicie sesión de nuevo." @@ -538,7 +556,7 @@ msgid "Loading" msgstr "Cargando" msgid "Loading user preset" -msgstr "Cargando la preselección del usuario" +msgstr "Loading user preset" msgid "Switching application language" msgstr "Cambio de idioma de la aplicación" @@ -649,9 +667,6 @@ msgstr "Cilindro" msgid "Cone" msgstr "Cono" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse Torre de limpieza" - msgid "Add settings" msgstr "Añadir ajustes" @@ -1067,7 +1082,7 @@ msgid "Push new filament into extruder" msgstr "" msgid "Purge old filament" -msgstr "Purgar el filamento viejo" +msgstr "Purge old filament" msgid "?" msgstr "?" @@ -1079,10 +1094,10 @@ msgid "Click the pencil icon to edit the filament." msgstr "Haga clic en el icono del lápiz para editar el filamento." msgid "Load Filament" -msgstr "Cargar filamento" +msgstr "Load" msgid "Unload Filament" -msgstr "Descargar" +msgstr "Unload" msgid "Tips" msgstr "Consejos" @@ -1192,67 +1207,62 @@ msgid "Exception" msgstr "Excepción" msgid "Logging in" -msgstr "Iniciando sesión" +msgstr "Logging in" msgid "Login failed" -msgstr "Fallo en el inicio de sesión" +msgstr "Login failed" msgid "The region parameter is incorrrect" -msgstr "El parámetro de región es incorrecto." +msgstr "The region parameter is incorrrect." msgid "Failure of printer login" -msgstr "Fallo en el inicio de sesión de la impresora" +msgstr "Printer login failure" msgid "Failed to get ticket" -msgstr "No se ha podido conseguir el ticket" +msgstr "Failed to get ticket" msgid "User authorization timeout" -msgstr "Límite de tiempo de espera de la autorización del usuario" +msgstr "User authorization timeout" msgid "Failure of bind" -msgstr "Fallo en la vinculación" +msgstr "Binding failure" msgid "Unknown Failure" -msgstr "Error desconocido" +msgstr "Unknown Failure" msgid "Abnormal print file data. Please slice again" -msgstr "Datos anormales del archivo de impresión. Por favor, procese de nuevo" +msgstr "Abnormal print file data. Please slice again" msgid "Task canceled" -msgstr "Tarea cancelada" +msgstr "Task canceled" msgid "Upload task timed out. Please check the network problem and try again" -msgstr "" -"La tarea de carga ha terminado. Por favor, compruebe el problema de red e " -"inténtelo de nuevo" +msgstr "Upload task timed out. Please check the network and try again" msgid "Cloud service connection failed. Please try again." -msgstr "" -"Ha fallado la conexión con el servicio de la nube. Por favor, inténtelo de " -"nuevo." +msgstr "Cloud service connection failed. Please try again." msgid "Print file not found, please slice again" -msgstr "" -"No se ha encontrado el archivo de impresión, por favor, vuelva a procesarlo" +msgstr "Print file not found, please slice again" msgid "" "The print file exceeds the maximum allowable size (1GB). Please simplify the " "model and slice again" msgstr "" -"El archivo de impresión supera el tamaño máximo permitido (1GB). Por favor, " -"simplifique el modelo y vuelva a procesarlo" +"The print file exceeds the maximum allowable size (1GB). Please simplify the " +"model and slice again" msgid "Failed uploading print file" -msgstr "Fallo al cargar el archivo de impresión" +msgstr "Failed uploading print file" msgid "Wrong Access code" -msgstr "Código de acceso incorrecto" +msgstr "Wrong Access code" msgid "Sending print job over LAN" -msgstr "Enviando el trabajo de impresión a través de la LAN" +msgstr "Sending print job over LAN" msgid "Sending print job through cloud service" -msgstr "Enviando trabajo de impresión a través del servicio en la nube" +msgstr "Sending print job through cloud service" msgid "Service Unavailable" msgstr "" @@ -1260,8 +1270,11 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" -msgstr "Enviando la configuración de impresión" +msgstr "Sending print configuration" #, c-format, boost-format msgid "Successfully sent. Will automatically jump to the device page in %s s" @@ -1298,7 +1311,7 @@ msgid "License" msgstr "Licencia" msgid "Bambu Studio is licensed under " -msgstr "Bambu Studio tiene licencia bajo " +msgstr "Bambu Studio is licensed under " msgid "GNU Affero General Public License, version 3" msgstr "GNU Affero General Public License, versión 3" @@ -1307,18 +1320,18 @@ msgid "" "Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " "by Alessandro Ranellucci and the RepRap community" msgstr "" -"Bambu Studio se basa en PrusaSlicer de Prusa Research, que proviene de " -"Slic3r de Alessandro Ranellucci y la comunidad RepRap" +"Bambu Studio is based on PrusaSlicer by Prusa Research, which is based on " +"Slic3r by Alessandro Ranellucci and the RepRap community" msgid "Libraries" -msgstr "Librerías" +msgstr "Libraries" msgid "" "This software uses open source components whose copyright and other " "proprietary rights belong to their respective owners" msgstr "" -"Este software utiliza componentes de código abierto cuyos derechos de autor " -"y otros derechos de propiedad pertenecen a sus respectivos propietarios" +"This software uses open source components whose copyright and other " +"proprietary rights belong to their respective owners" #, c-format, boost-format msgid "About %s" @@ -1356,8 +1369,8 @@ msgid "" "Nozzle\n" "Temperature" msgstr "" -"Boquilla\n" -"Temperatura" +"Nozzle\n" +"Temperature" msgid "max" msgstr "max" @@ -1367,7 +1380,7 @@ msgstr "min" #, boost-format msgid "The input value should be greater than %1% and less than %2%" -msgstr "El valor de entrada debe ser mayor que %1% y menor que %2%" +msgstr "The input value should be greater than %1% and less than %2%" msgid "SN" msgstr "SN" @@ -1385,50 +1398,62 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" -msgstr "Actualización de la inserción" +msgstr "Insertion update" msgid "" "The AMS will automatically read the filament information when inserting a " "new Bambu Lab filament. This takes about 20 seconds." msgstr "" -"El AMS leerá automáticamente la información del filamento al insertar un " -"nuevo filamento de Bambu Lab. Esto tardara unos 20 segundos." +"The AMS will automatically read the filament information when inserting a " +"new Bambu Lab filament spool. This takes about 20 seconds." msgid "" "Note: if new filament is inserted during printing, the AMS will not " "automatically read any information until printing is completed." msgstr "" -"Nota: si se inserta un nuevo filamento durante la impresión, el AMS no leerá " -"automáticamente ninguna información hasta que la impresión haya finalizado." +"Note: if new filament is inserted during printing, the AMS will not " +"automatically read any information until printing has finished." msgid "" "When inserting a new filament, the AMS will not automatically read its " "information, leaving it blank for you to enter manually." msgstr "" -"Al insertar un nuevo filamento, el AMS no leerá automáticamente su " -"información, dejándola en blanco para que usted la introduzca manualmente." +"When inserting a new filament, the AMS will not automatically read its " +"information, leaving it blank for you to enter manually." msgid "Power on update" -msgstr "Actualización de encendido" +msgstr "Power on update" msgid "" "The AMS will automatically read the information of inserted filament on " "start-up. It will take about 1 minute.The reading process will roll filament " "spools." msgstr "" -"El AMS leerá automáticamente la información del filamento insertado al " -"arrancar. Tomará aproximadamente 1 minuto. El proceso de lectura hará rodar " -"las bobinas de filamento." +"The AMS will automatically read the information of inserted filament on " +"start-up. It will take about 1 minute.The reading process will rotate the " +"filament spools." msgid "" "The AMS will not automatically read information from inserted filament " "during startup and will continue to use the information recorded before the " "last shutdown." msgstr "" -"El AMS no leerá automáticamente la información del filamento insertado " -"durante el arranque y seguirá utilizando la información registrada antes del " -"último apagado." +"The AMS will not automatically read information from inserted filament " +"during startup and will continue to use the information recorded before the " +"last shutdown." msgid "File" msgstr "Archivo" @@ -1735,70 +1760,67 @@ msgstr "" "del 100%.\n" msgid "Auto bed leveling" -msgstr "Nivelación de cama automática" +msgstr "Auto bed leveling" msgid "Heatbed preheating" -msgstr "Precalentamiento de la cama caliente" +msgstr "Heatbed preheating" msgid "Sweeping XY mech mode" -msgstr "Barrido en XY modo mecánico" +msgstr "Sweeping XY mech mode" msgid "Changing filament" -msgstr "Cambiando el filamento" +msgstr "Changing filament" msgid "M400 pause" -msgstr "Pausa M400" +msgstr "M400 pause" msgid "Paused due to filament runout" -msgstr "Pausa por agotamiento del filamento" +msgstr "Paused due to filament runout" msgid "Heating hotend" -msgstr "Calentando boquilla" +msgstr "Heating hotend" msgid "Calibrating extrusion" -msgstr "Calibrando la extrusión" +msgstr "Calibrating extrusion" msgid "Scanning bed surface" -msgstr "Escaneando la superficie de la cama" +msgstr "Scanning bed surface" msgid "Inspecting first layer" -msgstr "Inspeccionando la primera capa" +msgstr "Inspecting first layer" msgid "Identifying build plate type" -msgstr "Identificando el tipo de placa de impresión" +msgstr "Identifying build plate type" msgid "Calibrating Micro Lidar" -msgstr "Calibrando el Micro Lidar" +msgstr "Calibrating Micro Lidar" msgid "Homing toolhead" -msgstr "Homing del Cabezal" +msgstr "Homing toolhead" msgid "Cleaning nozzle tip" -msgstr "Limpiando la boquilla" +msgstr "Cleaning nozzle tip" msgid "Checking extruder temperature" -msgstr "Comprobando la temperatura del extrusor" +msgstr "Checking extruder temperature" msgid "Printing was paused by the user" -msgstr "El usuario ha interrumpido la impresión" +msgstr "Printing was paused by the user" msgid "Pause of front cover falling" -msgstr "Pausa al caer la cubierta frontal" +msgstr "Pause of front cover falling" msgid "Calibrating the micro lida" -msgstr "Calibrando el micro lidar" +msgstr "Calibrating the micro lidar" msgid "Calibrating extrusion flow" -msgstr "Calibrando el flujo de extrusión" +msgstr "Calibrating extrusion flow" msgid "Paused due to nozzle temperature malfunction" -msgstr "" -"Pausado debido a un mal funcionamiento de la temperatura de la boquilla" +msgstr "Paused due to nozzle temperature malfunction" msgid "Paused due to heat bed temperature malfunction" -msgstr "" -"Se ha interrumpido debido a un mal funcionamiento de la temperatura de la " -"cama caliente" +msgstr "Paused due to heat bed temperature malfunction" msgid "MC" msgstr "MC" @@ -1933,9 +1955,6 @@ msgstr "Tiempo" msgid "Display" msgstr "Pantalla" -msgid "Line type" -msgstr "Tipo de línea" - msgid "Layer Height (mm)" msgstr "Altura de la capa (mm)" @@ -1997,10 +2016,10 @@ msgid "Filament 1" msgstr "Filamento 1" msgid "Flushed filament" -msgstr "Filamento limpiado" +msgstr "Flushed filament" msgid "Filament change times" -msgstr "Tiempos de cambio de filamento" +msgstr "Filament change times" msgid "Color change" msgstr "Cambio de color" @@ -2023,6 +2042,9 @@ msgstr "Estimación total" msgid "Normal mode" msgstr "Modo normal" +msgid "Cost" +msgstr "Coste" + msgid "Prepare time" msgstr "Planificar tiempo" @@ -2077,9 +2099,6 @@ msgstr "Permitir varios materiales en la misma placa" msgid "Avoid extrusion calibration region" msgstr "Evitar la zona de calibración del extrusor" -msgid "Add" -msgstr "Añadir" - msgid "Add plate" msgstr "Añadir placa" @@ -2154,9 +2173,9 @@ msgid "" "minimize deviation.\n" "It keeps the device performing optimally." msgstr "" -"El programa de calibración detecta el estado de su dispositivo " -"automáticamente para minimizar la desviación.\n" -"Mantiene el dispositivo con un rendimiento óptimo." +"The calibration program detects the status of your device automatically to " +"minimize deviation.\n" +"It keeps the device performing optimally." msgid "Calibration Flow" msgstr "Calibración del flujo" @@ -2174,24 +2193,33 @@ msgid "Timelapse" msgstr "Timelapse" msgid "Monitoring Recording" -msgstr "Monitoreo de grabación" +msgstr "Monitoring Recording" msgid "ConnectPrinter(LAN)" -msgstr "Conectar Impresora (LAN)" +msgstr "Connect Printer (LAN)" msgid "Please input the printer access code:" -msgstr "Por favor, introduzca el código de acceso a la impresora:" +msgstr "Please input the printer access code:" msgid "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" msgstr "" -"Puede encontrarse en \"Configuración > Red > Código de conexión\"\n" -"en la impresora, como se muestra en la figura:" +"You can find it in \"Settings > Network > Connection code\"\n" +"on the printer, as shown in the figure:" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Teclea un término de búsqueda" + +msgid "Online" +msgstr "En línea" + +msgid "Offline" +msgstr "Fuera de línea" + msgid "Application is closing" msgstr "La aplicación se está cerrando" @@ -2208,11 +2236,14 @@ msgid "Preview" msgstr "Previsualización" msgid "Device" -msgstr "Dispositivo" +msgstr "Device" msgid "Project" msgstr "Proyecto" +msgid "Debug" +msgstr "Depurar" + msgid "Slice" msgstr "Laminar" @@ -2250,6 +2281,12 @@ msgstr "Comprobar Actualicaciones" msgid "&About %s" msgstr "&Acerca de %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Vista por Defecto" @@ -2321,9 +2358,24 @@ msgstr "Importar 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Cargar un modelo" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "Exportar todos los objetos como STL" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Exportar el archivo rebanado actual" @@ -2333,6 +2385,12 @@ msgstr "Exportar código G" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exportar" @@ -2399,27 +2457,12 @@ msgstr "Utilizar Vista Ortogonal" msgid "Preferences" msgstr "Preferencias" -msgid "About" -msgstr "" - msgid "View" msgstr "Vista" msgid "Help" msgstr "Ayuda" -msgid "&File" -msgstr "&Archivo" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "Ve&r" - -msgid "&Help" -msgstr "Ayu&da" - msgid "&Open G-code" msgstr "Abrir código G (&O)" @@ -2451,8 +2494,48 @@ msgstr "Sa&lir" msgid "Quit %s" msgstr "Cerrar %s" -msgid "Save configuration as:" -msgstr "Guardar la configuración como:" +msgid "&File" +msgstr "&Archivo" + +msgid "&View" +msgstr "Ve&r" + +msgid "&Help" +msgstr "Ayu&da" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Falta el archivo" @@ -2497,47 +2580,93 @@ msgstr "Reproduciendo..." msgid "Load failed [%d]!" msgstr "¡La carga ha fallado [%d]!" -msgid "3Dconnexion settings" -msgstr "Ajustes de conexión 3D" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Dispositivo:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Descargar" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Esperando" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Terminado" msgid "Speed:" msgstr "Velocidad:" -msgid "Translation" -msgstr "Translación" - -msgid "Zoom" -msgstr "Zoom" - msgid "Deadzone:" msgstr "Punto muerto:" msgid "Options:" msgstr "Opciones:" +msgid "Zoom" +msgstr "Zoom" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "Ajustes de conexión 3D" + msgid "Swap Y/Z axes" msgstr "Intercambiar los ejes Y/Z" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Progreso de impresión" -msgid "Report" -msgstr "Informe" +msgid "Resume" +msgstr "Reanudar" msgid "Stop" msgstr "Detener" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" @@ -2575,9 +2704,6 @@ msgstr "Imprimiendo Lista" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Reanudar" - msgid "Silent" msgstr "Silencio" @@ -2608,9 +2734,6 @@ msgstr "No se ha podido conectar con el servidor" msgid "Failed to connect to the printer" msgstr "No se ha podido conectar a la impresora" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "OK" @@ -2644,9 +2767,6 @@ msgstr "%s info" msgid "%s information" msgstr "%s información" -msgid "Download" -msgstr "Descargar" - msgid "Skip" msgstr "Saltar" @@ -2843,9 +2963,6 @@ msgstr "Filamento Usado (g)" msgid "Used Materials" msgstr "Materiales usados" -msgid "Cost" -msgstr "Coste" - msgid "Estimated time" msgstr "Tiempo estimado" @@ -2905,6 +3022,12 @@ msgstr "Será mejor que actualices tu software.\n" msgid "Newer 3mf version" msgstr "Nueva versión 3mf" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -2953,7 +3076,7 @@ msgid "Object with multiple parts was detected" msgstr "Se ha detectado un objeto con varias partes" msgid "The file does not contain any geometry data." -msgstr "El archivo no contiene ninguna información geométrica." +msgstr "The file does not contain any geometry data." msgid "" "Your object appears to be too large, Do you want to scale it down to fit the " @@ -3048,10 +3171,10 @@ msgid "G-code files can not be loaded with models together!" msgstr "¡Los archivos de código G no pueden cargarse con los modelos juntos!" msgid "Can not add models when in preview mode!" -msgstr "No se pueden añadir modelos en el modo de vista previa" +msgstr "Unable to add models in preview mode" msgid "Add Models" -msgstr "Añadir Modelos" +msgstr "Add Models" msgid "All objects will be removed, continue?" msgstr "Todos los objetos serán eliminados, deseas continuar?" @@ -3114,9 +3237,7 @@ msgstr "Tamaño: %1% x %2% x %3% mm\n" #, boost-format msgid "Volume: %1% in³\n" -msgstr "" -"Volumen: %1% pulgadas³\n" -" \n" +msgstr "Volume: %1% in³\n" #, boost-format msgid "Volume: %1% mm³\n" @@ -3144,34 +3265,34 @@ msgid "Changing application language" msgstr "Cambiar el idioma de la aplicación" msgid "Changing the region will log out your account.\n" -msgstr "Si cambias de región, saldrás de tu cuenta.\n" +msgstr "Changing the region will log you out of your account.\n" msgid "Region selection" -msgstr "Selección de región" +msgstr "Region selection" msgid "Second" msgstr "Segundo" msgid "General Settings" -msgstr "Configuración General" +msgstr "General Settings" msgid "Asia-Pacific" -msgstr "Asia-Pacífico" +msgstr "Asia-Pacific" msgid "China" msgstr "China" msgid "Europe" -msgstr "Europa" +msgstr "Europe" msgid "North America" -msgstr "América del Norte" +msgstr "North America" msgid "Others" msgstr "Otros" msgid "Login Region" -msgstr "Región de inicio de sesión" +msgstr "Login Region" msgid "Metric" msgstr "Métrico" @@ -3186,12 +3307,10 @@ msgid "User sync" msgstr "Sincronización del usuario" msgid "Auto sync user presets(Printer/Filament/Process)" -msgstr "" -"Sincronización automática de los preajustes del usuario (Impresora/Filamento/" -"Proceso)" +msgstr "Auto sync user presets (Printer/Filament/Process)" msgid "User Sync" -msgstr "Sincronización de usuario" +msgstr "User Sync" msgid "Associate files to BambuStudio" msgstr "Asociar archivos a BambuStudio" @@ -3213,7 +3332,7 @@ msgstr "" "archivos .stl" msgid "Associate .step/.stp files to BambuStudio" -msgstr "Asociar archivos .step/.stp a BambuStudio" +msgstr "Associate .step/.stp files to Bambu Studio" msgid "If enabled, sets BambuStudio as default application to open .step files" msgstr "" @@ -3290,7 +3409,7 @@ msgid "trace" msgstr "traza" msgid "Host Setting" -msgstr "Ajuste del Host" +msgstr "Host Setting" msgid "DEV host: api-dev.bambu-lab.com/v1" msgstr "DEV host: api-dev.bambu-lab.com/v1" @@ -3450,12 +3569,6 @@ msgstr "Para \"%1%\", añada \"%2%\" como un nuevo preajuste" msgid "Simply switch to \"%1%\"" msgstr "Simplemente cambia a \"%1%\"" -msgid "Online" -msgstr "En línea" - -msgid "Offline" -msgstr "Fuera de línea" - msgid "My Device" msgstr "Mi dispositivo" @@ -3463,13 +3576,13 @@ msgid "Other Device" msgstr "Otro dispositivo" msgid "Input access code" -msgstr "Introducir el código de acceso" +msgstr "Input access code" msgid "Log out successful." msgstr "Cierre de sesión con éxito." msgid "Busy" -msgstr "Ocupado" +msgstr "Busy" msgid "Bambu Cool Plate" msgstr "Placa frío Bambu" @@ -3484,7 +3597,7 @@ msgid "Send print job to" msgstr "Enviar el trabajo de impresión a" msgid "Refresh" -msgstr "Actualizar" +msgstr "Refresh" msgid "Bed Leveling" msgstr "Nivelación de la cama" @@ -3499,31 +3612,27 @@ msgid "send completed" msgstr "envío completo" msgid "No login account, only printers in LAN mode are displayed" -msgstr "Sin cuenta de acceso, sólo se muestran las impresoras en modo LAN" +msgstr "No login account, only printers in LAN mode are displayed" msgid "Connecting to server" -msgstr "Conectando al servidor" +msgstr "Connecting to server" msgid "Synchronizing device information" -msgstr "Sincronizando la información del dispositivo" +msgstr "Synchronizing device information" msgid "Synchronizing device information time out" -msgstr "" -"Finalización del tiempo de sincronización de la información del dispositivo" +msgstr "Synchronizing device information time out" msgid "Cannot send the print task when the upgrade is in progress" -msgstr "" -"No se puede enviar la tarea de impresión cuando la actualización está en " -"curso" +msgstr "Cannot send the print task when the upgrade is in progress" msgid "" "The printer is executing instructions. Please restart printing after it ends" msgstr "" -"La impresora está ejecutando instrucciones. Por favor, reinicie la impresión " -"cuando termine" +"The printer is executing instructions. Please restart printing after it ends" msgid "The printer is busy on other print job" -msgstr "La impresora está ocupada con otro trabajo de impresión." +msgstr "The printer is busy with another print job." #, c-format, boost-format msgid "" @@ -3540,15 +3649,15 @@ msgid "" "Filaments to AMS slots mappings have been established. You can click a " "filament above to change its mapping AMS slot" msgstr "" -"Se han establecido mapeos de filamentos a ranuras AMS. Puede hacer clic en " -"un filamento de arriba para cambiar su asignación de ranura AMS" +"Filaments to AMS slots mappings have been established. You can click a " +"filament above to change its mapping AMS slot" msgid "" "Please click each filament above to specify its mapping AMS slot before " "sending the print job" msgstr "" -"Por favor, haga clic en cada filamento de arriba para especificar su " -"asignación de ranura AMS antes de enviar el trabajo de impresión" +"Please click each filament above to specify its mapping AMS slot before " +"sending the print job" #, c-format, boost-format msgid "" @@ -3567,10 +3676,10 @@ msgid "" msgstr "" msgid "Preparing print job" -msgstr "Preparando el trabajo de impresión" +msgstr "Preparing print job" msgid "Modifying the device name" -msgstr "Modificar el nombre del dispositivo" +msgstr "Modifying the device name" msgid "Log in printer" msgstr "Iniciar sesión en la impresora" @@ -3606,6 +3715,15 @@ msgstr "Guardar %s actuales" msgid "Delete this preset" msgstr "Borra este ajuste" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3693,7 +3811,7 @@ msgid "Reserved keywords found" msgstr "Palabras clave utilizadas y encontradas" msgid "Setting Overrides" -msgstr "Anulaciones de configuración" +msgstr "Setting Overrides" msgid "Retraction" msgstr "Retracción" @@ -3728,9 +3846,8 @@ msgid "" "Bed temperature when cool plate is installed. Value 0 means the filament " "does not support to print on the Cool Plate" msgstr "" -"Esta es la temperatura de la cama cuando la placa fría está instalada. Un " -"valor de 0 significa que el filamento no admite la impresión en la placa " -"fría." +"This is the bed temperature when the cool plate is installed. A value of 0 " +"means the filament does not support printing on the Cool Plate." msgid "Engineering plate" msgstr "Placa de ingeniería" @@ -3739,9 +3856,8 @@ msgid "" "Bed temperature when engineering plate is installed. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Esta es la temperatura de la cama cuando la placa de ingeniería está " -"instalada. Un valor de 0 significa que el filamento no admite la impresión " -"en la placa de ingeniería." +"This is the bed temperature when the engineering plate is installed. A value " +"of 0 means the filament does not support printing on the Engineering Plate." msgid "High Temp Plate" msgstr "Placa de alta temperatura" @@ -3750,9 +3866,17 @@ msgid "" "Bed temperature when high temperature plate is installed. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Esta es la temperatura de la cama cuando la placa de alta temperatura está " -"instalada. Un valor de 0 significa que el filamento no admite la impresión " -"en la placa de alta temperatura." +"This is the bed temperature when the high temperature plate is installed. A " +"value of 0 means the filament does not support printing on the High Temp " +"Plate." + +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Volumetric speed limitation" msgstr "Limitación de la velocidad volumétrica" @@ -3864,7 +3988,7 @@ msgstr "¿Está seguro de %1% el preajuste seleccionado?" #. TRN Remove/Delete #, boost-format msgid "%1% Preset" -msgstr "%1% Preestablecido" +msgstr "%1% Preset" msgid "All" msgstr "Todo" @@ -3981,6 +4105,12 @@ msgstr "General" msgid "Capabilities" msgstr "Capacidades" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Ajustar como cubierta" @@ -3992,7 +4122,7 @@ msgid "The name \"%1%\" already exists." msgstr "El nombre \"%1%\" ya existe." msgid "Basic Info" -msgstr "Información Básica" +msgstr "Basic Info" msgid "Pictures" msgstr "Fotos" @@ -4006,8 +4136,8 @@ msgstr "Guía de montaje" msgid "Choose files" msgstr "Elija los archivos" -msgid "Designer" -msgstr "Diseñador" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Nombre del modelo" @@ -4110,6 +4240,9 @@ msgstr "Copiar al portapapeles" msgid "Paste from clipboard" msgstr "Pegar desde el portapapeles" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Muestra lista de atajos de teclado" @@ -4251,6 +4384,9 @@ msgstr "⌘+Rueda del ratón" msgid "Support/Color Painting: adjust pen radius" msgstr "Soporte/Pintado en color: ajuste del radio de la pluma" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Soporte/Pintado de color: ajuste de la posición de la sección" @@ -4463,7 +4599,7 @@ msgid "Support transition" msgstr "Apoyo a la transición" msgid "Multiple" -msgstr "Múltiple" +msgstr "Multiple" #, boost-format msgid "Failed to calculate line width of %1%. Can not get value of \"%2%\" " @@ -4580,11 +4716,11 @@ msgstr "" #, boost-format msgid "%1% is too close to others, and collisions may be caused." -msgstr "%1% está demasiado cerca de otros, y pueden producirse colisiones." +msgstr "%1% is too close to others, and collisions may be caused." #, boost-format msgid "%1% is too tall, and collisions will be caused." -msgstr "%1% es demasiado alto, y se producirán colisiones." +msgstr "%1% is too tall, and collisions will be caused." msgid " is too close to others, there will be collisions when printing.\n" msgstr " está demasiado cerca de otros, habrá colisiones al imprimir.\n" @@ -4598,11 +4734,10 @@ msgid "Prime Tower" msgstr "Torre principal" msgid " is too close to others, and collisions may be caused.\n" -msgstr "está demasiado cerca de otros, y se pueden producir colisiones.\n" +msgstr " is too close to others, and collisions may be caused.\n" msgid " is too close to exclusion area, and collisions will be caused.\n" -msgstr "" -" está demasiado cerca del área de exclusión, y se producirán colisiones.\n" +msgstr " is too close to an exclusion area, and collisions will be caused.\n" msgid "" "Can not print multiple filaments which have large difference of temperature " @@ -4764,9 +4899,8 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Cool Plate" msgstr "" -"Esta es la temperatura de la cama para las capas excepto la inicial. Un " -"valor de 0 significa que el filamento no admite la impresión en la placa " -"fría." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Cool Plate." msgid "°C" msgstr "°C" @@ -4778,17 +4912,20 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Esta es la temperatura de la cama para las capas excepto la inicial. Un " -"valor de 0 significa que el filamento no admite la impresión en la placa de " -"ingeniería." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Engineering Plate." msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Esta es la temperatura de la cama para las capas excepto la inicial. Un " -"valor de 0 significa que el filamento no admite la impresión en la placa de " -"alta temperatura." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Initial layer" msgstr "Capa inicial" @@ -4800,23 +4937,27 @@ msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Cool Plate" msgstr "" -"Esta es la temperatura de la cama de la capa inicial. Un valor de 0 " -"significa que el filamento no admite la impresión en la placa fría." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Cool Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Engineering Plate" msgstr "" -"Esta es la temperatura de la cama de la capa inicial. Un valor de 0 " -"significa que el filamento no admite la impresión en la placa de ingeniería." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Engineering Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the High Temp Plate" msgstr "" -"Esta es la temperatura de la cama de la capa inicial. Un valor de 0 " -"significa que el filamento no admite la impresión en la placa de alta " -"temperatura." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" msgid "Bed types supported by the printer" msgstr "Tipos de cama que admite la impresora" @@ -5067,9 +5208,9 @@ msgid "" "bridges to be supported, and set it to a very large value if you don't want " "any bridges to be supported." msgstr "" -"Esta es la longitud máxima de los puentes que no necesitan soporte. Ajústalo " -"a 0 si quieres que todos los puentes sean soportados, y ajústalo a un valor " -"muy grande si no quieres que ningún puente sea soportado." +"This is the maximum length of bridges that don't need support. Set it to 0 " +"if you want all bridges to be supported, and set it to a very large value if " +"you don't want any bridges to be supported." msgid "End G-code" msgstr "Código G final" @@ -5293,8 +5434,7 @@ msgstr "Material de soporte" msgid "" "Support material is commonly used to print support and support interface" msgstr "" -"El material de soporte se utiliza habitualmente para imprimir el soporte y " -"interficies de soporte" +"Support material is commonly used to print support and support interfaces." msgid "Temperature of vitrificaiton" msgstr "Temperatura de vitrificación" @@ -5451,7 +5591,7 @@ msgstr "" "de la anchura de la línea de la pared exterior" msgid "Fuzzy skin point distance" -msgstr "Distancia al punto de superficie irregular" +msgstr "Fuzzy skin point distance" msgid "" "The average diatance between the random points introducded on each line " @@ -5957,6 +6097,9 @@ msgstr "Alineado" msgid "Back" msgstr "Volver" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Distancia de la falda" @@ -6010,15 +6153,13 @@ msgstr "" "sólidas. El modelo final generado no tiene costura" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Record timelapse video of printing without showing the toolhead. In this " -"mode the toolhead docks near the excess chute at each layer change, and then " -"a snapshot is taken with the chamber camera. When printing finishes, a " -"timelapse video is created from all the snapshots." msgid "Temperature variation" msgstr "Variación de temperatura" @@ -6184,13 +6325,8 @@ msgstr "Altura de la capa de soporte independiente" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"La capa de soporte utiliza la altura de la capa independientemente de la " -"capa del objeto. Esto es para soportar la brecha de soporte personalizada, " -"pero puede causar cambios de filamento adicionales si el soporte se " -"especifica como un extrusor diferente con el objeto" msgid "Threshold angle" msgstr "Ángulo de umbral" @@ -6381,27 +6517,26 @@ msgstr "" "mezclado se podrá ver en el exterior." msgid "Flush into objects' support" -msgstr "Depositar en el soporte de los objetos" +msgstr "Flush into objects' support" msgid "" "Purging after filament change will be done inside objects' support. This may " "lower the amount of waste and decrease the print time" msgstr "" -"La purga después del cambio de filamento se hará dentro del soporte de los " -"objetos. Esto puede reducir la cantidad de residuos y disminuir el tiempo de " -"impresión." +"Purging after filament change will be done inside objects' support. This may " +"lower the amount of waste and decrease the print time." msgid "Flush into this object" -msgstr "Descarga en este objeto" +msgstr "Flush into this object" msgid "" "This object will be used to purge the nozzle after a filament change to save " "filament and decrease the print time. Colours of the objects will be mixed " "as a result" msgstr "" -"Este objeto se utilizará para purgar la boquilla después de un cambio de " -"filamento para ahorrar filamento y disminuir el tiempo de impresión. Los " -"colores de los objetos se mezclarán como resultado" +"This object will be used to purge the nozzle after a filament change to save " +"filament and decrease the print time. Colors of the objects will be mixed as " +"a result." msgid "X-Y hole compensation" msgstr "Compensación de huecos X-Y" @@ -6541,10 +6676,14 @@ msgstr "Comprobación de la necesidad de soporte" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Parece que el objeto %s necesita soporte para imprimir. Por favor, active la " -"generación de soporte." msgid "Optimizing toolpath" msgstr "Optimización de la trayectoria de la herramienta" @@ -6553,14 +6692,8 @@ msgid "Empty layers around bottom are replaced by nearest normal layers." msgstr "" "Las capas vacías del fondo se sustituyen por las capas normales más cercanas." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"El modelo tiene facetas superpuestas o auto-intersecadas. He intentado " -"repararlo, sin embargo, es posible que desee comprobar los resultados o " -"reparar el archivo de entrada y volver a intentarlo." msgid "Slicing mesh" msgstr "Malla de corte" @@ -6603,6 +6736,88 @@ msgstr "Soporte: arreglar huecos en la capa %d" msgid "Support: propagate branches at layer %d" msgstr "Soporte: propagar ramas en la capa %d" +#~ msgid "the 3mf is not compatible, load geometry data only!" +#~ msgstr "el 3mf no es compatible, ¡cargue sólo los datos geométricos!" + +#~ msgid "Save configuration as:" +#~ msgstr "Guardar la configuración como:" + +#~ msgid "Line type" +#~ msgstr "Tipo de línea" + +#~ msgid "Designer" +#~ msgstr "Diseñador" + +#~ msgid "Report" +#~ msgstr "Informe" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Dispositivo:" + +#~ msgid "Translation" +#~ msgstr "Translación" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "" +#~ "Parece que el objeto %s necesita soporte para imprimir. Por favor, active " +#~ "la generación de soporte." + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "El modelo tiene facetas superpuestas o auto-intersecadas. He intentado " +#~ "repararlo, sin embargo, es posible que desee comprobar los resultados o " +#~ "reparar el archivo de entrada y volver a intentarlo." + +#~ msgid "" +#~ "Auto orientates selected objects or all objects.If there are selected " +#~ "objects, it just orientates the selected ones.Otherwise, it will " +#~ "orientates all objects in the project." +#~ msgstr "" +#~ "Orienta automáticamente los objetos seleccionados o todos los objetos.Si " +#~ "hay objetos seleccionados, sólo orienta los seleccionados.En caso " +#~ "contrario, orienta todos los objetos del proyecto." + +#~ msgid "The Config is not compatible and can not be loaded." +#~ msgstr "La configuración no es compatible y no se puede cargar." + +#~ msgid "Creating" +#~ msgstr "Creando" + +#~ msgid "Uploading" +#~ msgstr "Subiendo" + +#~ msgid "Sending" +#~ msgstr "Enviando" + +#~ msgid "Please fill report first." +#~ msgstr "Por favor, rellene primero el informe." + +#~ msgid "Unable to create zip file" +#~ msgstr "Unable to create zip file" + +#~ msgid "Filaments Selection" +#~ msgstr "Selección de filamentos" + +#~ msgid "Printer Selection" +#~ msgstr "Selección de la impresora" + +#~ msgid "Auto arrange" +#~ msgstr "Auto posicionamiento" + +#~ msgid "Spiral mode" +#~ msgstr "Modo espiral" + #~ msgid "Alt + Mouse wheel" #~ msgstr "Alt + Rueda del ratón" @@ -6614,32 +6829,14 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "Por favor, resuelva el problema moviéndolo totalmente dentro o fuera de " #~ "la placa." -#~ msgid "Auto arrange" -#~ msgstr "Auto posicionamiento" - -#~ msgid "" -#~ "Auto orientates selected objects or all objects.If there are selected " -#~ "objects, it just orientates the selected ones.Otherwise, it will " -#~ "orientates all objects in the project." -#~ msgstr "" -#~ "Orienta automáticamente los objetos seleccionados o todos los objetos.Si " -#~ "hay objetos seleccionados, sólo orienta los seleccionados.En caso " -#~ "contrario, orienta todos los objetos del proyecto." - #~ msgid "Clear all" #~ msgstr "Borrar todo" -#~ msgid "Creating" -#~ msgstr "Creando" - #~ msgid "Ctrl + Any arrow" #~ msgstr "Ctrl + Cualquier tecla" #~ msgid "Ctrl + Left mouse button" -#~ msgstr "Ctrl + Botón izquierdo del ratón" - -#~ msgid "Debug" -#~ msgstr "Depurar" +#~ msgstr "Ctrl + Left mouse button" #~ msgid "Display printable box" #~ msgstr "Caja de visualización imprimible " @@ -6657,11 +6854,11 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "2. The Filament presets\n" #~ "3. The Printer presets\n" #~ msgstr "" -#~ "¿Quieres sincronizar tus datos personales desde Bambu Cloud? \n" -#~ "Contiene la siguiente información:\n" -#~ "1. Preajustes del proceso\n" -#~ "2. Preajustese de filamentos\n" -#~ "3. Preajustes de la impresora\n" +#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" +#~ "Contains the following information:\n" +#~ "1. Process presets\n" +#~ "2. Filament presets\n" +#~ "3. Printer presets\n" #~ msgid "" #~ "Don't retract when the travel is in infill area absolutely. That means " @@ -6670,15 +6867,6 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "No se repliegue cuando el recorrido esté en zona de relleno " #~ "absolutamente. Eso significa que el rezago no puede ser visto" -#~ msgid "Enter a search term" -#~ msgstr "Teclea un término de búsqueda" - -#~ msgid "Filaments Selection" -#~ msgstr "Selección de filamentos" - -#~ msgid "Finished" -#~ msgstr "Terminado" - #~ msgid "Fix model locally" #~ msgstr "Fijar el modelo localmente" @@ -6686,13 +6874,13 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ msgstr "Fijar el modelo a través de la nube" #~ msgid "Fragment Filter" -#~ msgstr "Filtro de fragmentos" +#~ msgstr "Fragment Filter" #~ msgid "Fragment area" -#~ msgstr "Zona de fragmentos" +#~ msgstr "Fragment area" #~ msgid "Fragment filter" -#~ msgstr "Filtro de Fragmentos" +#~ msgstr "Fragment filter" #~ msgid "" #~ "Heat the nozzle to target \n" @@ -6702,10 +6890,10 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "temperatura" #~ msgid "In the calibration of extrusion flow" -#~ msgstr "En la calibración del flujo de extrusión" +#~ msgstr "In the calibration of extrusion flow" #~ msgid "In the calibration of laser scanner" -#~ msgstr "En la calibración del escáner láser" +#~ msgstr "In the calibration of laser scanner" #~ msgid "Module" #~ msgstr "Módulo" @@ -6717,19 +6905,16 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ msgstr "Archivo de salida" #~ msgid "Pause(heated bed temperature error)" -#~ msgstr "Pausa (error de temperatura de la cama caliente)" +#~ msgstr "Pause(heated bed temperature error)" #~ msgid "Pause(hotend temperature error)" -#~ msgstr "Pausa (error de temperatura del hotend)" +#~ msgstr "Pause(hotend temperature error)" #~ msgid "Pause(toolhead shell off)" -#~ msgstr "Pausa (cabezal apagado)" - -#~ msgid "Please fill report first." -#~ msgstr "Por favor, rellene primero el informe." +#~ msgstr "Pause(toolhead shell off)" #~ msgid "Please upgrade your printer first" -#~ msgstr "Por favor, actualice su impresora primero" +#~ msgstr "Please upgrade your printer first" #~ msgid "Position:" #~ msgstr "Posición:" @@ -6738,14 +6923,11 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "Preview only mode:\n" #~ "The loaded file contains gcode only." #~ msgstr "" -#~ "Modo de vista previa solamente:\n" -#~ "El archivo cargado sólo contiene gcode." +#~ "Preview only mode:\n" +#~ "The loaded file contains G-code only." #~ msgid "Preview only mode for gcode file." -#~ msgstr "Modo de vista previa sólo para el archivo gcode." - -#~ msgid "Printer Selection" -#~ msgstr "Selección de la impresora" +#~ msgstr "Preview only mode for G-code file." #~ msgid "" #~ "Push new filament \n" @@ -6754,9 +6936,6 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ "Empujar el nuevo filamento \n" #~ "en el extrusor" -#~ msgid "Sending" -#~ msgstr "Enviando" - #~ msgid "Shift + Any arrow" #~ msgstr "Mayúsculas + Cualquier flecha" @@ -6772,39 +6951,19 @@ msgstr "Soporte: propagar ramas en la capa %d" #~ msgid "Show Printable Box(TODO)" #~ msgstr "Mostrar caja imprimible(TODO)" -#~ msgid "Spiral mode" -#~ msgstr "Modo espiral" - #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" #~ msgstr "" -#~ "Enviado con éxito. Saltará automáticamente a la página del dispositivo en " -#~ "%s s" +#~ "Successfully sent. Will automatically jump to the device page in %s s" #~ msgid "Swith cloud environment, Please login again!" #~ msgstr "Cambiar el entorno de la nube, ¡Por favor, inicie sesión de nuevo!" -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "La configuración no es compatible y no se puede cargar." - #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" #~ msgstr "" -#~ "Las versiones del firmware de la impresora y del AMS son demasiado " -#~ "antiguas, por favor, actualice a la última versión antes de enviar el " -#~ "trabajo de impresión." - -#~ msgid "Unable to create zip file" -#~ msgstr "No se puede crear un archivo zip" - -#~ msgid "Uploading" -#~ msgstr "Subiendo" +#~ "The firmware versions of the printer and AMS are too low. Please update " +#~ "them to the latest version before sending any print jobs." #~ msgid "User pause" -#~ msgstr "Pausa de usuario" - -#~ msgid "Waiting" -#~ msgstr "Esperando" - -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "el 3mf no es compatible, ¡cargue sólo los datos geométricos!" +#~ msgstr "User pause" diff --git a/bbl/i18n/fr/BambuStudio_fr.po b/bbl/i18n/fr/BambuStudio_fr.po index dd50f7b362..2a3eaa1ab2 100644 --- a/bbl/i18n/fr/BambuStudio_fr.po +++ b/bbl/i18n/fr/BambuStudio_fr.po @@ -2,13 +2,16 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Localazy (https://localazy.com)\n" "Plural-Forms: nplurals=2; plural=(n==0 || n==1) ? 0 : 1;\n" +"X-Generator: Poedit 3.1\n" msgid "Supports Painting" msgstr "Prend en charge la peinture" @@ -365,6 +368,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Ajouter" + msgid "Notice" msgstr "Remarque" @@ -650,9 +668,6 @@ msgstr "Cylindre" msgid "Cone" msgstr "Cône" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse Wipe Tower" - msgid "Add settings" msgstr "Ajouter des réglages" @@ -857,11 +872,13 @@ msgstr "" msgid "%1$d error repaired" msgid_plural "%1$d errors repaired" msgstr[0] "%1$d erreur réparée" +msgstr[1] "" #, c-format, boost-format msgid "Error: %1$d non-manifold edge." msgid_plural "Error: %1$d non-manifold edges." msgstr[0] "Erreur : %1$d arête non multiple." +msgstr[1] "" msgid "Remaining errors" msgstr "Erreurs restantes" @@ -870,6 +887,7 @@ msgstr "Erreurs restantes" msgid "%1$d non-manifold edge" msgid_plural "%1$d non-manifold edges" msgstr[0] "%1$d arête non multiple" +msgstr[1] "" msgid "Right click the icon to fix model object" msgstr "Cliquez avec le bouton droit sur l'icône pour fixer l'objet modèle" @@ -977,10 +995,12 @@ msgstr "Réparer l'objet modèle" msgid "Following model object has been repaired" msgid_plural "Following model objects have been repaired" msgstr[0] "L'objet modèle suivant a été réparé" +msgstr[1] "" msgid "Failed to repair folowing model object" msgid_plural "Failed to repair folowing model objects" msgstr[0] "Échec de la réparation de l'objet modèle suivant" +msgstr[1] "" msgid "Repairing was canceled" msgstr "La réparation a été annulée" @@ -1075,7 +1095,7 @@ msgid "Click the pencil icon to edit the filament." msgstr "Cliquez sur l'icône du crayon pour modifier le filament." msgid "Load Filament" -msgstr "Charger le filament" +msgstr "Load" msgid "Unload Filament" msgstr "Unload" @@ -1250,6 +1270,9 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" msgstr "Sending print configuration" @@ -1375,6 +1398,18 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" msgstr "Insertion update" @@ -1742,7 +1777,7 @@ msgid "Identifying build plate type" msgstr "Identifying build plate type" msgid "Calibrating Micro Lidar" -msgstr "Calibrage du Micro-Lidar" +msgstr "Calibrating Micro Lidar" msgid "Homing toolhead" msgstr "Homing toolhead" @@ -1901,9 +1936,6 @@ msgstr "Durée" msgid "Display" msgstr "Afficher" -msgid "Line type" -msgstr "Type de ligne" - msgid "Layer Height (mm)" msgstr "Hauteur de couche (mm)" @@ -1991,6 +2023,9 @@ msgstr "Estimation totale" msgid "Normal mode" msgstr "Mode normal" +msgid "Cost" +msgstr "Coût" + msgid "Prepare time" msgstr "Temps de préparation" @@ -2045,9 +2080,6 @@ msgstr "Autoriser plusieurs matériaux sur la même plaque" msgid "Avoid extrusion calibration region" msgstr "Éviter la région d'étalonnage de l'extrusion" -msgid "Add" -msgstr "Ajouter" - msgid "Add plate" msgstr "Ajouter une assiette" @@ -2160,6 +2192,15 @@ msgstr "" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Entrer un terme de recherche" + +msgid "Online" +msgstr "En ligne" + +msgid "Offline" +msgstr "Hors ligne" + msgid "Application is closing" msgstr "L'application se ferme" @@ -2182,6 +2223,9 @@ msgstr "Device" msgid "Project" msgstr "Projet" +msgid "Debug" +msgstr "Déboguer" + msgid "Slice" msgstr "Découper" @@ -2219,6 +2263,12 @@ msgstr "Vérifier la mise à jour" msgid "&About %s" msgstr "&Au sujet de %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Vue par défaut" @@ -2290,9 +2340,24 @@ msgstr "Importer 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Charger un modèle" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "Exporter tous les objets au format STL" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Exporter le fichier en tranches actuel" @@ -2302,6 +2367,12 @@ msgstr "Exporter le G-code" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exporter" @@ -2368,27 +2439,12 @@ msgstr "Utiliser la vue orthogonale" msgid "Preferences" msgstr "Préférences" -msgid "About" -msgstr "" - msgid "View" msgstr "Vue" msgid "Help" msgstr "Aide" -msgid "&File" -msgstr "&File" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&View" - -msgid "&Help" -msgstr "&Help" - msgid "&Open G-code" msgstr "&Open G-code" @@ -2420,8 +2476,48 @@ msgstr "&Quit" msgid "Quit %s" msgstr "Quit %s" -msgid "Save configuration as:" -msgstr "Enregistrer la configuration sous :" +msgid "&File" +msgstr "&File" + +msgid "&View" +msgstr "&View" + +msgid "&Help" +msgstr "&Help" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Le fichier est manquant" @@ -2466,47 +2562,93 @@ msgstr "En jouant..." msgid "Load failed [%d]!" msgstr "Le chargement a échoué [%d] !" -msgid "3Dconnexion settings" -msgstr "Paramètres 3Dconnexion" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Appareil :" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Télécharger" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Waiting" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Terminé" msgid "Speed:" msgstr "Vitesse:" -msgid "Translation" -msgstr "Traduction" - -msgid "Zoom" -msgstr "Zoom" - msgid "Deadzone:" msgstr "Zone morte :" msgid "Options:" msgstr "Options :" +msgid "Zoom" +msgstr "Zoom" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "Paramètres 3Dconnexion" + msgid "Swap Y/Z axes" msgstr "Permuter les axes Y/Z" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Progression de l'impression" -msgid "Report" -msgstr "Signaler" +msgid "Resume" +msgstr "Résumer" msgid "Stop" msgstr "Arrêt" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" @@ -2544,9 +2686,6 @@ msgstr "Liste d'impression" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Résumer" - msgid "Silent" msgstr "Silencieux" @@ -2577,9 +2716,6 @@ msgstr "Impossible de se connecter au serveur" msgid "Failed to connect to the printer" msgstr "Échec de la connexion à l'imprimante" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "OK" @@ -2613,9 +2749,6 @@ msgstr "%s infos" msgid "%s information" msgstr "Information de %s" -msgid "Download" -msgstr "Télécharger" - msgid "Skip" msgstr "Sauter" @@ -2659,11 +2792,13 @@ msgstr "Ouvrir un répertoire." msgid "%1$d Object has custom supports." msgid_plural "%1$d Objects have custom supports." msgstr[0] "L'objet %1$d a des supports personnalisés." +msgstr[1] "" #, c-format, boost-format msgid "%1$d Object has color painting." msgid_plural "%1$d Objects have color painting." msgstr[0] "%1$d L'objet est peint en couleur." +msgstr[1] "" msgid "Slice ok." msgstr "Slice complete" @@ -2807,9 +2942,6 @@ msgstr "Filament Utilisé (g)" msgid "Used Materials" msgstr "Matériaux utilisés" -msgid "Cost" -msgstr "Coût" - msgid "Estimated time" msgstr "Temps estimé" @@ -2868,6 +3000,12 @@ msgstr "Vous feriez mieux de mettre à jour votre logiciel.\n" msgid "Newer 3mf version" msgstr "Nouvelle version 3mf" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -3413,12 +3551,6 @@ msgstr "Pour \"%1%\", ajoutez \"%2%\" comme nouveau préréglage" msgid "Simply switch to \"%1%\"" msgstr "Passez simplement à \"%1%\"" -msgid "Online" -msgstr "En ligne" - -msgid "Offline" -msgstr "Hors ligne" - msgid "My Device" msgstr "Mon appareil" @@ -3566,6 +3698,15 @@ msgstr "Enregistrer l'état actuel %s" msgid "Delete this preset" msgstr "Supprimer ce préréglage" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3644,6 +3785,7 @@ msgstr[0] "" "La ligne suivante %s contient des mots clés réservés. Veuillez le supprimer, " "ou il battra la visualisation du code G et l'estimation du temps " "d'impression." +msgstr[1] "" msgid "Reserved keywords found" msgstr "Mots clés réservés trouvés" @@ -3708,6 +3850,14 @@ msgstr "" "value of 0 means the filament does not support printing on the High Temp " "Plate." +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Volumetric speed limitation" msgstr "Limitation de vitesse volumétrique" @@ -3809,6 +3959,7 @@ msgstr "Détaché" msgid "Following preset will be deleted too." msgid_plural "Following presets will be deleted too." msgstr[0] "Le préréglage suivant sera également supprimé." +msgstr[1] "" #, boost-format msgid "Are you sure to %1% the selected preset?" @@ -3937,6 +4088,12 @@ msgstr "Général" msgid "Capabilities" msgstr "Fonctionnalités" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Définir comme couverture" @@ -3962,8 +4119,8 @@ msgstr "Guide d'assemblage" msgid "Choose files" msgstr "Choisir des fichiers" -msgid "Designer" -msgstr "Designer" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Nom du modèle" @@ -4071,6 +4228,9 @@ msgstr "Copier dans le presse-papier" msgid "Paste from clipboard" msgstr "Coller depuis le presse-papier" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Afficher la liste des raccourcis clavier" @@ -4212,6 +4372,9 @@ msgstr "⌘+molette de la souris" msgid "Support/Color Painting: adjust pen radius" msgstr "Support/Peinture couleur : ajustez le rayon du stylet" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Support/Peinture couleur : ajuster la position de la section" @@ -4540,12 +4703,11 @@ msgstr "" #, boost-format msgid "%1% is too close to others, and collisions may be caused." -msgstr "" -"%1% est trop proche des autres, cela pourrait provoquer des collisions." +msgstr "%1% is too close to others, and collisions may be caused." #, boost-format msgid "%1% is too tall, and collisions will be caused." -msgstr "%1% est trop grand, cela pourrait provoquer des collisions." +msgstr "%1% is too tall, and collisions will be caused." msgid " is too close to others, there will be collisions when printing.\n" msgstr "" @@ -4751,6 +4913,11 @@ msgstr "" "This is the bed temperature for layers except for the first one. A value of " "0 means the filament does not support printing on the High Temp Plate." +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Initial layer" msgstr "Couche initiale" @@ -4778,6 +4945,11 @@ msgstr "" "This is the bed temperature of the first layer. A value of 0 means the " "filament does not support printing on the High Temp Plate." +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" + msgid "Bed types supported by the printer" msgstr "Types de lit pris en charge par l'imprimante" @@ -5329,8 +5501,8 @@ msgid "" "Acceleration of top surface infill. Using a lower value may improve top " "surface quality" msgstr "" -"This is the acceleration of top surface infill. Using a lower value may " -"improve top surface quality." +"Acceleration of top surface infill. Using a lower value may improve top " +"surface quality" msgid "" "Acceleration of initial layer. Using a lower value can improve build plate " @@ -5924,6 +6096,9 @@ msgstr "Aligné" msgid "Back" msgstr "Retour" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Distance jupe" @@ -5978,15 +6153,13 @@ msgstr "" "solides. Le modèle généré final n'a pas de couture" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Record timelapse video of printing without showing the toolhead. In this " -"mode the toolhead docks near the excess chute at each layer change, and then " -"a snapshot is taken with the chamber camera. When printing finishes, a " -"timelapse video is created from all the snapshots." msgid "Temperature variation" msgstr "Variation de température" @@ -6153,13 +6326,8 @@ msgstr "Hauteur de la couche de support indépendante" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"La couche de support utilise une hauteur de couche indépendante de la couche " -"d'objet. Il s'agit de prendre en charge l'écart de support personnalisé, " -"mais cela peut entraîner des commutateurs de filament supplémentaires si le " -"support est spécifié comme extrudeuse différente avec l'objet" msgid "Threshold angle" msgstr "Angle de seuil" @@ -6510,10 +6678,14 @@ msgstr "Vérification de la nécessité du support" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Il semble que l'objet %s ait besoin d'aide pour imprimer. Veuillez activer " -"la génération de support." msgid "Optimizing toolpath" msgstr "Optimisation du parcours d'outil" @@ -6523,13 +6695,8 @@ msgstr "" "Les calques vides autour du bas sont remplacés par les calques normaux les " "plus proches." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"La vitesse d'impression minimale lors du ralentissement pour le " -"refroidissement" msgid "Slicing mesh" msgstr "Maillage de tranchage" @@ -6572,6 +6739,88 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "the 3mf is not compatible, load geometry data only!" +#~ msgstr "" +#~ "le 3mf n'est pas compatible, chargez uniquement les données de géométrie !" + +#~ msgid "Save configuration as:" +#~ msgstr "Enregistrer la configuration sous :" + +#~ msgid "Line type" +#~ msgstr "Type de ligne" + +#~ msgid "Designer" +#~ msgstr "Designer" + +#~ msgid "Report" +#~ msgstr "Signaler" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Appareil :" + +#~ msgid "Translation" +#~ msgstr "Traduction" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "" +#~ "Il semble que l'objet %s ait besoin d'aide pour imprimer. Veuillez " +#~ "activer la génération de support." + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "La vitesse d'impression minimale lors du ralentissement pour le " +#~ "refroidissement" + +#~ msgid "" +#~ "Auto orientates selected objects or all objects.If there are selected " +#~ "objects, it just orientates the selected ones.Otherwise, it will " +#~ "orientates all objects in the project." +#~ msgstr "" +#~ "Oriente automatiquement les objets sélectionnés ou tous les objets. S'il " +#~ "y a des objets sélectionnés, il oriente uniquement ceux qui sont " +#~ "sélectionnés. Sinon, il oriente tous les objets du projet." + +#~ msgid "The Config is not compatible and can not be loaded." +#~ msgstr "La Config n'est pas compatible et ne peut pas être chargée." + +#~ msgid "Creating" +#~ msgstr "Creating" + +#~ msgid "Uploading" +#~ msgstr "Téléchargement" + +#~ msgid "Sending" +#~ msgstr "Sending" + +#~ msgid "Please fill report first." +#~ msgstr "Veuillez d'abord remplir le rapport." + +#~ msgid "Unable to create zip file" +#~ msgstr "Unable to create zip file" + +#~ msgid "Filaments Selection" +#~ msgstr "Sélection de filaments" + +#~ msgid "Printer Selection" +#~ msgstr "Sélection de l'imprimante" + +#~ msgid "Auto arrange" +#~ msgstr "Organisation automatique" + +#~ msgid "Spiral mode" +#~ msgstr "Mode spirale" + #~ msgid "Alt + Mouse wheel" #~ msgstr "Alt + molette de la souris" @@ -6583,33 +6832,15 @@ msgstr "Support: propagate branches at layer %d" #~ "problème en le déplaçant totalement à l'intérieur ou à l'extérieur de la " #~ "plaque." -#~ msgid "Auto arrange" -#~ msgstr "Organisation automatique" - -#~ msgid "" -#~ "Auto orientates selected objects or all objects.If there are selected " -#~ "objects, it just orientates the selected ones.Otherwise, it will " -#~ "orientates all objects in the project." -#~ msgstr "" -#~ "Oriente automatiquement les objets sélectionnés ou tous les objets. S'il " -#~ "y a des objets sélectionnés, il oriente uniquement ceux qui sont " -#~ "sélectionnés. Sinon, il oriente tous les objets du projet." - #~ msgid "Clear all" #~ msgstr "Tout effacer" -#~ msgid "Creating" -#~ msgstr "Creating" - #~ msgid "Ctrl + Any arrow" #~ msgstr "Ctrl + n'importe quelle flèche" #~ msgid "Ctrl + Left mouse button" #~ msgstr "Ctrl + Left mouse button" -#~ msgid "Debug" -#~ msgstr "Déboguer" - #~ msgid "Display printable box" #~ msgstr "Afficher la boîte imprimable" @@ -6639,15 +6870,6 @@ msgstr "Support: propagate branches at layer %d" #~ "Ne vous rétractez absolument pas lorsque le déplacement est dans la zone " #~ "de remplissage. Cela signifie que le suintement ne peut pas être vu" -#~ msgid "Enter a search term" -#~ msgstr "Entrer un terme de recherche" - -#~ msgid "Filaments Selection" -#~ msgstr "Sélection de filaments" - -#~ msgid "Finished" -#~ msgstr "Terminé" - #~ msgid "Fix model locally" #~ msgstr "Corriger le modèle localement" @@ -6692,9 +6914,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Pause(toolhead shell off)" #~ msgstr "Pause(toolhead shell off)" -#~ msgid "Please fill report first." -#~ msgstr "Veuillez d'abord remplir le rapport." - #~ msgid "Please upgrade your printer first" #~ msgstr "Please upgrade your printer first" @@ -6711,17 +6930,11 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Preview only mode for gcode file." #~ msgstr "Preview only mode for G-code file." -#~ msgid "Printer Selection" -#~ msgstr "Sélection de l'imprimante" - #~ msgid "" #~ "Push new filament \n" #~ "into extruder" #~ msgstr "Poussez le nouveau filament dans l'extruder" -#~ msgid "Sending" -#~ msgstr "Sending" - #~ msgid "Shift + Any arrow" #~ msgstr "Maj + n'importe quelle flèche" @@ -6737,9 +6950,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Show Printable Box(TODO)" #~ msgstr "Afficher la boîte imprimable (TODO)" -#~ msgid "Spiral mode" -#~ msgstr "Mode spirale" - #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" #~ msgstr "" #~ "Successfully sent. Will automatically jump to the device page in %s s" @@ -6747,9 +6957,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Swith cloud environment, Please login again!" #~ msgstr "Changez d'environnement cloud, veuillez vous reconnecter !" -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "La Config n'est pas compatible et ne peut pas être chargée." - #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" @@ -6757,18 +6964,5 @@ msgstr "Support: propagate branches at layer %d" #~ "The firmware versions of the printer and AMS are too low. Please update " #~ "them to the latest version before sending any print jobs." -#~ msgid "Unable to create zip file" -#~ msgstr "Unable to create zip file" - -#~ msgid "Uploading" -#~ msgstr "Téléchargement" - #~ msgid "User pause" #~ msgstr "User pause" - -#~ msgid "Waiting" -#~ msgstr "Waiting" - -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "" -#~ "le 3mf n'est pas compatible, chargez uniquement les données de géométrie !" diff --git a/bbl/i18n/hu/BambuStudio_hu.po b/bbl/i18n/hu/BambuStudio_hu.po index d03679417b..3e2a673890 100644 --- a/bbl/i18n/hu/BambuStudio_hu.po +++ b/bbl/i18n/hu/BambuStudio_hu.po @@ -1,14 +1,22 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# msgid "" msgstr "" -"Project-Id-Version: Bambu Studio\n" +"Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: 2022-07-27 22:05+0100\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Localazy (https://localazy.com)\n" -"Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.1.1\n" msgid "Supports Painting" msgstr "Támaszok festése" @@ -172,8 +180,9 @@ msgstr "Átméretezés" msgid "Error: Please close all toolbar menus first" msgstr "Hiba: Kérjük, először zárd be az összes eszköztár menüt" +# d msgid "Tool-Lay on Face" -msgstr "Tool-Lay on Face" +msgstr "" msgid "in" msgstr "in" @@ -196,8 +205,9 @@ msgstr "Objektum műveletek" msgid "Volume Operations" msgstr "Térfogat műveletek" +# d msgid "Translate" -msgstr "Translate" +msgstr "" msgid "Group Operations" msgstr "Csoportos műveletek" @@ -208,6 +218,7 @@ msgstr "Pozíció beállítása" msgid "Set Orientation" msgstr "Orientáció beállítása" +# d msgid "Set Scale" msgstr "Méretarány beállítása" @@ -254,7 +265,7 @@ msgid "Cut to parts" msgstr "Részekre darabolás" msgid "Auto Segment" -msgstr "Auto Segment" +msgstr "" msgid "Perform cut" msgstr "Vágás" @@ -330,7 +341,7 @@ msgstr "" "A művelet törlése már folyamatban van. Kérjük, várj néhány másodpercet." msgid "Face recognition" -msgstr "Face recognition" +msgstr "" msgid "Perform Recognition" msgstr "Felismerés" @@ -365,6 +376,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Hozzáadás" + msgid "Notice" msgstr "Megjegyzés" @@ -509,8 +535,6 @@ msgid "" "You can keep the modifield presets to the new project, discard or save " "changes as new presets." msgstr "" -"You can keep the modified presets for the new project, discard, or save " -"changes as new presets." msgid "User logged out" msgstr "" @@ -646,9 +670,6 @@ msgstr "Henger" msgid "Cone" msgstr "Kúp" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse törlő torony" - msgid "Add settings" msgstr "Beállítások hozzáadása" @@ -944,7 +965,7 @@ msgstr "" "lennie." msgid "The type of the last solid object part is not to be changed." -msgstr "The type of the last solid object part cannot be changed." +msgstr "" msgid "Negative Part" msgstr "Negatív tárgy" @@ -1013,7 +1034,7 @@ msgid "No-brim" msgstr "Nincs perem" msgid " " -msgstr "" +msgstr " " msgid "Layer height" msgstr "Rétegmagasság" @@ -1183,7 +1204,7 @@ msgid "Orienting" msgstr "Orientáció" msgid "Error! Unable to create thread!" -msgstr "Error. Unable to create thread." +msgstr "" msgid "Exception" msgstr "Kivétel" @@ -1201,7 +1222,7 @@ msgid "Failure of printer login" msgstr "Sikertelen bejelentkezés a nyomtatóra" msgid "Failed to get ticket" -msgstr "Failed to get ticket" +msgstr "" msgid "User authorization timeout" msgstr "Felhasználó hitelesítési időtúllépés" @@ -1255,6 +1276,9 @@ msgstr "Szolgáltatás nem elérhető" msgid "Unkown Error." msgstr "Ismeretlen hiba." +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" msgstr "Nyomtatási konfiguráció küldése" @@ -1391,8 +1415,20 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" -msgstr "Insertion update" +msgstr "" msgid "" "The AMS will automatically read the filament information when inserting a " @@ -1642,11 +1678,6 @@ msgid "" "\n" "The value will be reset to 0." msgstr "" -"This setting is only used for tuning model size by small amounts.\n" -"For example, when the model size has small errors or when tolerances are " -"incorrect. For large adjustments, please use the model scale function.\n" -"\n" -"The value will be reset to 0." msgid "" "Too large elefant foot compensation is unreasonable.\n" @@ -1655,11 +1686,6 @@ msgid "" "\n" "The value will be reset to 0." msgstr "" -"The elephant foot compensation value is too large.\n" -"If there are significant elephant foot issues, please check other settings.\n" -"The bed temperature may be too high, for example.\n" -"\n" -"The value will be reset to 0." msgid "" "Spiral mode only works when wall loops is 1, \n" @@ -1724,9 +1750,6 @@ msgid "" "Yes - switch to zig-zag pattern automaticlly\n" "No - reset density to default non 100% value automaticlly\n" msgstr "" -"Switch to zig-zag pattern?\n" -"Yes - Switch to zig-zag pattern automatically\n" -"No - Reset density to default non-100% value automatically\n" msgid "Auto bed leveling" msgstr "Automatikus asztalszintezés" @@ -1735,7 +1758,7 @@ msgid "Heatbed preheating" msgstr "Asztal előfűtése" msgid "Sweeping XY mech mode" -msgstr "Sweeping XY mech mode" +msgstr "" msgid "Changing filament" msgstr "Filament váltása" @@ -1777,7 +1800,7 @@ msgid "Printing was paused by the user" msgstr "Nyomtatás szüneteltetve a felhasználó által" msgid "Pause of front cover falling" -msgstr "Pause of front cover falling" +msgstr "" msgid "Calibrating the micro lida" msgstr "Micro Lidar kalibrálása" @@ -1795,16 +1818,16 @@ msgid "MC" msgstr "MC" msgid "MainBoard" -msgstr "MainBoard" +msgstr "" msgid "AMS" msgstr "AMS" msgid "TH" -msgstr "TH" +msgstr "" msgid "XCam" -msgstr "XCam" +msgstr "" msgid "Unknown" msgstr "Ismeretlen" @@ -1848,13 +1871,13 @@ msgstr "Érvénytelen számjegy." #, c-format, boost-format msgid "Value %s is out of range, continue?" -msgstr "Value %s is out of range, continue?" +msgstr "" msgid "Parameter validation" msgstr "Paraméter validáció" msgid "Value is out of range." -msgstr "Value is out of range." +msgstr "" #, c-format, boost-format msgid "" @@ -1862,13 +1885,10 @@ msgid "" "YES for %s%%, \n" "NO for %s %s." msgstr "" -"Is it %s%% or %s %s?\n" -"YES for %s%%, \n" -"NO for %s %s." #, boost-format msgid "Invalid format. Expected vector format: \"%1%\"" -msgstr "Invalid format. Expected vector format: \"%1%\"" +msgstr "" msgid "Layer Height" msgstr "Rétegmagasság" @@ -1880,19 +1900,19 @@ msgid "Fan Speed" msgstr "Ventilátor fordulatszám" msgid "Temperature" -msgstr "Temperature" +msgstr "" msgid "Flow" msgstr "Anyagáramlás" msgid "Tool" -msgstr "Tool" +msgstr "" msgid "Extruder position" msgstr "Extruder pozíció" msgid "Loading G-codes" -msgstr "Loading G-codes" +msgstr "" msgid "Generating geometry vertex data" msgstr "Geometriai vertex adatok generálása" @@ -1901,16 +1921,16 @@ msgid "Generating geometry index data" msgstr "Geometriai index adatok generálása" msgid "up to" -msgstr "up to" +msgstr "" msgid "above" -msgstr "above" +msgstr "" msgid "from" -msgstr "from" +msgstr "" msgid "to" -msgstr "to" +msgstr "" msgid "Color Scheme" msgstr "Színséma" @@ -1924,9 +1944,6 @@ msgstr "Idő" msgid "Display" msgstr "Megjelenítés" -msgid "Line type" -msgstr "Vonal típusa" - msgid "Layer Height (mm)" msgstr "Rétegmagasság (mm)" @@ -1940,13 +1957,13 @@ msgid "Fan Speed (%)" msgstr "Ventilátor fordulatszám (%)" msgid "Temperature (°C)" -msgstr "Temperature (°C)" +msgstr "" msgid "Volumetric flow rate (mm³/s)" msgstr "Térfogatáramlás (mm³/s)" msgid "Used filament" -msgstr "Used filament" +msgstr "" msgid "Filament N XX" msgstr "Filament N XX" @@ -1967,13 +1984,13 @@ msgid "Retract" msgstr "Visszahúzás" msgid "Unretract" -msgstr "Unretract" +msgstr "" msgid "Filament Changes" msgstr "Filamentcserék" msgid "Wipe" -msgstr "Wipe" +msgstr "" msgid "Options" msgstr "Opciók" @@ -2012,7 +2029,10 @@ msgid "Total Estimation" msgstr "Összesített becslés" msgid "Normal mode" -msgstr "Normal mode" +msgstr "" + +msgid "Cost" +msgstr "Költség" msgid "Prepare time" msgstr "Előkészítési idő" @@ -2024,22 +2044,22 @@ msgid "Total" msgstr "Összesen" msgid "Switch to silent mode" -msgstr "Switch to silent mode" +msgstr "" msgid "Switch to normal mode" -msgstr "Switch to normal mode" +msgstr "" msgid "Sequence" msgstr "Sorrend" msgid "Mirror Object" -msgstr "Mirror object" +msgstr "" msgid "Tool Move" -msgstr "Tool move" +msgstr "" msgid "Move Object" -msgstr "Move object" +msgstr "" msgid "Auto Orientation options" msgstr "Automatikus orientáció beállításai" @@ -2048,7 +2068,7 @@ msgid "Enable rotation" msgstr "Forgatás engedélyezése" msgid "Optimize support interface area" -msgstr "Optimize support interface area" +msgstr "" msgid "Orient" msgstr "Orientáció" @@ -2068,9 +2088,6 @@ msgstr "Többféle anyag használata egy tálcán" msgid "Avoid extrusion calibration region" msgstr "Extrudáláskalibráció környékének elkerülése" -msgid "Add" -msgstr "Hozzáadás" - msgid "Add plate" msgstr "Tálca hozzáadása" @@ -2096,7 +2113,7 @@ msgid "Select Plate" msgstr "Tálca kiválasztása" msgid "Assembly Return" -msgstr "Assembly Return" +msgstr "" msgid "return" msgstr "vissza" @@ -2108,7 +2125,7 @@ msgid "Explosion Ratio" msgstr "Robbantási arány" msgid "Total Volume:" -msgstr "Total Volume:" +msgstr "" msgid "Assembly Info" msgstr "Összeállítási információ" @@ -2149,9 +2166,6 @@ msgid "" "minimize deviation.\n" "It keeps the device performing optimally." msgstr "" -"The calibration program detects the status of your device automatically to " -"minimize deviation.\n" -"It keeps the device performing optimally." msgid "Calibration Flow" msgstr "Kalibrációs anyagáramlás" @@ -2169,7 +2183,7 @@ msgid "Timelapse" msgstr "Timelapse" msgid "Monitoring Recording" -msgstr "Monitoring Recording" +msgstr "" msgid "ConnectPrinter(LAN)" msgstr "Nyomtató csatlakoztatása (LAN)" @@ -2181,12 +2195,19 @@ msgid "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" msgstr "" -"You can find it in \"Settings > Network > Connection code\"\n" -"on the printer, as shown in the figure:" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "" + +msgid "Online" +msgstr "" + +msgid "Offline" +msgstr "" + msgid "Application is closing" msgstr "Az alkalmazás bezárul" @@ -2194,7 +2215,7 @@ msgid "Closing Application while some presets are modified." msgstr "Alkalmazás bezárása egyes beállítások módosítása közben." msgid "Logging" -msgstr "Logging" +msgstr "" msgid "Prepare" msgstr "Előkészítés" @@ -2208,6 +2229,9 @@ msgstr "Nyomtató" msgid "Project" msgstr "Projekt" +msgid "Debug" +msgstr "Debug" + msgid "Slice" msgstr "Szeletelés" @@ -2245,6 +2269,12 @@ msgstr "Frissítés keresése" msgid "&About %s" msgstr "&%s névjegye" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Alapértelmezett nézet" @@ -2314,11 +2344,26 @@ msgid "Import 3MF/STL/STEP/OBJ/AMF" msgstr "3MF/STL/STEP/OBJ/AMF importálása" msgid "Load a model" -msgstr "Load a model" +msgstr "" + +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" msgid "Export all objects as STL" msgstr "Összes objektum exportálása STL-ként" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Jelenlegi szeletelt fájl exportálása" @@ -2328,6 +2373,12 @@ msgstr "G-kód exportálása" msgid "Export current plate as G-code" msgstr "Jelenlegi tálca exportálása G-kódként" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exportálás" @@ -2394,50 +2445,35 @@ msgstr "Ortogonális nézet használata" msgid "Preferences" msgstr "Beállítások" -msgid "About" -msgstr "" - msgid "View" msgstr "Nézet" msgid "Help" msgstr "Segítség" -msgid "&File" -msgstr "&File" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&View" - -msgid "&Help" -msgstr "&Help" - msgid "&Open G-code" -msgstr "&Open G-code" +msgstr "" msgid "Open a G-code file" msgstr "G-kód fájl megnyitása" msgid "Re&load from Disk" -msgstr "Re&load from Disk" +msgstr "" msgid "Reload the plater from disk" -msgstr "Reload the plater from disk" +msgstr "" msgid "Export &Toolpaths as OBJ" -msgstr "Export &Toolpaths as OBJ" +msgstr "" msgid "Export toolpaths as OBJ" msgstr "Szerszámút exportálása OBJ-ként" msgid "Open &PrusaSlicer" -msgstr "Open &PrusaSlicer" +msgstr "" msgid "Open PrusaSlicer" -msgstr "Open PrusaSlicer" +msgstr "" msgid "&Quit" msgstr "&Kilépés" @@ -2446,14 +2482,54 @@ msgstr "&Kilépés" msgid "Quit %s" msgstr "Kilépés %s" -msgid "Save configuration as:" -msgstr "Konfiguráció mentése mint:" +msgid "&File" +msgstr "" + +msgid "&View" +msgstr "" + +msgid "&Help" +msgstr "" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Hiányzik a fájl" msgid "The project is no longer available." -msgstr "The project is no longer available." +msgstr "" msgid "Filament Settings" msgstr "Filament beállítások" @@ -2472,20 +2548,20 @@ msgstr "" "3. Nyomtató beállítások\n" msgid "Synchronization" -msgstr "Synchronization" +msgstr "" msgid "Initialize failed (No Device)!" msgstr "Sikertelen inicializálás (Nincs eszköz)!" msgid "Initializing..." -msgstr "Initializing..." +msgstr "" #, c-format, boost-format msgid "Initialize failed [%d]!" -msgstr "Initalization failed [%d]!" +msgstr "" msgid "Loading..." -msgstr "Loading..." +msgstr "" msgid "Stopped." msgstr "Megállítva." @@ -2495,49 +2571,95 @@ msgstr "Lejátszás..." #, c-format, boost-format msgid "Load failed [%d]!" -msgstr "Loading failed [%d]!" +msgstr "" -msgid "3Dconnexion settings" -msgstr "3Dconnexion beállítások" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Eszköz:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Letöltés" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "Csatlakozás..." + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "" msgid "Speed:" msgstr "Sebesség:" -msgid "Translation" -msgstr "Translation" - -msgid "Zoom" -msgstr "Zoom" - msgid "Deadzone:" msgstr "Tiltott zóna:" msgid "Options:" msgstr "Opciók:" +msgid "Zoom" +msgstr "" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion beállítások" + msgid "Swap Y/Z axes" -msgstr "Swap Y/Z axes" +msgstr "" msgid "Camera" msgstr "Kamera" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Nyomtatás folyamata" -msgid "Report" -msgstr "Report" +msgid "Resume" +msgstr "Folytatás" msgid "Stop" msgstr "Állj" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" @@ -2575,9 +2697,6 @@ msgstr "Nyomtatási lista" msgid "Downloading..." msgstr "Letöltés..." -msgid "Resume" -msgstr "Folytatás" - msgid "Silent" msgstr "Csendes" @@ -2594,10 +2713,10 @@ msgid "Status" msgstr "Állapot" msgid "Media" -msgstr "Media" +msgstr "" msgid "Update" -msgstr "Update" +msgstr "" msgid "HMS" msgstr "HMS" @@ -2608,9 +2727,6 @@ msgstr "Nem sikerült csatlakozni a szerverhez" msgid "Failed to connect to the printer" msgstr "Nem sikerült csatlakozni a nyomtatóhoz" -msgid "Connecting..." -msgstr "Csatlakozás..." - msgid "OK" msgstr "OK" @@ -2644,9 +2760,6 @@ msgstr "%s infó" msgid "%s information" msgstr "%s információ" -msgid "Download" -msgstr "Letöltés" - msgid "Skip" msgstr "Kihagyás" @@ -2657,19 +2770,19 @@ msgid "Configuration can update now." msgstr "A konfiguráció már frissíthető." msgid "Detail." -msgstr "More" +msgstr "" msgid "Integration was successful." -msgstr "Integration was successful." +msgstr "" msgid "Integration failed." -msgstr "Integration failed." +msgstr "" msgid "Undo integration was successful." -msgstr "Undo integration was successful." +msgstr "" msgid "Undo integration failed." -msgstr "Undo integration failed." +msgstr "" msgid "Exporting." msgstr "Exportálás." @@ -2708,7 +2821,7 @@ msgid "Export." msgstr "Exportálás." msgid "Jump to" -msgstr "Jump to" +msgstr "" msgid "Error:" msgstr "Hiba:" @@ -2726,10 +2839,10 @@ msgid " Click here to install it." msgstr " Kattints ide a telepítéshez." msgid "WARNING:" -msgstr "WARNING:" +msgstr "" msgid "Your model needs support ! Please make support material enable." -msgstr "Your model needs support! Please enable support material." +msgstr "" msgid "Gcode path overlap" msgstr "G-kód útvonal átfedés" @@ -2741,7 +2854,7 @@ msgid "Color painting" msgstr "Színfestés" msgid "Layers" -msgstr "Layers" +msgstr "" msgid "Range" msgstr "Tartomány" @@ -2753,22 +2866,18 @@ msgid "" "The application cannot run normally because OpenGL version is lower than " "2.0.\n" msgstr "" -"The application cannot run normally because your OpenGL version is lower " -"than 2.0.\n" msgid "Please upgrade your graphics card driver." msgstr "Kérjük, frissítsd a grafikus kártya illesztőprogramját." msgid "Unsupported OpenGL version" -msgstr "Unsupported OpenGL version" +msgstr "" #, c-format, boost-format msgid "" "Unable to load shaders:\n" "%s" msgstr "" -"Unable to load shaders:\n" -"%s" msgid "Error loading shaders" msgstr "Hiba a shaderek betöltésében" @@ -2791,7 +2900,7 @@ msgid "First Layer Inspection" msgstr "" msgid "Switch to per-object setting mode to edit modifier settings." -msgstr "Switch to per-object setting mode to edit modifier settings." +msgstr "" msgid "Don't show again" msgstr "Ne mutasd újra" @@ -2809,7 +2918,7 @@ msgid "Compare presets" msgstr "Beállítások összehasonlítása" msgid "View all object's settings" -msgstr "View all object's settings" +msgstr "" msgid "Filament settings" msgstr "Filament beállítások" @@ -2822,25 +2931,22 @@ msgid " plate %1%:" msgstr " %1% tálca:" msgid "Invalid name, the following characters are not allowed:" -msgstr "Invalid name, the following characters are not allowed:" +msgstr "" msgid "Sliced Info" msgstr "Szeletelési infó" msgid "Used Filament (m)" -msgstr "Used Filament (m)" +msgstr "" msgid "Used Filament (mm³)" -msgstr "Used Filament (mm³)" +msgstr "" msgid "Used Filament (g)" -msgstr "Used Filament (g)" +msgstr "" msgid "Used Materials" -msgstr "Used Materials" - -msgid "Cost" -msgstr "Költség" +msgstr "" msgid "Estimated time" msgstr "Becsült idő" @@ -2858,7 +2964,7 @@ msgid "Flushing volumes" msgstr "Öblítési mennyiségek" msgid "Untitled" -msgstr "Untitled" +msgstr "" #, boost-format msgid "Do you want to save changes to \"%1%\"?" @@ -2872,7 +2978,7 @@ msgstr "Visszaállítás" #, c-format, boost-format msgid "Loading file: %s" -msgstr "Loading file: %s" +msgstr "" msgid "The 3mf is not from Bambu Lab, load geometry data only." msgstr "" @@ -2891,14 +2997,18 @@ msgid "" "The 3mf's version %s is newer than %s's version %s, Found following keys " "unrecognized:\n" msgstr "" -"The 3mf file's version %s is newer than %s's version %s, Found the following " -"unrecognized keys:\n" msgid "You'd better upgrade your software.\n" -msgstr "You'd better upgrade your software.\n" +msgstr "" msgid "Newer 3mf version" -msgstr "Newer 3mf version" +msgstr "" + +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -2907,10 +3017,10 @@ msgid "Incompatible 3mf" msgstr "Nem kompatibilis 3mf" msgid "Name of components inside step file is not UTF8 format!" -msgstr "Component name(s) inside step file not in UTF8 format!" +msgstr "" msgid "The name may show garbage characters!" -msgstr "Because of unsupported text encoding, garbage characters may appear!" +msgstr "" msgid "Attention!" msgstr "Figyelem!" @@ -2920,30 +3030,28 @@ msgid "Failed loading file \"%1%\". An invalid configuration was found." msgstr "Nem sikerült betölteni \"%1%\" fájlt. Érvénytelen konfiguráció." msgid "Objects with zero volume removed" -msgstr "Objects with zero volume removed" +msgstr "" msgid "The volume of the object is zero" -msgstr "The volume of the object is zero" +msgstr "" #, c-format, boost-format msgid "" "The object from file %s is too small, and maybe in meters or inches.\n" " Do you want to scale to millimeters?" msgstr "" -"The object from file %s is too small, and may be in meters or inches.\n" -" Do you want to scale to millimeters?" msgid "Object too small" -msgstr "Object too small" +msgstr "" msgid "Load these files as a single object with multiple parts?\n" -msgstr "Load these files as a single object with multiple parts?\n" +msgstr "" msgid "Object with multiple parts was detected" -msgstr "An object with multiple parts was detected" +msgstr "" msgid "The file does not contain any geometry data." -msgstr "The file does not contain any geometry data." +msgstr "" msgid "" "Your object appears to be too large, Do you want to scale it down to fit the " @@ -2960,7 +3068,7 @@ msgid "Save file as:" msgstr "Fájl mentése mint:" msgid "The selected object couldn't be split." -msgstr "The selected object couldn't be split." +msgstr "" msgid "Another export job is running." msgstr "Egy másik exportálási feladat is fut." @@ -2972,13 +3080,13 @@ msgid "Slicing" msgstr "Szeletelés" msgid "There are warnings after slicing models:" -msgstr "There are warnings after slicing models:" +msgstr "" msgid "warnings" -msgstr "warnings" +msgstr "" msgid "Invalid data" -msgstr "Invalid data" +msgstr "" #, c-format, boost-format msgid "Slicing Plate %d" @@ -3000,16 +3108,16 @@ msgstr "" "Előkészítés fülre" msgid "You can keep the modified presets to the new project or discard them" -msgstr "You can keep the modified presets for the new project or discard them" +msgstr "" msgid "Creating a new project" msgstr "Új projekt létrehozása" msgid "Load project" -msgstr "Load project" +msgstr "" msgid "The selected file" -msgstr "The selected file" +msgstr "" msgid "does not contain valid gcode." msgstr "nem tartalmaz érvényes G-kódot." @@ -3030,7 +3138,7 @@ msgid "Import geometry only" msgstr "Csak a geometria importálása" msgid "Only one G-code file can be opened at the same time." -msgstr "Only one G-code file can be opened at a time." +msgstr "" msgid "G-code loading" msgstr "G-code betöltése" @@ -3086,7 +3194,7 @@ msgstr "" "Az egyedi támaszok és a színfestés eltávolításra került a javítást előtt." msgid "Invalid number" -msgstr "Invalid number" +msgstr "" #, boost-format msgid "Part name: %1%\n" @@ -3117,16 +3225,16 @@ msgid "Triangles: %1%\n" msgstr "Háromszögek: %1%\n" msgid "Switching the language requires application restart.\n" -msgstr "Switching languages requires the application to restart.\n" +msgstr "" msgid "Do you want to continue?" msgstr "Szeretnéd folytatni?" msgid "Language selection" -msgstr "Language selection" +msgstr "" msgid "Switching application language while some presets are modified." -msgstr "Switching application language while some presets are modified." +msgstr "" msgid "Changing application language" msgstr "Alkalmazás nyelvének megváltoztatása" @@ -3179,7 +3287,7 @@ msgstr "" "Folyamat)" msgid "User Sync" -msgstr "User Sync" +msgstr "" msgid "Associate files to BambuStudio" msgstr "Fájlok társítása a BambuStudiohoz" @@ -3224,7 +3332,7 @@ msgid "Show home page on startup" msgstr "Kezdőlap megjelenítése indításkor" msgid "Sync settings" -msgstr "Sync settings" +msgstr "" msgid "Preset sync" msgstr "Beállítások szinkronizálása" @@ -3233,31 +3341,31 @@ msgid "Preferences sync" msgstr "Beállítások szinkronizálása" msgid "View control settings" -msgstr "View control settings" +msgstr "" msgid "Rotate of view" msgstr "Nézet elforgatása" msgid "Move of view" -msgstr "Pan View" +msgstr "" msgid "Zoom of view" -msgstr "Zoom View" +msgstr "" msgid "Other" msgstr "Egyéb" msgid "Mouse wheel reverses when zooming" -msgstr "Reverse scroll direction while zooming" +msgstr "" msgid "Develop mode" msgstr "Fejlesztői mód" msgid "Dump video" -msgstr "Dump video" +msgstr "" msgid "Log Level" -msgstr "Log Level" +msgstr "" msgid "fatal" msgstr "súlyos" @@ -3266,16 +3374,16 @@ msgid "error" msgstr "hiba" msgid "warning" -msgstr "warning" +msgstr "" msgid "info" -msgstr "info" +msgstr "" msgid "debug" msgstr "debug" msgid "trace" -msgstr "trace" +msgstr "" msgid "Host Setting" msgstr "Host beállítás" @@ -3305,10 +3413,10 @@ msgid "Switch cloud environment, Please login again!" msgstr "" msgid "System presets" -msgstr "System presets" +msgstr "" msgid "User presets" -msgstr "User presets" +msgstr "" msgid "Incompatible presets" msgstr "Nem kompatibilis beállítások" @@ -3335,13 +3443,13 @@ msgid "Packing project data into 3mf file" msgstr "Projektadatok csomagolása 3mf fájlba" msgid "Uploading 3mf" -msgstr "Uploading 3mf" +msgstr "" msgid "Jump to model publish web page" -msgstr "Jump to model publish web page" +msgstr "" msgid "Note: The preparation may takes several minutes. Please be patiant." -msgstr "Note: The preparation may take several minutes. Please be patient." +msgstr "" msgid "Publish" msgstr "Közzététel" @@ -3356,7 +3464,7 @@ msgid "Packing data to 3mf" msgstr "Adatok csomagolása 3mf-be" msgid "Jump to webpage" -msgstr "Jump to webpage" +msgstr "" #, c-format, boost-format msgid "Save %s as" @@ -3369,7 +3477,7 @@ msgid "Project Inside Preset" msgstr "Projekt a beállításon belül" msgid "Name is invalid;" -msgstr "Name is invalid;" +msgstr "" msgid "illegal characters:" msgstr "tiltott karakterek:" @@ -3378,7 +3486,7 @@ msgid "illegal suffix:" msgstr "tiltott utótag:" msgid "Name is unavailable." -msgstr "Name is unavailable." +msgstr "" msgid "Overwrite a system profile is not allowed" msgstr "A rendszerprofil felülírása nem engedélyezett" @@ -3395,16 +3503,16 @@ msgid "Please note that saving action will replace this preset" msgstr "Figyelem, a mentési művelet lecseréli ezt a beállítást" msgid "The name is not allowed to be empty." -msgstr "The name field is not allowed to be empty." +msgstr "" msgid "The name is not allowed to start with space character." -msgstr "The name is not allowed to start with a space." +msgstr "" msgid "The name is not allowed to end with space character." -msgstr "The name is not allowed to end with a space." +msgstr "" msgid "The name cannot be the same as a preset alias name." -msgstr "The name cannot be the same as a preset alias name." +msgstr "" msgid "Save preset" msgstr "Beállítás mentése" @@ -3423,22 +3531,16 @@ msgstr "Kérjük, válassz egy műveletet a(z) \"%1%\" beállítással a mentés #, boost-format msgid "For \"%1%\", change \"%2%\" to \"%3%\" " -msgstr "For \"%1%\", change \"%2%\" to \"%3%\" " +msgstr "" #, boost-format msgid "For \"%1%\", add \"%2%\" as a new preset" -msgstr "For \"%1%\", add \"%2%\" as a new preset" +msgstr "" #, boost-format msgid "Simply switch to \"%1%\"" msgstr "Csak válts a(z) \"%1%\"-ra" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - msgid "My Device" msgstr "Saját eszköz" @@ -3446,10 +3548,10 @@ msgid "Other Device" msgstr "Egyéb eszköz" msgid "Input access code" -msgstr "Input access code" +msgstr "" msgid "Log out successful." -msgstr "Log out successful." +msgstr "" msgid "Busy" msgstr "Elfoglalt" @@ -3482,16 +3584,16 @@ msgid "send completed" msgstr "küldés befejezve" msgid "No login account, only printers in LAN mode are displayed" -msgstr "No login account, only printers in LAN mode are displayed" +msgstr "" msgid "Connecting to server" msgstr "Csatlakozás a szerverhez" msgid "Synchronizing device information" -msgstr "Synchronizing device information" +msgstr "" msgid "Synchronizing device information time out" -msgstr "Synchronizing device information time out" +msgstr "" msgid "Cannot send the print task when the upgrade is in progress" msgstr "" @@ -3501,10 +3603,9 @@ msgstr "" msgid "" "The printer is executing instructions. Please restart printing after it ends" msgstr "" -"The printer is executing instructions. Please restart printing after it ends" msgid "The printer is busy on other print job" -msgstr "The printer is busy with another print job." +msgstr "" #, c-format, boost-format msgid "" @@ -3521,15 +3622,11 @@ msgid "" "Filaments to AMS slots mappings have been established. You can click a " "filament above to change its mapping AMS slot" msgstr "" -"Filaments to AMS slots mappings have been established. You can click a " -"filament above to change its mapping AMS slot" msgid "" "Please click each filament above to specify its mapping AMS slot before " "sending the print job" msgstr "" -"Please click each filament above to specify its mapping AMS slot before " -"sending the print job" #, c-format, boost-format msgid "" @@ -3551,28 +3648,28 @@ msgid "Preparing print job" msgstr "Nyomtatási feladat előkészítése" msgid "Modifying the device name" -msgstr "Modifying the device name" +msgstr "" msgid "Log in printer" -msgstr "Log in printer" +msgstr "" msgid "Would you like to log in this printer with current account?" -msgstr "Would you like to log in this printer with the current account?" +msgstr "" msgid "Log in successful." -msgstr "Log in successful." +msgstr "" msgid "Log out printer" -msgstr "Log out printer" +msgstr "" msgid "Would you like to log out the printer?" -msgstr "Would you like to log out the printer?" +msgstr "" msgid "Please log in first." msgstr "Kérjük, előbb jelentkezz be." msgid "There was a problem connecting to the printer. Please try again." -msgstr "There was a problem connecting to the printer. Please try again." +msgstr "" msgid "Failed to log out." msgstr "Sikertelen kijelentkezés." @@ -3585,6 +3682,15 @@ msgstr "Jelenlegi %s mentése" msgid "Delete this preset" msgstr "Ezen beállítás törlése" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3621,9 +3727,6 @@ msgid "" "expressed as a percentage of line width. 0 speed means no slowing down for " "the overhang degree range and wall speed is used" msgstr "" -"This is the speed for various overhang degrees. Overhang degrees are " -"expressed as a percentage of line width. 0 speed means no slowing down for " -"the overhang degree range and wall speed is used" msgid "Travel speed" msgstr "Mozgás sebessége" @@ -3697,7 +3800,7 @@ msgid "Nozzle" msgstr "Fúvóka" msgid "Nozzle temperature when printing" -msgstr "Nozzle temperature when printing" +msgstr "" msgid "Cool plate" msgstr "Cool plate" @@ -3730,6 +3833,14 @@ msgstr "" "jelenti, hogy a filament nem támogatja a High Temp Plate-re történő " "nyomtatást" +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Volumetric speed limitation" msgstr "Volumetrikus sebességhatár" @@ -3807,7 +3918,7 @@ msgid "Motion ability" msgstr "Géplimitek" msgid "Normal" -msgstr "Normal" +msgstr "" msgid "Speed limitation" msgstr "Sebesség limitek" @@ -3819,13 +3930,13 @@ msgid "Jerk limitation" msgstr "Jerk limitek" msgid "Layer height limits" -msgstr "Layer height limits" +msgstr "" msgid "Retraction when switching material" msgstr "Visszahúzás anyagváltáskor" msgid "Detached" -msgstr "Detached" +msgstr "" msgid "Following preset will be deleted too." msgid_plural "Following presets will be deleted too." @@ -3834,7 +3945,7 @@ msgstr[1] "A következő beállítások szintén törlődni fognak." #, boost-format msgid "Are you sure to %1% the selected preset?" -msgstr "Are you sure you want to %1% the selected preset?" +msgstr "" #. TRN Remove/Delete #, boost-format @@ -3851,7 +3962,7 @@ msgid "Custom G-code" msgstr "Egyedi G-kód" msgid "Click to reset current value and attach to the global value." -msgstr "Click to reset current value and attach to the global value." +msgstr "" msgid "Click to drop current modify and reset to saved value." msgstr "" @@ -3862,10 +3973,10 @@ msgid "Process Settings" msgstr "Folyamatbeállítások" msgid "Undef" -msgstr "Undefined" +msgstr "" msgid "Unsaved Changes" -msgstr "unsaved changes" +msgstr "" msgid "Discard or Keep changes" msgstr "Változások elvetése vagy megtartása" @@ -3877,7 +3988,7 @@ msgid "New Value" msgstr "Új érték" msgid "Transfer" -msgstr "Transfer" +msgstr "" msgid "Don't save" msgstr "Ne mentsd" @@ -3898,10 +4009,10 @@ msgid "Save the selected options." msgstr "A kiválasztott beállítások mentése." msgid "Keep the selected options." -msgstr "Keep the selected options." +msgstr "" msgid "Transfer the selected options to the newly selected preset." -msgstr "Transfer the selected options to the newly selected preset." +msgstr "" #, boost-format msgid "" @@ -3916,8 +4027,6 @@ msgid "" "Transfer the selected options to the newly selected preset \n" "\"%1%\"." msgstr "" -"Transfer the selected options to the newly selected preset \n" -"\"%1%\"." #, boost-format msgid "Preset \"%1%\" contains the following unsaved changes:" @@ -3957,6 +4066,12 @@ msgstr "Általános" msgid "Capabilities" msgstr "Képességek" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Beállítás borítóként" @@ -3965,7 +4080,7 @@ msgstr "Lefedés" #, boost-format msgid "The name \"%1%\" already exists." -msgstr "The name \"%1%\" already exists." +msgstr "" msgid "Basic Info" msgstr "Alapinformáció" @@ -3982,11 +4097,11 @@ msgstr "Összeszerelési útmutató" msgid "Choose files" msgstr "Fájlok kiválasztása" -msgid "Designer" -msgstr "Tervező" +msgid "Author" +msgstr "" msgid "Model Name" -msgstr "Model Name" +msgstr "" #, c-format, boost-format msgid "%s Update" @@ -4009,15 +4124,12 @@ msgstr "Nem kompatibilis konfiguráció" msgid "the configuration package is incompatible with current application." msgstr "" -"the configuration package is incompatible with the current application." #, c-format, boost-format msgid "" "The configuration package is incompatible with current application.\n" "%s will update the configuration package, Otherwise it won't be able to start" msgstr "" -"The configuration package is incompatible with the current application.\n" -"%s will update the configuration package to allow the application to start." #, c-format, boost-format msgid "Exit %s" @@ -4025,17 +4137,15 @@ msgstr "Kilépés %s" msgid "the Configuration package is incompatible with current APP." msgstr "" -"The configuration package is incompatible with the current version of Bambu " -"Studio." msgid "Configuration updates" msgstr "Konfiguráció frissítések" msgid "No updates available." -msgstr "No updates available." +msgstr "" msgid "The configuration is up to date." -msgstr "The configuration is up to date." +msgstr "" msgid "Auto-Calc" msgstr "Automatikus számítás" @@ -4050,34 +4160,34 @@ msgid "Flush multiplier" msgstr "Öblítési szorzó" msgid "unloaded" -msgstr "unloaded" +msgstr "" msgid "loaded" -msgstr "loaded" +msgstr "" msgid "Filament #" msgstr "Filament #" msgid "From" -msgstr "From" +msgstr "" msgid "To" -msgstr "To" +msgstr "" msgid "Login" msgstr "Bejelentkezés" msgid "The configuration package is changed in previous Config Guide" -msgstr "The configuration package is changed in previous Config Guide" +msgstr "" msgid "Configuration package changed" msgstr "Konfigurációs csomag megváltozott" msgid "Toolbar" -msgstr "Toolbar" +msgstr "" msgid "Objects list" -msgstr "Objects list" +msgstr "" msgid "Import geometry data from STL/STEP/3MF/OBJ/AMF files." msgstr "Geometriai adatok importálása STL/STEP/3MF/OBJ/AMF fájlokból." @@ -4088,6 +4198,9 @@ msgstr "Másolás a vágólapra" msgid "Paste from clipboard" msgstr "Beillesztés a vágólapról" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Gyorsgombok listájának megjelenítése" @@ -4110,7 +4223,7 @@ msgid "⌘+Any arrow" msgstr "⌘+Bármilyen nyíl gomb" msgid "Movement in camera space" -msgstr "Movement in camera space" +msgstr "" msgid "⌥+Left mouse button" msgstr "" @@ -4143,31 +4256,31 @@ msgid "Arrow Up" msgstr "Felfelé nyíl" msgid "Move selection 10 mm in positive Y direction" -msgstr "Move selection 10mm in positive Y direction" +msgstr "" msgid "Arrow Down" msgstr "Lefelé nyíl" msgid "Move selection 10 mm in negative Y direction" -msgstr "Move selection 10mm in negative Y direction" +msgstr "" msgid "Arrow Left" msgstr "Balra nyíl" msgid "Move selection 10 mm in negative X direction" -msgstr "Move selection 10mm in negative X direction" +msgstr "" msgid "Arrow Right" msgstr "Jobbra nyíl" msgid "Move selection 10 mm in positive X direction" -msgstr "Move selection 10mm in positive X direction" +msgstr "" msgid "Shift+Any arrow" msgstr "Shift+Bármelyik nyílgomb" msgid "Movement step set to 1 mm" -msgstr "Movement step set to 1mm" +msgstr "" msgid "keyboard 1-9: set filament for object/part" msgstr "filament hozzárendelése az objektumhoz/tárgyhoz" @@ -4218,19 +4331,22 @@ msgid "Gizmo FDM paint-on seam" msgstr "" msgid "Plater" -msgstr "Plater" +msgstr "" msgid "Move: press to snap by 1mm" -msgstr "Move: press to snap by 1mm" +msgstr "" msgid "⌘+Mouse wheel" msgstr "⌘+Egérgörgő" msgid "Support/Color Painting: adjust pen radius" -msgstr "Support/Color Painting: adjust pen radius" +msgstr "" + +msgid "⌥+Mouse wheel" +msgstr "" msgid "Support/Color Painting: adjust section position" -msgstr "Support/Color Painting: adjust section position" +msgstr "" msgid "Ctrl+Mouse wheel" msgstr "Ctrl+Egérgörgő" @@ -4248,7 +4364,7 @@ msgid "Delete objects, parts, modifiers " msgstr "Objektumok, tárgyak, módosítók törlése " msgid "Space" -msgstr "Space" +msgstr "" msgid "Select the object/part and press space to change the name" msgstr "" @@ -4256,7 +4372,7 @@ msgstr "" "megváltoztatásához" msgid "Mouse click" -msgstr "Mouse click" +msgstr "" msgid "Select the object/part and mouse click to change the name" msgstr "" @@ -4264,25 +4380,25 @@ msgstr "" "megváltoztatásához" msgid "Objects List" -msgstr "Objects List" +msgstr "" msgid "Vertical slider - Move active thumb Up" -msgstr "Vertical slider - Move active thumb Up" +msgstr "" msgid "Vertical slider - Move active thumb Down" -msgstr "Vertical slider - Move active thumb Down" +msgstr "" msgid "Horizontal slider - Move active thumb Left" -msgstr "Horizontal slider - Move active thumb Left" +msgstr "" msgid "Horizontal slider - Move active thumb Right" -msgstr "Horizontal slider - Move active thumb Right" +msgstr "" msgid "On/Off one layer mode of the vertical slider" -msgstr "On/Off one layer mode of the vertical slider" +msgstr "" msgid "Move slider 5x faster" -msgstr "Move slider 5x faster" +msgstr "" msgid "Shift+Mouse wheel" msgstr "Shift+Egérgörgő" @@ -4295,7 +4411,7 @@ msgid "version %s update information :" msgstr "" msgid "New version of Bambu Studio" -msgstr "New version of Bambu Studio" +msgstr "A Bambu Studio új verziója" msgid "Saving objects into the 3mf failed." msgstr "Az objektumok mentése a 3mf-be sikertelen volt." @@ -4319,7 +4435,7 @@ msgid "Repair failed." msgstr "Sikertelen javítás." msgid "Loading repaired objects" -msgstr "Loading repaired objects" +msgstr "" msgid "Exporting 3mf file failed" msgstr "3MF fájl exportálása sikertelen" @@ -4334,10 +4450,10 @@ msgid "Repaired 3mf file contains more than one object" msgstr "A megjavított 3mf fájl egynél több objektumot tartalmaz" msgid "Repaired 3mf file does not contain any volume" -msgstr "The repaired 3mf file does not contain any volume." +msgstr "" msgid "Repaired 3mf file contains more than one volume" -msgstr "The repaired 3mf file contains more than one volume." +msgstr "" msgid "Repair finished" msgstr "Javítás befejezve" @@ -4354,38 +4470,34 @@ msgid "Copying directory %1% to %2% failed: %3%" msgstr "%1% mappa másolása sikertelen a következő helyre: %2% Hiba: %3%" msgid "Need to check the unsaved changes before configuration updates." -msgstr "Please check any unsaved changes before updating the configuration." +msgstr "" msgid "Configuration package updated to " msgstr "Konfigurációs csomag frissítve a következőre " msgid "Open G-code file:" -msgstr "Open G-code file:" +msgstr "" msgid "" "One object has empty initial layer and can't be printed. Please Cut the " "bottom or enable supports." msgstr "" -"One object has empty initial layer and can't be printed. Please Cut the " -"bottom or enable supports." #, boost-format msgid "Object can't be printed for empty layer between %1% and %2%." -msgstr "The object has empty layers between %1% and %2% and can’t be printed." +msgstr "" #, boost-format msgid "Object: %1%" -msgstr "Object: %1%" +msgstr "" msgid "" "Maybe parts of the object at these height are too thin, or the object has " "faulty mesh" msgstr "" -"Parts of the object at these heights may be too thin or the object may have " -"a faulty mesh." msgid "No object can be printed. Maybe too small" -msgstr "No object can be printed. It may be too small." +msgstr "" msgid "" "Failed to generate gcode for invalid custom G-code.\n" @@ -4434,44 +4546,44 @@ msgid "Support interface" msgstr "Támasz érintkező felület" msgid "Support transition" -msgstr "Support transition" +msgstr "" msgid "Multiple" -msgstr "Multiple" +msgstr "" #, boost-format msgid "Failed to calculate line width of %1%. Can not get value of \"%2%\" " -msgstr "Failed to calculate line width of %1%. Cannot get value of “%2%” " +msgstr "" msgid "undefined error" -msgstr "undefined error" +msgstr "" msgid "too many files" -msgstr "too many files" +msgstr "" msgid "file too large" msgstr "fájl túl nagy" msgid "unsupported method" -msgstr "unsupported method" +msgstr "" msgid "unsupported encryption" -msgstr "unsupported encryption" +msgstr "" msgid "unsupported feature" -msgstr "unsupported feature" +msgstr "" msgid "failed finding central directory" msgstr "nem sikerült megtalálni a központi könyvtárat" msgid "not a ZIP archive" -msgstr "not a ZIP archive" +msgstr "" msgid "invalid header or corrupted" -msgstr "invalid header or corrupted" +msgstr "" msgid "unsupported multidisk" -msgstr "Saving to RAID is not supported." +msgstr "" msgid "decompression failed" msgstr "sikertelen kicsomagolás" @@ -4480,13 +4592,13 @@ msgid "compression failed" msgstr "tömörítés sikertelen" msgid "unexpected decompressed size" -msgstr "unexpected decompressed size" +msgstr "" msgid "CRC check failed" msgstr "CRC-ellenőrzés sikertelen" msgid "unsupported central directory size" -msgstr "unsupported central directory size" +msgstr "" msgid "allocation failed" msgstr "sikertelen allokáció" @@ -4513,16 +4625,16 @@ msgid "file stat failed" msgstr "fájl stat sikertelen" msgid "invalid parameter" -msgstr "invalid parameter" +msgstr "" msgid "invalid filename" -msgstr "invalid filename" +msgstr "" msgid "buffer too small" msgstr "túl kicsi puffer" msgid "internal error" -msgstr "internal error" +msgstr "" msgid "file not found" msgstr "fájl nem található" @@ -4531,10 +4643,10 @@ msgid "archive too large" msgstr "archívum túl nagy" msgid "validation failed" -msgstr "validation failed" +msgstr "" msgid "write callback failed" -msgstr "write callback failed" +msgstr "" #, boost-format msgid "" @@ -4595,7 +4707,7 @@ msgstr "" "megsérülhet nyomtatás közben" msgid "No extrusions under current settings." -msgstr "No extrusions under current settings." +msgstr "" msgid "" "Please select \"By object\" print sequence to print multiple objects in " @@ -4608,58 +4720,47 @@ msgid "" "The spiral vase mode does not work when an object contains more than one " "materials." msgstr "" -"Spiral (vase) mode does not work when an object contains more than one " -"material." msgid "The prime tower is not supported in \"By object\" print." -msgstr "A prime tower is not supported in “By object” print." +msgstr "" msgid "" "The prime tower is not supported when adaptive layer height is on. It " "requires that all objects have the same layer height." msgstr "" -"A prime tower is not supported when adaptive layer height is on. It requires " -"that all objects have the same layer height." msgid "The prime tower requires \"support gap\" to be multiple of layer height" msgstr "" -"A prime tower requires any “support gap” to be a multiple of layer height." msgid "The prime tower requires that all objects have the same layer heights" -msgstr "A prime tower requires that all objects have the same layer height." +msgstr "" msgid "" "The prime tower requires that all objects are printed over the same number " "of raft layers" msgstr "" -"A prime tower requires that all objects are printed over the same number of " -"raft layers." msgid "" "The prime tower requires that all objects are sliced with the same layer " "heights." msgstr "" -"A prime tower requires that all objects are sliced with the same layer " -"height." msgid "Too small line width" -msgstr "Line width too small" +msgstr "" msgid "Too large line width" -msgstr "Line width too large" +msgstr "" msgid "" "The prime tower requires that support has the same layer height with object." msgstr "" -"A prime tower requires that support has the same layer height as the object." msgid "" "Support enforcers are used but support is not enabled. Please enable support." msgstr "" -"Support enforcers are used but support is not enabled. Please enable support." msgid "Layer height cannot exceed nozzle diameter" -msgstr "Layer height cannot exceed nozzle diameter." +msgstr "" #, c-format, boost-format msgid "Plate %d: %s does not support filament %s.\n" @@ -4711,8 +4812,6 @@ msgstr "Nyomtatási magasság" msgid "Maximum printable height which is limited by mechanism of printer" msgstr "" -"This is the maximum printable height which is limited by the height of the " -"build area." msgid "Printer preset names" msgstr "Nyomtató beállítások neve" @@ -4731,8 +4830,6 @@ msgid "" "Maximum detour distance for avoiding crossing wall. Don't detour if the " "detour distance is large than this value" msgstr "" -"Maximum detour distance for avoiding travel across walls. If the distance is " -"larger than this value, there will be no detour." msgid "Other layers" msgstr "Többi réteg" @@ -4764,11 +4861,16 @@ msgstr "" "Az asztal hőmérséklete a kezdeti réteg kivételével. A 0 érték azt jelenti, " "hogy a szál nem támogatja a High Temp Plate-re történő nyomtatást" +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" + msgid "Initial layer" msgstr "Kezdőréteg" msgid "Initial layer bed temperature" -msgstr "First layer bed temperature" +msgstr "" msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " @@ -4791,6 +4893,11 @@ msgstr "" "A kezdőréteg asztalhőmérséklete. A 0 érték azt jelenti, hogy a filament nem " "támogatja a High Temp Plate-re történő nyomtatást" +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" + msgid "Bed types supported by the printer" msgstr "Nyomtató által támogatott asztaltípusok" @@ -4801,7 +4908,7 @@ msgid "Engineering Plate" msgstr "Engineering Plate" msgid "This G-code is inserted at every layer change before lifting z" -msgstr "This G-code is inserted at every layer change before lifting z." +msgstr "" msgid "Bottom shell layers" msgstr "Alsó héj rétegek" @@ -4811,9 +4918,6 @@ msgid "" "surface layer. When the thickness calculated by this value is thinner than " "bottom shell thickness, the bottom shell layers will be increased" msgstr "" -"This is the number of solid layers of bottom shell, including the bottom " -"surface layer. When the thickness calculated by this value is thinner than " -"bottom shell thickness, the bottom shell layers will be increased" msgid "Bottom shell thickness" msgstr "Alsó héj vastagság" @@ -4825,11 +4929,6 @@ msgid "" "is disabled and thickness of bottom shell is absolutely determained by " "bottom shell layers" msgstr "" -"The number of bottom solid layers is increased when slicing if the thickness " -"calculated by bottom shell layers is thinner than this value. This can avoid " -"having too thin a shell when layer height is small. 0 means that this " -"setting is disabled and the thickness of the bottom shell is determined " -"simply by the number of bottom shell layers." msgid "Force cooling for overhang and bridge" msgstr "Hűtés kényszerítése túlnyúlásoknál és áthidalásoknál" @@ -4849,9 +4948,6 @@ msgid "" "wall which has large overhang degree. Forcing cooling for overhang and " "bridge can get better quality for these part" msgstr "" -"Force part cooling fan to be this speed when printing bridges or overhang " -"walls which have a large overhang degree. Forcing cooling for overhangs and " -"bridges can achieve better quality for these parts." msgid "Cooling overhang threshold" msgstr "Túlnyúlás hűtésének küszöbértéke" @@ -4861,9 +4957,6 @@ msgid "" "exceeds this value. Expressed as percentage which indicides how much width " "of the line without support from lower layer" msgstr "" -"This forces the cooling fan to use a specific speed when overhang degrees of " -"parts exceed the set value. It is expressed as percentage which indicates " -"how much line is acceptable without support from lower layers." msgid "Bridge flow" msgstr "Áthidalás áramlási sebessége" @@ -4882,8 +4975,6 @@ msgid "" "Use only one wall on flat top surface, to give more space to the top infill " "pattern" msgstr "" -"Use only one wall on flat top surfaces, to give more space to the top infill " -"pattern" msgid "Slow down for overhang" msgstr "Lassítás túlnyúlásoknál" @@ -4913,9 +5004,6 @@ msgid "" "holes or both. Auto means both the brim position and brim width is analysed " "and calculated automatically" msgstr "" -"This controls brim position including outer side of models, inner side of " -"holes, or both. Auto means both the brim position and brim width are " -"analyzed and calculated automatically." msgid "Brim-object gap" msgstr "Perem-tárgy közötti rés" @@ -4973,8 +5061,6 @@ msgid "" "The default acceleration of both normal printing and travel except initial " "layer" msgstr "" -"This is the default acceleration for both normal printing and travel after " -"the first layer." msgid "mm/s²" msgstr "mm/s²" @@ -5038,9 +5124,6 @@ msgid "" "bridges to be supported, and set it to a very large value if you don't want " "any bridges to be supported." msgstr "" -"This is the maximum length of bridges that don't need support. Set it to 0 " -"if you want all bridges to be supported, and set it to a very large value if " -"you don't want any bridges to be supported." msgid "End G-code" msgstr "Befejező G-kód" @@ -5055,7 +5138,7 @@ msgid "Top surface pattern" msgstr "Felső felület mintázata" msgid "Line pattern of top surface infill" -msgstr "This is the line pattern for top surface infill." +msgstr "" msgid "Concentric" msgstr "Koncentrikus" @@ -5074,11 +5157,9 @@ msgstr "Alsó felület mintázata" msgid "Line pattern of bottom surface infill, not bridge infill" msgstr "" -"This is the line pattern of bottom surface infill, not including bridge " -"infill." msgid "Line width of outer wall" -msgstr "Line width of outer wall" +msgstr "" msgid "" "Speed of outer wall which is outermost and visible. It's used to be slower " @@ -5106,17 +5187,15 @@ msgid "infill/outer/inner" msgstr "kitöltés/külső/belső" msgid "Height to rod" -msgstr "Height to rod" +msgstr "" msgid "" "Height of the clearance cylinder around extruder. Used as input of auto-" "arrange to avoid collision when print object by object" msgstr "" -"Height of the clearance cylinder around extruder: used as input for auto-" -"arranging to avoid collisions when printing object by object" msgid "Height to lid" -msgstr "Height to lid" +msgstr "" msgid "Radius" msgstr "Radius" @@ -5133,7 +5212,7 @@ msgid "Extruder Color" msgstr "Extruder szín" msgid "Only used as a visual help on UI" -msgstr "Only used as a visual help on UI" +msgstr "" msgid "Extruder offset" msgstr "Extruder offszet" @@ -5148,11 +5227,6 @@ msgid "" "and 1.05. Maybe you can tune this value to get nice flat surface when there " "has slight overflow or underflow" msgstr "" -"The material may have volumetric change after switching between molten and " -"crystalline states. This setting changes all extrusion flow of this filament " -"in G-code proportionally. The recommended value range is between 0.95 and " -"1.05. You may be able to tune this value to get a nice flat surface if there " -"is slight overflow or underflow." msgid "Default line width if some line width is set to be zero" msgstr "" @@ -5197,15 +5271,12 @@ msgid "" "extruded per second. Printing speed is limited by max volumetric speed, in " "case of too high and unreasonable speed setting. Zero means no limit" msgstr "" -"Use this to set the maximum volume of filament that can be melted and " -"extruded per second. Printing speed is limited by maximum volumetric speed " -"if settings are unreasonably high. 0 means there is no limit." msgid "mm³/s" msgstr "mm³/s" msgid "Minimal purge on wipe tower" -msgstr "Minimal purge on wipe tower" +msgstr "" msgid "mm³" msgstr "mm³" @@ -5215,16 +5286,12 @@ msgstr "Filament betöltési idő" msgid "Time to load new filament when switch filament. For statistics only" msgstr "" -"Time to load new filament when switching filament, for statistical purposes " -"only." msgid "Filament unload time" msgstr "Filament kitöltési idő" msgid "Time to unload old filament when switch filament. For statistics only" msgstr "" -"Time to unload old filament when switching filament, for statistical " -"purposes only." msgid "" "Filament diameter is used to calculate extrusion in gcode, so it's important " @@ -5246,7 +5313,7 @@ msgid "Type" msgstr "Típus" msgid "The material type of filament" -msgstr "Filament material type" +msgstr "" msgid "Soluble material" msgstr "Oldható anyag" @@ -5258,12 +5325,11 @@ msgstr "" "használják" msgid "Support material" -msgstr "Support material" +msgstr "" msgid "" "Support material is commonly used to print support and support interface" msgstr "" -"Support material is commonly used to print support and support interfaces." msgid "Temperature of vitrificaiton" msgstr "Üvegesedési hőmérséklet" @@ -5272,8 +5338,6 @@ msgid "" "Material becomes soft at this temperature. Thus the heatbed cannot be hotter " "than this tempature" msgstr "" -"Material becomes soft at this temperature. Thus, the heat bed cannot be " -"hotter than this temperature." msgid "Price" msgstr "Költség" @@ -5282,7 +5346,7 @@ msgid "Filament price. For statistics only" msgstr "Filament költsége. Csak statisztikákhoz kerül felhasználásra" msgid "money/kg" -msgstr "money/kg" +msgstr "" msgid "(Undefined)" msgstr "(Undefined)" @@ -5303,14 +5367,12 @@ msgstr "Kitöltés sűrűsége" #, c-format msgid "Density of internal sparse infill, 100% means solid throughout" msgstr "" -"This is the density of internal sparse infill. 100% means that the object " -"will be solid throughout." msgid "Sparse infill pattern" msgstr "Kitöltési mintázat" msgid "Line pattern for internal sparse infill" -msgstr "This is the line pattern for internal sparse infill." +msgstr "" msgid "Grid" msgstr "Rács" @@ -5348,7 +5410,7 @@ msgstr "" "tárgyasztalhoz való tapadást" msgid "Line width of initial layer" -msgstr "Line width of first layer" +msgstr "" msgid "Initial layer height" msgstr "Kezdő rétegmagasság" @@ -5386,10 +5448,10 @@ msgid "Speed of solid infill part of initial layer" msgstr "A kezdőréteg szilárd kitöltési részének sebessége" msgid "Initial layer nozzle temperature" -msgstr "First layer nozzle temperature" +msgstr "" msgid "Nozzle temperature to print initial layer when using this filament" -msgstr "Nozzle temperature for printing the first layer with this filament" +msgstr "" msgid "Full fan speed at layer" msgstr "Teljes ventilátor fordulatszám ennél a rétegnél" @@ -5414,8 +5476,6 @@ msgid "" "The width within which to jitter. It's adversed to be below outer wall line " "width" msgstr "" -"The width of jittering: it’s recommended to keep this lower than the outer " -"wall line width." msgid "Fuzzy skin point distance" msgstr "Fuzzy skin pontok távolsága" @@ -5424,8 +5484,6 @@ msgid "" "The average diatance between the random points introducded on each line " "segment" msgstr "" -"The average diatance between the random points introducded on each line " -"segment" msgid "" "Speed of gap infill. Gap usually has irregular line width and should be " @@ -5449,7 +5507,6 @@ msgstr "Vonalszám hozzáadása" msgid "Enable this to add line number(Nx) at the beginning of each G-Code line" msgstr "" -"Enable this to add line number(Nx) at the beginning of each G-Code line." msgid "Scan first layer" msgstr "Az első réteg szkennelése" @@ -5468,8 +5525,6 @@ msgid "" "The metallic material of nozzle. This determines the abrasive resistance of " "nozzle, and what kind of filament can be printed" msgstr "" -"The metallic material of the nozzle: This determines the abrasive resistance " -"of the nozzle and what kind of filament can be printed." msgid "Hardened steel" msgstr "Edzett acél" @@ -5489,7 +5544,7 @@ msgid "G-code flavor" msgstr "G-kód változat" msgid "What kind of gcode the printer is compatible with" -msgstr "What kind of G-code the printer is compatible with." +msgstr "" msgid "Infill combination" msgstr "Kitöltés összevonása" @@ -5506,7 +5561,7 @@ msgid "Filament to print internal sparse infill." msgstr "Filament a belső ritkás kitöltésekhez." msgid "Line width of internal sparse infill" -msgstr "Line width of internal sparse infill" +msgstr "" msgid "Infill/Wall overlap" msgstr "Kitöltés/fal átfedés" @@ -5515,9 +5570,6 @@ msgid "" "Infill area is enlarged slightly to overlap with wall for better bonding. " "The percentage value is relative to line width of sparse infill" msgstr "" -"This allows the infill area to be enlarged slightly to overlap with walls " -"for better bonding. The percentage value is relative to line width of sparse " -"infill." msgid "Speed of internal sparse infill" msgstr "A belső ritkás kitöltés sebessége" @@ -5529,8 +5581,6 @@ msgid "" "Ironing is using small flow to print on same height of surface again to make " "flat surface more smooth. This setting controls which layer being ironed" msgstr "" -"Ironing uses a small flow to print at the same height of a surface to make " -"flat surfaces smoother. This setting controls which layers are being ironed." msgid "No ironing" msgstr "Nincs vasalás" @@ -5551,34 +5601,29 @@ msgid "" "The amount of material to extrude during ironing. Relative to flow of normal " "layer height. Too high value results in overextrusion on the surface" msgstr "" -"This is the amount of material to be extruded during ironing. It is relative " -"to the flow of normal layer height. Too high a value will result in " -"overextrusion on the surface." msgid "Ironing line spacing" msgstr "Vasalási vonalak közötti távolság" msgid "The distance between the lines of ironing" -msgstr "This is the distance between the lines used for ironing." +msgstr "" msgid "Ironing speed" -msgstr "Ironing speed" +msgstr "" msgid "Print speed of ironing lines" msgstr "A vasalási vonalak nyomtatási sebessége" msgid "This gcode part is inserted at every layer change after lift z" -msgstr "This G-code is inserted at every layer change after the z lift." +msgstr "" msgid "Supports silent mode" -msgstr "Silent Mode" +msgstr "" msgid "" "Whether the machine supports silent mode in which machine use lower " "acceleration to print" msgstr "" -"Whether the machine supports silent mode in which machine uses lower " -"acceleration to print more quietly" msgid "Maximum speed X" msgstr "Maximális sebesség X" @@ -5644,46 +5689,46 @@ msgid "Maximum jerk E" msgstr "Maximális jerk E" msgid "Maximum jerk of the X axis" -msgstr "Maximum jerk of the X axis" +msgstr "" msgid "Maximum jerk of the Y axis" -msgstr "Maximum jerk of the Y axis" +msgstr "" msgid "Maximum jerk of the Z axis" -msgstr "Maximum jerk of the Z axis" +msgstr "" msgid "Maximum jerk of the E axis" -msgstr "Maximum jerk of the E axis" +msgstr "" msgid "Minimum speed for extruding" -msgstr "Minimum speed for extruding" +msgstr "" msgid "Minimum speed for extruding (M205 S)" -msgstr "Minimum speed for extruding (M205 S)" +msgstr "" msgid "Minimum travel speed" -msgstr "Minimum travel speed" +msgstr "" msgid "Minimum travel speed (M205 T)" -msgstr "Minimum travel speed (M205 T)" +msgstr "" msgid "Maximum acceleration for extruding" -msgstr "Maximum acceleration for extruding" +msgstr "" msgid "Maximum acceleration for extruding (M204 P)" -msgstr "Maximum acceleration for extruding (M204 P)" +msgstr "" msgid "Maximum acceleration for retracting" -msgstr "Maximum acceleration for retracting" +msgstr "" msgid "Maximum acceleration for retracting (M204 R)" -msgstr "Maximum acceleration for retracting (M204 R)" +msgstr "" msgid "Maximum acceleration for travel" -msgstr "Maximum acceleration for travel" +msgstr "" msgid "Maximum acceleration for travel (M204 T)" -msgstr "Maximum acceleration for travel (M204 T)" +msgstr "" msgid "Fan speed" msgstr "Ventilátor fordulatszám" @@ -5702,11 +5747,9 @@ msgid "" "The largest printable layer height for extruder. Used tp limits the maximum " "layer hight when enable adaptive layer height" msgstr "" -"The highest printable layer height for the extruder: this is used to limit " -"the maximum layer height when adaptive layer height is enabled." msgid "Minimum speed for part cooling fan" -msgstr "Minimum speed for part cooling fan" +msgstr "" msgid "" "Speed of auxiliary part cooling fan. Auxiliary fan will run at this speed " @@ -5724,26 +5767,24 @@ msgid "" "The lowest printable layer height for extruder. Used tp limits the minimum " "layer hight when enable adaptive layer height" msgstr "" -"The lowest printable layer height for the extruder. This is used to limit " -"the minimum layer height when adaptive layer height is enabled." msgid "Min print speed" -msgstr "Min print speed" +msgstr "" msgid "The minimum printing speed when slow down for cooling" -msgstr "The minimum printing speed when slowing down for cooling." +msgstr "" msgid "Nozzle diameter" -msgstr "Nozzle diameter" +msgstr "" msgid "Diameter of nozzle" msgstr "Fúvóka átmérője" msgid "Nozzle volume" -msgstr "Nozzle volume" +msgstr "" msgid "Volume of nozzle between the cutter and the end of nozzle" -msgstr "Volume of nozzle between the filament cutter and the end of the nozzle" +msgstr "" msgid "Reduce infill retraction" msgstr "Csökkentett visszahúzás kitöltésnél" @@ -5766,7 +5807,7 @@ msgid "Filename format" msgstr "Fájlnév formátum" msgid "User can self-define the project file name when export" -msgstr "Users can decide project file names when exporting." +msgstr "" msgid "Detect overhang wall" msgstr "Túlnyúló fal felismerése" @@ -5781,21 +5822,19 @@ msgstr "" "beállított sebességet használja." msgid "Line width of inner wall" -msgstr "Line width of inner walls" +msgstr "" msgid "Speed of inner wall" msgstr "A belső fal nyomtatási sebessége" msgid "Number of walls of every layer" -msgstr "This is the number of walls per layer." +msgstr "" msgid "Raft contact Z distance" msgstr "Tutaj érintkezés Z távolság" msgid "Z gap between object and raft. Ignored for soluble interface" msgstr "" -"This is the Z gap between an object and a raft. It is ignored for soluble " -"interfaces." msgid "Raft expansion" msgstr "Tutaj kibővítése" @@ -5804,16 +5843,16 @@ msgid "Expand all raft layers in XY plane" msgstr "Összes tutaj réteg kiterjesztése az XY síkban" msgid "Initial layer density" -msgstr "First layer density" +msgstr "" msgid "Density of the first raft or support layer" msgstr "Az első tutaj vagy támasz réteg sűrűsége" msgid "Initial layer expansion" -msgstr "First layer expansion" +msgstr "" msgid "Expand the first raft or support layer to improve bed plate adhesion" -msgstr "This expands the first raft or support layer to improve bed adhesion." +msgstr "" msgid "Raft layers" msgstr "Tutaj rétegek" @@ -5822,8 +5861,6 @@ msgid "" "Object will be raised by this number of support layers. Use this function to " "avoid wrapping when print ABS" msgstr "" -"Object will be raised by this number of support layers. Use this function to " -"avoid warping when printing ABS." msgid "Resolution" msgstr "Felbontás" @@ -5844,8 +5881,6 @@ msgid "" "Only trigger retraction when the travel distance is longer than this " "threshold" msgstr "" -"Only trigger retraction when the travel distance is longer than this " -"threshold." msgid "Retract amount before wipe" msgstr "Visszahúzott mennyiség törlés előtt" @@ -5853,8 +5888,6 @@ msgstr "Visszahúzott mennyiség törlés előtt" msgid "" "The length of fast retraction before wipe, relative to retraction length" msgstr "" -"This is the length of fast retraction before a wipe, relative to retraction " -"length." msgid "Retract when change layer" msgstr "Visszahúzás rétegváltáskor" @@ -5884,10 +5917,6 @@ msgid "" "clearance between nozzle and the print. It prevents nozzle from hitting the " "print when travel move. Using spiral line to lift z can prevent stringing" msgstr "" -"Whenever there is a retraction, the nozzle is lifted a little to create " -"clearance between the nozzle and the print. This prevents the nozzle from " -"hitting the print when traveling more. Using spiral lines to lift z can " -"prevent stringing." msgid "Retraction Speed" msgstr "Visszahúzás sebessége" @@ -5909,7 +5938,7 @@ msgid "Seam position" msgstr "Varrat pozíció" msgid "The start position to print each part of outer wall" -msgstr "This is the starting position for each part of the outer wall." +msgstr "" msgid "Nearest" msgstr "Legközelebbi" @@ -5920,6 +5949,9 @@ msgstr "Igazított" msgid "Back" msgstr "Hátul" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Szoknya távolsága" @@ -5942,9 +5974,6 @@ msgid "" "The printing speed in exported gcode will be slowed down, when the estimated " "layer time is shorter than this value, to get better cooling for these layers" msgstr "" -"The printing speed in exported G-code will be slowed down when the estimated " -"layer time is shorter than this value in order to get better cooling for " -"these layers." msgid "Minimum sparse infill threshold" msgstr "Ritkás kitöltés küszöbértéke" @@ -5960,7 +5989,7 @@ msgid "mm²" msgstr "mm²" msgid "Line width of internal solid infill" -msgstr "Line width of internal solid infill" +msgstr "" msgid "Speed of internal solid infill, not the top and bottom surface" msgstr "" @@ -5980,19 +6009,16 @@ msgstr "" "varratok" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Timelapse videófelvétel készítése a nyomtatásról a nyomtatófej megjelenítése " -"nélkül. Ebben az üzemmódban a nyomtatófej minden rétegváltásnál kiáll a " -"felesleges anyagot kidobó nyílás közelében, majd a kamerával " -"pillanatfelvétel készül. A nyomtatás befejezésekor egy timelapse videó áll " -"össze az összes pillanatfelvételből." msgid "Temperature variation" -msgstr "Temperature variation" +msgstr "" msgid "Start G-code" msgstr "Kezdő G-kód" @@ -6013,9 +6039,6 @@ msgid "" "normal(auto) and tree(auto) is used to generate support automatically. If " "normal or tree is selected, only support enforcers are generated" msgstr "" -"normal(auto), hybrid(auto) and tree(auto) are used to generate support " -"automatically. If normal or tree is selected, only support enforcers are " -"generated." msgid "normal(auto)" msgstr "normál (auto)" @@ -6036,14 +6059,13 @@ msgid "Support/object xy distance" msgstr "Támasz/tárgy XY távolság" msgid "XY separation between an object and its support" -msgstr "This controls the XY separation between an object and its support." +msgstr "" msgid "Pattern angle" msgstr "Mintázat szöge" msgid "Use this setting to rotate the support pattern on the horizontal plane." msgstr "" -"Use this setting to rotate the support pattern on the horizontal plane." msgid "On build plate only" msgstr "Csak a tárgyasztaltól" @@ -6055,7 +6077,7 @@ msgid "Top Z distance" msgstr "Z távolság" msgid "The z gap between the top support interface and object" -msgstr "This determines the Z gap between top support interfaces and objects." +msgstr "" msgid "" "Filament to print support and skirt. 0 means no specific filament for " @@ -6065,10 +6087,10 @@ msgstr "" "külön kijelölt filament és a jelenleg használt kerül felhasználásra" msgid "Line width of support" -msgstr "Line width of support" +msgstr "" msgid "Interface use loop pattern" -msgstr "Loop pattern interface" +msgstr "" msgid "" "Cover the top contact layer of the supports with loops. Disabled by default." @@ -6088,7 +6110,7 @@ msgid "Top interface layers" msgstr "Felső érintkező rétegek" msgid "Number of top interface layers" -msgstr "This is the number of top interface layers." +msgstr "" msgid "Bottom interface layers" msgstr "Alsó érintkező rétegek" @@ -6114,7 +6136,7 @@ msgid "Base pattern" msgstr "Alap mintázata" msgid "Line pattern of support" -msgstr "This is the line pattern for support." +msgstr "" msgid "Rectilinear" msgstr "Vonalak" @@ -6147,19 +6169,15 @@ msgid "Style" msgstr "Stílus" msgid "Snug" -msgstr "Snug" +msgstr "" msgid "Independent support layer height" msgstr "Független támasz rétegmagassága" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"The support layer uses layer height independent of object layers. This is to " -"support custom support gaps, but may cause extra filament switches if " -"support is specified as a different filament from the object." msgid "Threshold angle" msgstr "Dőlésszög küszöbértéke" @@ -6168,56 +6186,48 @@ msgid "" "Support will be generated for overhangs whose slope angle is below the " "threshold." msgstr "" -"Support will be generated for overhangs whose slope angle is below this " -"threshold." msgid "Tree support branch angle" -msgstr "Tree support branch angle" +msgstr "" msgid "" "This setting determines the maximum overhang angle that t he branches of " "tree support allowed to make.If the angle is increased, the branches can be " "printed more horizontally, allowing them to reach farther." msgstr "" -"This setting determines the maximum overhang angle that the branches of tree " -"support are allowed to make. If the angle is increased, the branches can be " -"printed more horizontally, allowing them to reach farther." msgid "Tree support branch distance" -msgstr "Tree support branch distance" +msgstr "" msgid "" "This setting determines the distance between neighboring tree support nodes." msgstr "" -"This setting determines the distance between neighboring tree support nodes." msgid "Tree support branch diameter" -msgstr "Tree support branch diameter" +msgstr "" msgid "This setting determines the initial diameter of support nodes." -msgstr "This setting determines the initial diameter of support nodes." +msgstr "" msgid "Tree support wall loops" -msgstr "Tree support wall loops" +msgstr "" msgid "This setting specify the count of walls around tree support" -msgstr "This setting specifies the wall count around tree support." +msgstr "" msgid "Tree support with infill" -msgstr "Tree support with infill" +msgstr "" msgid "" "This setting specifies whether to add infill inside large hollows of tree " "support" msgstr "" -"This setting specifies whether to add infill inside large hollows of tree " -"support." msgid "Nozzle temperature for layers after the initial one" -msgstr "Nozzle temperature after the first layer" +msgstr "" msgid "Nozzle temperature" -msgstr "Nozzle temperature" +msgstr "" msgid "Bed temperature difference" msgstr "Asztalhőmérséklet különbség" @@ -6246,11 +6256,9 @@ msgid "" "This gcode is inserted when change filament, including T command to trigger " "tool change" msgstr "" -"This G-code is inserted when filament is changed, including T commands to " -"trigger tool change." msgid "Line width for top surfaces" -msgstr "Line width for top surfaces" +msgstr "" msgid "Speed of top surface infill which is solid" msgstr "A felső felületi kitöltés sebessége, amely szilárd" @@ -6263,12 +6271,9 @@ msgid "" "layer. When the thickness calculated by this value is thinner than top shell " "thickness, the top shell layers will be increased" msgstr "" -"This is the number of solid layers of top shell, including the top surface " -"layer. When the thickness calculated by this value is thinner than the top " -"shell thickness, the top shell layers will be increased" msgid "Top solid layers" -msgstr "Top solid layers" +msgstr "" msgid "Top shell thickness" msgstr "Felső héj vastagság" @@ -6280,11 +6285,6 @@ msgid "" "is disabled and thickness of top shell is absolutely determained by top " "shell layers" msgstr "" -"The number of top solid layers is increased when slicing if the thickness " -"calculated by top shell layers is thinner than this value. This can avoid " -"having too thin a shell when layer height is small. 0 means that this " -"setting is disabled and thickness of top shell is determined simply by the " -"number of top shell layers." msgid "Speed of travel which is faster and without extrusion" msgstr "Mozgási sebesség, amikor nem történik extrudálás" @@ -6296,9 +6296,6 @@ msgid "" "Move nozzle along the last extrusion path when retracting to clean leaked " "material on nozzle. This can minimize blob when print new part after travel" msgstr "" -"This moves the nozzle along the last extrusion path when retracting to clean " -"any leaked material on the nozzle. This can minimize blobs when printing a " -"new part after traveling." msgid "Wipe Distance" msgstr "Törlési távolság" @@ -6323,13 +6320,12 @@ msgstr "Öblítési mennyiség" msgid "The volume of material to prime extruder on tower." msgstr "" -"This is the volume of material to prime the extruder with on the tower." msgid "Width" msgstr "Szélesség" msgid "Width of prime tower" -msgstr "This is the width of prime towers." +msgstr "" msgid "Flush into objects' infill" msgstr "Öblítés a tárgyak kitöltésébe" @@ -6362,9 +6358,6 @@ msgid "" "filament and decrease the print time. Colours of the objects will be mixed " "as a result" msgstr "" -"This object will be used to purge the nozzle after a filament change to save " -"filament and decrease the print time. Colors of the objects will be mixed as " -"a result." msgid "X-Y hole compensation" msgstr "X-Y furatkompenzáció" @@ -6402,9 +6395,6 @@ msgid "" "concentric pattern will be used for the area to speed printing up. " "Otherwise, rectilinear pattern is used defaultly." msgstr "" -"This option will auto-detect narrow internal solid infill areas. If enabled, " -"the concentric pattern will be used for the area to speed up printing. " -"Otherwise, the rectilinear pattern will be used by default." msgid "Export 3MF" msgstr "3MF exportálása" @@ -6455,16 +6445,16 @@ msgid "Scale the model by a float factor" msgstr "A modell méretezése egy lebegő tényezővel" msgid "Load General Settings" -msgstr "Load General Settings" +msgstr "" msgid "Load process/machine settings from the specified file" -msgstr "Load process/machine settings from the specified file" +msgstr "" msgid "Load Filament Settings" -msgstr "Load Filament Settings" +msgstr "" msgid "Load filament settings from the specified file list" -msgstr "Load filament settings from the specified file list" +msgstr "" msgid "Output directory" msgstr "Kimeneti mappa" @@ -6502,25 +6492,23 @@ msgstr "Támasz szükségességének ellenőrzése" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Úgy tűnik %s objektumnak támaszra lenne szüksége a nyomtatáshoz. Kérjük, " -"engedélyezd a támasz generálását." msgid "Optimizing toolpath" msgstr "Szerszámút optimalizálása" msgid "Empty layers around bottom are replaced by nearest normal layers." -msgstr "Empty layers around bottom are replaced by nearest normal layers." - -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." msgstr "" -"The model has overlapping or self-intersecting facets. Repair was attempted, " -"however we recommend checking the results or repairing the input file and " -"retrying." + +msgid "The model has too many empty layers." +msgstr "" msgid "Slicing mesh" msgstr "Háló szeletelése" @@ -6534,49 +6522,59 @@ msgstr "Hiba a következő sorban %1%:\n" #, c-format, boost-format msgid "Support: generate toolpath at layer %d" -msgstr "Support: generate toolpath at layer %d" +msgstr "" msgid "Support: detect overhangs" -msgstr "Support: detect overhangs" +msgstr "" msgid "Support: generate contact points" -msgstr "Support: generate contact points" +msgstr "" msgid "Support: propagate branches" -msgstr "Support: propagate branches" +msgstr "" msgid "Support: draw polygons" -msgstr "Support: draw polygons" +msgstr "" msgid "Support: generate toolpath" -msgstr "Support: generate toolpath" +msgstr "" #, c-format, boost-format msgid "Support: generate polygons at layer %d" -msgstr "Support: generate polygons at layer %d" +msgstr "" #, c-format, boost-format msgid "Support: fix holes at layer %d" -msgstr "Support: fix holes at layer %d" +msgstr "" #, c-format, boost-format msgid "Support: propagate branches at layer %d" -msgstr "Support: propagate branches at layer %d" +msgstr "" -#~ msgid "Alt + Mouse wheel" -#~ msgstr "Alt + Mouse wheel" +#~ msgid "Save configuration as:" +#~ msgstr "Konfiguráció mentése mint:" + +#~ msgid "Line type" +#~ msgstr "Vonal típusa" + +#~ msgid "Designer" +#~ msgstr "Tervező" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse törlő torony" + +#~ msgid "Device:" +#~ msgstr "Eszköz:" #~ msgid "" -#~ "An object is layed over the boundary of plate.\n" -#~ "Please solve the problem by moving it totally inside or outside plate." +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." #~ msgstr "" -#~ "An object is laid over the edge of the plate or exceeds the height " -#~ "limit.\n" -#~ "Please solve the problem by moving it totally on or off the plate, and " -#~ "confirming that the height is within the build volume." - -#~ msgid "Auto arrange" -#~ msgstr "Auto Arrange" +#~ "Úgy tűnik %s objektumnak támaszra lenne szüksége a nyomtatáshoz. Kérjük, " +#~ "engedélyezd a támasz generálását." #~ msgid "" #~ "Auto orientates selected objects or all objects.If there are selected " @@ -6588,186 +6586,55 @@ msgstr "Support: propagate branches at layer %d" #~ "ellenkező esetben az aktuális projektben lévő összes objektumot " #~ "orientálja." -#~ msgid "Clear all" -#~ msgstr "Clear all" - -#~ msgid "Creating" -#~ msgstr "Creating" - -#~ msgid "Ctrl + Any arrow" -#~ msgstr "Ctrl + Any arrow" - -#~ msgid "Ctrl + Left mouse button" -#~ msgstr "Ctrl + Left mouse button" - -#~ msgid "Debug" -#~ msgstr "Debug" - -#~ msgid "Display printable box" -#~ msgstr "Display printable box" - -#~ msgid "Display shadow of objects" -#~ msgstr "Display shadow of objects" - -#~ msgid "Display triangles of models" -#~ msgstr "Display triangles of models" - -#~ msgid "" -#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" -#~ "Contains the following information:\n" -#~ "1. The Process presets\n" -#~ "2. The Filament presets\n" -#~ "3. The Printer presets\n" -#~ msgstr "" -#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" -#~ "Contains the following information:\n" -#~ "1. Process presets\n" -#~ "2. Filament presets\n" -#~ "3. Printer presets\n" - -#~ msgid "" -#~ "Don't retract when the travel is in infill area absolutely. That means " -#~ "the oozing can't been seen" -#~ msgstr "" -#~ "This disables retraction when travel is entirely within an infill area " -#~ "and oozing can’t be seen." - -#~ msgid "Enter a search term" -#~ msgstr "Enter a search term" - -#~ msgid "Filaments Selection" -#~ msgstr "Filaments selection" - -#~ msgid "Finished" -#~ msgstr "Finished" - -#~ msgid "Fix model locally" -#~ msgstr "Fix model locally" - -#~ msgid "Fix model through cloud" -#~ msgstr "Fix model through cloud" - -#~ msgid "Fragment Filter" -#~ msgstr "Fragment Filter" - -#~ msgid "Fragment area" -#~ msgstr "Fragment area" - -#~ msgid "Fragment filter" -#~ msgstr "Fragment filter" - -#~ msgid "" -#~ "Heat the nozzle to target \n" -#~ "temperature" -#~ msgstr "" -#~ "Heat the nozzle to the target \n" -#~ "temperature" - -#~ msgid "In the calibration of extrusion flow" -#~ msgstr "In the calibration of extrusion flow" - -#~ msgid "In the calibration of laser scanner" -#~ msgstr "In the calibration of laser scanner" - -#~ msgid "Module" -#~ msgstr "Module" - -#~ msgid "Monitoring" -#~ msgstr "Monitoring" - -#~ msgid "Output file" -#~ msgstr "Output file" - -#~ msgid "Pause(heated bed temperature error)" -#~ msgstr "Pause(heated bed temperature error)" - -#~ msgid "Pause(hotend temperature error)" -#~ msgstr "Pause(hotend temperature error)" - -#~ msgid "Pause(toolhead shell off)" -#~ msgstr "Pause(toolhead shell off)" - -#~ msgid "Please fill report first." -#~ msgstr "Please fill report first." - -#~ msgid "Please upgrade your printer first" -#~ msgstr "Please upgrade your printer first" - -#~ msgid "Position:" -#~ msgstr "Position:" - -#~ msgid "" -#~ "Preview only mode:\n" -#~ "The loaded file contains gcode only." -#~ msgstr "" -#~ "Preview only mode:\n" -#~ "The loaded file contains G-code only." - -#~ msgid "Preview only mode for gcode file." -#~ msgstr "Preview only mode for G-code file." - -#~ msgid "Printer Selection" -#~ msgstr "Printer Selection" - -#~ msgid "" -#~ "Push new filament \n" -#~ "into extruder" -#~ msgstr "" -#~ "Push new filament \n" -#~ "into extruder" - -#~ msgid "Sending" -#~ msgstr "Sending" - -#~ msgid "Shift + Any arrow" -#~ msgstr "Shift + Any arrow" - -#~ msgid "Shift + Mouse wheel" -#~ msgstr "Shift + Mouse wheel" - -#~ msgid "Show Model Mesh(TODO)" -#~ msgstr "Show Model Mesh(TODO)" - -#~ msgid "Show Model Shadow(TODO)" -#~ msgstr "Show Model Shadow(TODO)" - -#~ msgid "Show Printable Box(TODO)" -#~ msgstr "Show Printable Box(TODO)" - -#~ msgid "Spiral mode" -#~ msgstr "Spiral/Vase mode" - -#~ msgid "Successfully sent.Will automatically jump to the device page in %s s" -#~ msgstr "" -#~ "Successfully sent. Will automatically jump to the device page in %s s" - -#~ msgid "Swith cloud environment, Please login again!" -#~ msgstr "Switch cloud environment, Please login again!" - -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "The configuration is not compatible and cannot be loaded!" - -#~ msgid "" -#~ "The firmware versions of printer and AMS are too low.Please update to the " -#~ "latest version before sending the print job" -#~ msgstr "" -#~ "The firmware versions of the printer and AMS are too low. Please update " -#~ "them to the latest version before sending any print jobs." - #~ msgid "Timelapse without toolhead" #~ msgstr "Nyomtatófej nélküli timelapse" -#~ msgid "Unable to create zip file" -#~ msgstr "Unable to create zip file" +# d +#~ msgid "Fragment area" +#~ msgstr "Hézag küszöbértéke" -#~ msgid "Uploading" -#~ msgstr "Uploading" +#~ msgid "Clear all" +#~ msgstr "Összes törlése" -#~ msgid "User pause" -#~ msgstr "User pause" +#~ msgid "Downloading Bambu Network plug-in" +#~ msgstr "Bambu hálózati plug-in letöltése" -#~ msgid "Waiting" -#~ msgstr "Waiting" +#~ msgid "Connect %s[SN:%s] failed!" +#~ msgstr "%s[SN:%s]-hez való csatlakozás sikertelen!" -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "The 3mf is not compatible, loading geometry data only!" +#~ msgid "Auto arrange" +#~ msgstr "Automatikus elrendezés" + +#~ msgid "Printer firmware does not support material = >ams slot mapping." +#~ msgstr "" +#~ "A nyomtató firmware nem támogatja a támaszanyagot => AMS helyek kiosztása." + +#~ msgid "Filaments Selection" +#~ msgstr "Filament választás" + +#~ msgid "Printer Selection" +#~ msgstr "Nyomtató kiválasztása" + +#~ msgid "Spiral mode" +#~ msgstr "Spirál mód" + +#~ msgid "Fragment filter" +#~ msgstr "Hézagkitöltés" + +#~ msgid "Fragment Filter" +#~ msgstr "Hézagkitöltés" + +#~ msgid "Position:" +#~ msgstr "Pozíció:" + +#~ msgid "Show Model Mesh(TODO)" +#~ msgstr "Modell háló megjelenítése" + +#~ msgid "Show Model Shadow(TODO)" +#~ msgstr "Modell árnyék megjelenítése" + +#~ msgid "Show Printable Box(TODO)" +#~ msgstr "Nyomtatható terület megjelenítése" + +#~ msgid "Monitoring" +#~ msgstr "Monitorozás" diff --git a/bbl/i18n/list.txt b/bbl/i18n/list.txt index 57ceea33b3..d12dd62447 100644 --- a/bbl/i18n/list.txt +++ b/bbl/i18n/list.txt @@ -12,6 +12,8 @@ src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp src/slic3r/GUI/Gizmos/GLGizmoFaceDetector.cpp src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp src/slic3r/GUI/Gizmos/GLGizmoSeam.hpp +src/slic3r/GUI/Gizmos/GLGizmoText.cpp +src/slic3r/GUI/Gizmos/GLGizmoText.hpp src/slic3r/GUI/GUI.cpp src/slic3r/GUI/GUI_App.cpp src/slic3r/GUI/GUI_Init.cpp @@ -56,6 +58,9 @@ src/slic3r/GUI/ConnectPrinter.cpp src/slic3r/GUI/HMSPanel.cpp src/slic3r/GUI/MainFrame.cpp src/slic3r/GUI/MediaPlayCtrl.cpp +src/slic3r/GUI/MediaFilePanel.cpp +src/slic3r/GUI/ImageGrid.cpp +src/slic3r/GUI/Printer/PrinterFileSystem.cpp src/slic3r/GUI/Mouse3DController.cpp src/slic3r/GUI/StatusPanel.cpp src/slic3r/GUI/Monitor.cpp diff --git a/bbl/i18n/nl/BambuStudio_nl.po b/bbl/i18n/nl/BambuStudio_nl.po index 34359a62ac..7e0d210db2 100644 --- a/bbl/i18n/nl/BambuStudio_nl.po +++ b/bbl/i18n/nl/BambuStudio_nl.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,7 +23,7 @@ msgid "Left mouse button" msgstr "Linker muisknop" msgid "Enforce supports" -msgstr "Support afdwingen" +msgstr "Ondersteuning (support) afdwingen" msgid "Right mouse button" msgstr "Rechter muisknop" @@ -65,7 +65,7 @@ msgid "Smart fill angle" msgstr "Slim vullen hoek" msgid "Auto support threshold angle: " -msgstr "Maximale hoek automatische support: " +msgstr "Hoek voor automatische support: " msgid "Circle" msgstr "Cirkel" @@ -74,7 +74,7 @@ msgid "Sphere" msgstr "Gebied" msgid "Fill" -msgstr "Vullen" +msgstr "Fill" msgid "Gap Fill" msgstr "" @@ -146,7 +146,7 @@ msgid "Triangle" msgstr "Triangle" msgid "Height Range" -msgstr "Hoogtebereik" +msgstr "Height Range" msgid "Remove painted color" msgstr "Getekende kleur verwijderen" @@ -267,7 +267,7 @@ msgid "Mesh name" msgstr "Constructie name" msgid "Detail level" -msgstr "Detailniveau" +msgstr "Detail level" msgid "Decimate ratio" msgstr "Decimeren verhouding" @@ -330,7 +330,7 @@ msgid "Operation already cancelling. Please wait few seconds." msgstr "De toepassing wordt al geannuleerd. Wacht even alstublieft." msgid "Face recognition" -msgstr "Gezichtsherkenning" +msgstr "Face recognition" msgid "Perform Recognition" msgstr "Perform Recognition" @@ -365,6 +365,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Toevoegen" + msgid "Notice" msgstr "Let op" @@ -416,8 +431,8 @@ msgid "" "BambuStudio will terminate because of running out of memory.It may be a bug. " "It will be appreciated if you report the issue to our team." msgstr "" -"Bambu Studio wordt beëindigd omdat het geheugen bijna vol is. Het kan een " -"bug zijn. Meldt dit probleem alstublieft bij support." +"BambuStudio wordt beëindigd omdat het geheugen bijna vol is. Het kan een bug " +"zijn. Meldt dit probleem alstublieft bij support." msgid "Fatal error" msgstr "Fatale fout" @@ -432,7 +447,7 @@ msgstr "Kritische fout" #, boost-format msgid "BambuStudio got an unhandled exception: %1%" -msgstr "Er is een onbekende uitzondering opgetreden in Bambu Studio : %1%" +msgstr "Er is een onbekende uitzondering opgetreden in BambuStudio : %1%" msgid "Downloading Bambu Network Plug-in" msgstr "" @@ -551,11 +566,11 @@ msgid "Select a G-code file:" msgstr "Selecteer een G-code bestand:" msgid "Bambu Studio GUI initialization failed" -msgstr "Initialisatie van Bambu Studio GUI is mislukt" +msgstr "Bambu Studio GUI initialization failed" #, boost-format msgid "Fatal error, exception catched: %1%" -msgstr "Fatale fout, uitzondering: %1%" +msgstr "Fatal error, exception: %1%" msgid "Quality" msgstr "Kwaliteit" @@ -644,9 +659,6 @@ msgstr "Cilinder" msgid "Cone" msgstr "Kegel" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse Wipe Tower" - msgid "Add settings" msgstr "Instellingen toevoegen" @@ -775,7 +787,8 @@ msgstr "Automatisch oriënteren" msgid "Auto orient the object to improve print quality." msgstr "" -"Automatisch oriënteren van het object om de printkwaliteit te verbeteren." +"Stel de orientatie van het object automatisch in om de print kwaliteit de " +"verbeteren." msgid "Split the selected object into mutiple objects" msgstr "Splits het geselecteerde object op in meerdere objecten" @@ -811,7 +824,7 @@ msgid "Remove the selected plate" msgstr "Verwijder het huidige printbed" msgid "Clone" -msgstr "Dupliceren" +msgstr "Kopieren" msgid "Reduce Triangles" msgstr "Aantal driehoeken verkleinen (vereenvoudigen)" @@ -892,7 +905,9 @@ msgstr "" "Klik op het pictogram om de afdruk eigenschap van het object in te schakelen" msgid "Click the icon to edit support painting of the object" -msgstr "Klik op het pictogram om de support van het object te bewerken" +msgstr "" +"Klik op het pictogram om de ondersteuning (support) van het object te " +"bewerken" msgid "Click the icon to edit color painting of the object" msgstr "Klik op het pictogram om de kleur van het object te bewerken" @@ -1074,7 +1089,7 @@ msgid "Purge old filament" msgstr "Purge old filament" msgid "?" -msgstr " ?" +msgstr "?" msgid "Empty" msgstr "Leeg" @@ -1083,7 +1098,7 @@ msgid "Click the pencil icon to edit the filament." msgstr "Klik op het potlood icoon om het filament aan te passen." msgid "Load Filament" -msgstr "Laden" +msgstr "Filament laden" msgid "Unload Filament" msgstr "Unload" @@ -1099,8 +1114,8 @@ msgstr "AMS kalibreren..." msgid "A problem occured during calibration. Click to view the solution." msgstr "" -"Er is een probleem opgetreden tijdens de kalibratie. Klik om de oplossing te " -"bekijken." +"Er is een probleem opgetreden tijdens het kalibreren. Klik hier om tips te " +"krijgen." msgid "Calibrate again" msgstr "Opnieuw kalibreren" @@ -1123,7 +1138,7 @@ msgid "" "We can not do auto-arrange on these objects." msgstr "" "De geselecteerde objecten bevinden zich op een vergrendeld printbed.\n" -"Deze objecten kunnen niet automatisch worden gerangschikt." +"Deze obhjecten kunnen niet automatisch worden gerangschikt." msgid "No arrangable objects are selected." msgstr "Er zijn geen objecten geselecteerd die geschikt kunnen worden." @@ -1136,7 +1151,7 @@ msgstr "" "Het is niet mogelijk om automatisch te rangschikken op dit printbed." msgid "Arranging..." -msgstr "Rangschikken..." +msgstr "Rangschikken" msgid "" "Arrange failed. Found some exceptions when processing object geometries." @@ -1174,7 +1189,7 @@ msgid "" "We can not do auto-orient on these objects." msgstr "" "De geselecteerde objecten bevinden zich op een vergrendeld printbed.\n" -"Deze objecten kunnen niet automatisch worden georiënteerd." +"Deze obhjecten kunnen niet automatisch worden gerangschikt." msgid "" "This plate is locked,\n" @@ -1205,22 +1220,22 @@ msgid "The region parameter is incorrrect" msgstr "The region parameter is incorrrect." msgid "Failure of printer login" -msgstr "Fout bij inloggen op printer" +msgstr "Printer login failure" msgid "Failed to get ticket" -msgstr "Het is niet gelukt om een ticket te verkrijgen" +msgstr "Failed to get ticket" msgid "User authorization timeout" msgstr "User authorization timeout" msgid "Failure of bind" -msgstr "Koppeling mislukt" +msgstr "Binding failure" msgid "Unknown Failure" msgstr "Unknown Failure" msgid "Abnormal print file data. Please slice again" -msgstr "Abnormale printbestand. Slice opnieuw" +msgstr "Abnormal print file data. Please slice again" msgid "Task canceled" msgstr "Task canceled" @@ -1229,7 +1244,7 @@ msgid "Upload task timed out. Please check the network problem and try again" msgstr "Upload task timed out. Please check the network and try again" msgid "Cloud service connection failed. Please try again." -msgstr "Verbinding met cloudservice is mislukt. Probeer het nog eens." +msgstr "Cloud service connection failed. Please try again." msgid "Print file not found, please slice again" msgstr "Print file not found, please slice again" @@ -1242,7 +1257,7 @@ msgstr "" "model and slice again" msgid "Failed uploading print file" -msgstr "Uploaden van het printbestand is mislukt" +msgstr "Failed uploading print file" msgid "Wrong Access code" msgstr "Wrong Access code" @@ -1259,6 +1274,9 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" msgstr "Sending print configuration" @@ -1291,26 +1309,26 @@ msgid "Portions copyright" msgstr "License Info" msgid "Copyright" -msgstr "Auteursrecht" +msgstr "Copyright" msgid "License" msgstr "Licentie" msgid "Bambu Studio is licensed under " -msgstr "Bambu Studio is gelicentieerd onder " +msgstr "Bambu Studio is licensed under " msgid "GNU Affero General Public License, version 3" -msgstr "GNU Affero Algemene Openbare Licentie, versie 3" +msgstr "GNU Affero General Public License, version 3" msgid "" "Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " "by Alessandro Ranellucci and the RepRap community" msgstr "" -"Bambu Studio is gebaseerd op PrusaSlicer van Prusa Research, welke is " -"afgeleid van Slic3r van Alessandro Ranellucci en de RepRap gemeenschap" +"Bambu Studio is based on PrusaSlicer by Prusa Research, which is based on " +"Slic3r by Alessandro Ranellucci and the RepRap community" msgid "Libraries" -msgstr "Bibliotheken" +msgstr "Libraries" msgid "" "This software uses open source components whose copyright and other " @@ -1321,7 +1339,7 @@ msgstr "" #, c-format, boost-format msgid "About %s" -msgstr "Over %s" +msgstr "About %s" msgid "" "Bambu Studio is based on PrusaSlicer by PrusaResearch and SuperSlicer by " @@ -1349,7 +1367,7 @@ msgid "AMSMaterialsSetting" msgstr "" msgid "Colour" -msgstr "Kleur" +msgstr "Color" msgid "" "Nozzle\n" @@ -1384,8 +1402,20 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" -msgstr "Update gegevens bij invoeren" +msgstr "Insertion update" msgid "" "The AMS will automatically read the filament information when inserting a " @@ -1464,7 +1494,7 @@ msgid "Underflow" msgstr "Underflow" msgid "Floating reserved operand" -msgstr "Zwevende gereserveerde operand" +msgstr "Floating reserved operand" msgid "Stack overflow" msgstr "Stack overflow" @@ -1730,16 +1760,16 @@ msgstr "" "Nee - Reset vulling automatisch naar de standaard niet-100% waarde\n" msgid "Auto bed leveling" -msgstr "Automatisch bed levellen" +msgstr "Auto bed leveling" msgid "Heatbed preheating" -msgstr "Printbed opwarmen" +msgstr "Heatbed preheating" msgid "Sweeping XY mech mode" msgstr "Sweeping XY mech mode" msgid "Changing filament" -msgstr "Filament wordt gewisseld" +msgstr "Changing filament" msgid "M400 pause" msgstr "M400 pause" @@ -1748,31 +1778,31 @@ msgid "Paused due to filament runout" msgstr "Paused due to filament runout" msgid "Heating hotend" -msgstr "Hotend opwarmen" +msgstr "Heating hotend" msgid "Calibrating extrusion" -msgstr "Extrusie wordt gecalibreerd" +msgstr "Calibrating extrusion" msgid "Scanning bed surface" msgstr "Scanning bed surface" msgid "Inspecting first layer" -msgstr "De eerste laag wordt geinspecteerd" +msgstr "Inspecting first layer" msgid "Identifying build plate type" -msgstr "Vastellen printbedtype" +msgstr "Identifying build plate type" msgid "Calibrating Micro Lidar" -msgstr "Micro Lidar wordt gecalibreerd" +msgstr "Calibrating Micro Lidar" msgid "Homing toolhead" -msgstr "Printkop naar beginpositie" +msgstr "Homing toolhead" msgid "Cleaning nozzle tip" -msgstr "Nozzle wordt schoongemaakt" +msgstr "Cleaning nozzle tip" msgid "Checking extruder temperature" -msgstr "Extruder temperatuur wordt gecontroleerd" +msgstr "Checking extruder temperature" msgid "Printing was paused by the user" msgstr "Printing was paused by the user" @@ -1781,10 +1811,10 @@ msgid "Pause of front cover falling" msgstr "Pause of front cover falling" msgid "Calibrating the micro lida" -msgstr "Micro Lidar wordt gecalibreerd" +msgstr "Calibrating the micro lidar" msgid "Calibrating extrusion flow" -msgstr "De extrusieflow kalibreren" +msgstr "Calibrating extrusion flow" msgid "Paused due to nozzle temperature malfunction" msgstr "Paused due to nozzle temperature malfunction" @@ -1925,9 +1955,6 @@ msgstr "Tijd" msgid "Display" msgstr "Tonen" -msgid "Line type" -msgstr "Lijn-type" - msgid "Layer Height (mm)" msgstr "Laaghoogte (mm)" @@ -1992,7 +2019,7 @@ msgid "Flushed filament" msgstr "Flushed filament" msgid "Filament change times" -msgstr "Filamentwisseltijden" +msgstr "Filament change times" msgid "Color change" msgstr "Kleur veranderen" @@ -2015,6 +2042,9 @@ msgstr "Schatting totaal" msgid "Normal mode" msgstr "Normale modus" +msgid "Cost" +msgstr "Kosten" + msgid "Prepare time" msgstr "Voorbereidingstijd" @@ -2061,7 +2091,7 @@ msgid "Spacing" msgstr "Uitlijning" msgid "Auto rotate for arrangement" -msgstr "Automatisch roteren voor rankschikking" +msgstr "Automatisch roteren voor indeling" msgid "Allow multiple materials on same plate" msgstr "Sta verschillende materiaalsoorten op hetzelfde printbed toe" @@ -2069,9 +2099,6 @@ msgstr "Sta verschillende materiaalsoorten op hetzelfde printbed toe" msgid "Avoid extrusion calibration region" msgstr "Vermijd het extrusie kalibratie gebied" -msgid "Add" -msgstr "Toevoegen" - msgid "Add plate" msgstr "Printbed toevoegen" @@ -2169,7 +2196,7 @@ msgid "Monitoring Recording" msgstr "Monitoring Recording" msgid "ConnectPrinter(LAN)" -msgstr "Printer aansluiten (LAN)" +msgstr "Connect Printer (LAN)" msgid "Please input the printer access code:" msgstr "Please input the printer access code:" @@ -2184,6 +2211,15 @@ msgstr "" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Enter a search term" + +msgid "Online" +msgstr "Online" + +msgid "Offline" +msgstr "Offline" + msgid "Application is closing" msgstr "De toepassing wordt afgesloten" @@ -2200,11 +2236,14 @@ msgid "Preview" msgstr "Preview" msgid "Device" -msgstr "Apparaat" +msgstr "Device" msgid "Project" msgstr "Project" +msgid "Debug" +msgstr "Debuggen" + msgid "Slice" msgstr "Slice" @@ -2242,6 +2281,12 @@ msgstr "Zoeken naar updates" msgid "&About %s" msgstr "&Over %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Standaard weergave" @@ -2313,9 +2358,24 @@ msgstr "Importeer 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Laad een model" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "Exporteer alle objecten als STL" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Exporteer het huidig \"sliced\" bestand" @@ -2325,6 +2385,12 @@ msgstr "Exporteer G-code" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exporteren" @@ -2365,10 +2431,10 @@ msgid "Deletes all objects" msgstr "Verwijder alle objecten" msgid "Clone selected" -msgstr "Duplicaat geselecteerd" +msgstr "Kopie geselecteerd" msgid "Clone copies of selections" -msgstr "Duplicaten van selecties maken" +msgstr "Kopieën van selecties maken" msgid "Select all" msgstr "Alles selecteren" @@ -2391,27 +2457,12 @@ msgstr "Orthogonale weergave gebruiken" msgid "Preferences" msgstr "Voorkeuren" -msgid "About" -msgstr "" - msgid "View" msgstr "Weergave" msgid "Help" msgstr "Help" -msgid "&File" -msgstr "&Bestand" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&Bekijken" - -msgid "&Help" -msgstr "&Help" - msgid "&Open G-code" msgstr "&Open G-code" @@ -2425,10 +2476,10 @@ msgid "Reload the plater from disk" msgstr "Reload the plater from disk" msgid "Export &Toolpaths as OBJ" -msgstr "Exporteer &Toolpaths als OBJ" +msgstr "Export &Toolpaths as OBJ" msgid "Export toolpaths as OBJ" -msgstr "Toolpaths exporteren als OBJ" +msgstr "Export toolpaths as OBJ" msgid "Open &PrusaSlicer" msgstr "Open &PrusaSlicer" @@ -2437,14 +2488,54 @@ msgid "Open PrusaSlicer" msgstr "Open PrusaSlicer" msgid "&Quit" -msgstr "&Afsluiten" +msgstr "&Quit" #, c-format, boost-format msgid "Quit %s" msgstr "Quit %s" -msgid "Save configuration as:" -msgstr "Bewaar configuratie als:" +msgid "&File" +msgstr "&File" + +msgid "&View" +msgstr "&View" + +msgid "&Help" +msgstr "&Help" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Bestand ontbreekt" @@ -2489,53 +2580,99 @@ msgstr "Afspelen..." msgid "Load failed [%d]!" msgstr "Laden mislukt [%d]!" -msgid "3Dconnexion settings" -msgstr "3Dconnexion instellingen" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Apparaat:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Download" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Waiting" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Finished" msgid "Speed:" msgstr "Snelheid" -msgid "Translation" -msgstr "Vertaling" - -msgid "Zoom" -msgstr "Inzoomen" - msgid "Deadzone:" msgstr "Deadzone:" msgid "Options:" msgstr "Opties:" +msgid "Zoom" +msgstr "Inzoomen" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion instellingen" + msgid "Swap Y/Z axes" msgstr "Wissel Y/Z assen om" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Print voortgang" -msgid "Report" -msgstr "Rapport" +msgid "Resume" +msgstr "Hervatten" msgid "Stop" msgstr "Stop" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" msgid "Control" -msgstr "Besturing" +msgstr "Control" msgid "Print Options" msgstr "" @@ -2567,9 +2704,6 @@ msgstr "Print lijst" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Hervatten" - msgid "Silent" msgstr "Stille" @@ -2600,9 +2734,6 @@ msgstr "Verbinding maken met de server is mislukt" msgid "Failed to connect to the printer" msgstr "Verbinding maken met de printer is mislukt" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "Offline" @@ -2636,9 +2767,6 @@ msgstr "%s info" msgid "%s information" msgstr "%s informatie" -msgid "Download" -msgstr "Downloaden" - msgid "Skip" msgstr "Overslaan" @@ -2740,7 +2868,7 @@ msgid "Support painting" msgstr "Ondersteuning (support) intekenen" msgid "Color painting" -msgstr "Kleur aanbrengen" +msgstr "Kleur schilderen" msgid "Layers" msgstr "Lagen" @@ -2843,9 +2971,6 @@ msgstr "Verbruikt filament (g)" msgid "Used Materials" msgstr "Verbruikte materialen" -msgid "Cost" -msgstr "Kosten" - msgid "Estimated time" msgstr "Geschatte tijd" @@ -2905,6 +3030,12 @@ msgstr "U dient de software te upgraden.\n" msgid "Newer 3mf version" msgstr "Nieuwere versie 3mf" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -3027,7 +3158,7 @@ msgid "Error occurs while loading G-code file" msgstr "Er is een fout opgetreden tijdens het laden van het G-codebestand." msgid "Drop project file" -msgstr "Projectbestand neerzetten" +msgstr "Drop project file" msgid "Please select an action" msgstr "Selecteer een actie" @@ -3048,10 +3179,10 @@ msgid "G-code files can not be loaded with models together!" msgstr "G-Code bestanden en modellen kunnen niet tegelijk geladen worden!" msgid "Can not add models when in preview mode!" -msgstr "Modellen kunnen niet worden toegevoegd in voorbeeldmodus" +msgstr "Unable to add models in preview mode" msgid "Add Models" -msgstr "Modellen toevoegen" +msgstr "Add Models" msgid "All objects will be removed, continue?" msgstr "Alle objecten zullen verwijderd worden, doorgaan?" @@ -3092,7 +3223,8 @@ msgstr "Stuur naar printer" msgid "Custom supports and color painting were removed before repairing." msgstr "" -"Handmatig aangebrachte support en kleuren zijn verwijderd voor het repareren." +"Handmatig ingetekende ondersteuning (support) en kleuren zijn verwijdererd " +"voor het repareren." msgid "Invalid number" msgstr "Ongeldig nummer" @@ -3144,7 +3276,7 @@ msgid "Changing application language" msgstr "Taal van de applicatie wijzigen" msgid "Changing the region will log out your account.\n" -msgstr "Als u de regio wijzigt, wordt u afgemeld bij uw account.\n" +msgstr "Changing the region will log you out of your account.\n" msgid "Region selection" msgstr "Region selection" @@ -3153,16 +3285,16 @@ msgid "Second" msgstr "Seconde" msgid "General Settings" -msgstr "Algemene instellingen" +msgstr "General Settings" msgid "Asia-Pacific" -msgstr "Azië-Pacific" +msgstr "Asia-Pacific" msgid "China" msgstr "China" msgid "Europe" -msgstr "Europa" +msgstr "Europe" msgid "North America" msgstr "North America" @@ -3186,18 +3318,16 @@ msgid "User sync" msgstr "Gebruikerssynchronisatie" msgid "Auto sync user presets(Printer/Filament/Process)" -msgstr "" -"Gebruikersvoorinstellingen automatisch synchroniseren (printer/filament/" -"proces)" +msgstr "Auto sync user presets (Printer/Filament/Process)" msgid "User Sync" msgstr "User Sync" msgid "Associate files to BambuStudio" -msgstr "Koppel bestanden aan Bambu Studio" +msgstr "Koppel bestanden aan BambuStudio" msgid "Associate .3mf files to BambuStudio" -msgstr "Koppel .3mf-bestanden aan Bambu Studio" +msgstr "Koppel .3mf-bestanden aan BambuStudio" msgid "If enabled, sets BambuStudio as default application to open .3mf files" msgstr "" @@ -3205,7 +3335,7 @@ msgstr "" "om .3mf-bestanden te openen" msgid "Associate .stl files to BambuStudio" -msgstr "Koppel .stl-bestanden aan Bambu Studio" +msgstr "Koppel .stl-bestanden aan BambuStudio" msgid "If enabled, sets BambuStudio as default application to open .stl files" msgstr "" @@ -3213,7 +3343,7 @@ msgstr "" "om .stl-bestanden te openen" msgid "Associate .step/.stp files to BambuStudio" -msgstr "Koppel .step/.stp bestanden aan Bambu Studio" +msgstr "Associate .step/.stp files to Bambu Studio" msgid "If enabled, sets BambuStudio as default application to open .step files" msgstr "" @@ -3227,7 +3357,7 @@ msgid "Auto-Backup" msgstr "Automatisch backup maken" msgid "Backup interval" -msgstr "Backupinterval" +msgstr "Backup interval" msgid "Home page and daily tips" msgstr "Startpagina en dagelijkse tips" @@ -3266,7 +3396,7 @@ msgid "Develop mode" msgstr "Ontwikkelmodus" msgid "Dump video" -msgstr "Video verwijderen" +msgstr "Dump video" msgid "Log Level" msgstr "Log level" @@ -3290,10 +3420,10 @@ msgid "trace" msgstr "Traceren" msgid "Host Setting" -msgstr "Host-instelling" +msgstr "Host Setting" msgid "DEV host: api-dev.bambu-lab.com/v1" -msgstr "DEV-host: api-dev.bambu-lab.com/v1" +msgstr "DEV host: api-dev.bambu-lab.com/v1" msgid "QA host: api-qa.bambu-lab.com/v1" msgstr "QA host: api-qa.bambu-lab.com/v1" @@ -3326,7 +3456,7 @@ msgid "Incompatible presets" msgstr "Onbruikbare voorinstellingen" msgid "AMS filaments" -msgstr "AMS-filament" +msgstr "AMS-filamenten" msgid "Click to pick filament color" msgstr "Klik om de filament kleur te kiezen" @@ -3453,12 +3583,6 @@ msgstr "" msgid "Simply switch to \"%1%\"" msgstr "Schakel eenvoudig over naar \"%1%\"" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - msgid "My Device" msgstr "Mijn apparaat" @@ -3466,13 +3590,13 @@ msgid "Other Device" msgstr "Ander apparaat" msgid "Input access code" -msgstr "Toegangscode invoeren" +msgstr "Input access code" msgid "Log out successful." msgstr "Uitloggen gelukt." msgid "Busy" -msgstr "Bezet" +msgstr "Busy" msgid "Bambu Cool Plate" msgstr "Bambu Cool (koude) Plate" @@ -3505,7 +3629,7 @@ msgid "No login account, only printers in LAN mode are displayed" msgstr "No login account, only printers in LAN mode are displayed" msgid "Connecting to server" -msgstr "Verbinding maken met server" +msgstr "Connecting to server" msgid "Synchronizing device information" msgstr "Synchronizing device information" @@ -3514,7 +3638,7 @@ msgid "Synchronizing device information time out" msgstr "Synchronizing device information time out" msgid "Cannot send the print task when the upgrade is in progress" -msgstr "Kan de printtaak niet verzenden wanneer de upgrade wordt uitgevoerd" +msgstr "Cannot send the print task when the upgrade is in progress" msgid "" "The printer is executing instructions. Please restart printing after it ends" @@ -3539,8 +3663,8 @@ msgid "" "Filaments to AMS slots mappings have been established. You can click a " "filament above to change its mapping AMS slot" msgstr "" -"De toewijzingen van filamenten aan AMS-slots zijn vastgesteld. U kunt op een " -"filament hierboven klikken om de toewijzing van het AMS slot te wijzigen" +"Filaments to AMS slots mappings have been established. You can click a " +"filament above to change its mapping AMS slot" msgid "" "Please click each filament above to specify its mapping AMS slot before " @@ -3605,6 +3729,15 @@ msgstr "Bewaar huidige %s" msgid "Delete this preset" msgstr "Verwijder deze voorinstelling" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3659,7 +3792,7 @@ msgid "Prime tower" msgstr "Prime toren" msgid "Flush options" -msgstr "Flush-opties" +msgstr "Flush options" msgid "Special mode" msgstr "Speciale modus" @@ -3668,7 +3801,7 @@ msgid "G-code output" msgstr "" msgid "Frequent" -msgstr "Veelgebruikt" +msgstr "Frequent" #, c-format, boost-format msgid "" @@ -3727,8 +3860,8 @@ msgid "" "Bed temperature when cool plate is installed. Value 0 means the filament " "does not support to print on the Cool Plate" msgstr "" -"Dit is de bedtemperatuur wanneer de koelplaat is geïnstalleerd. Een waarde " -"van 0 betekent dat het filament printen op de Cool Plate niet ondersteunt." +"This is the bed temperature when the cool plate is installed. A value of 0 " +"means the filament does not support printing on the Cool Plate." msgid "Engineering plate" msgstr "Engineering plate (technisch printbed)" @@ -3737,9 +3870,8 @@ msgid "" "Bed temperature when engineering plate is installed. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Dit is de bedtemperatuur wanneer de technische plaat is geïnstalleerd. Een " -"waarde van 0 betekent dat het filament afdrukken op de Engineering Plate " -"niet ondersteunt." +"This is the bed temperature when the engineering plate is installed. A value " +"of 0 means the filament does not support printing on the Engineering Plate." msgid "High Temp Plate" msgstr "High Temp Plate (hoge temperatuur printbed)" @@ -3748,9 +3880,17 @@ msgid "" "Bed temperature when high temperature plate is installed. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Dit is de bedtemperatuur wanneer de hogetemperatuurplaat is geïnstalleerd. " -"Een waarde van 0 betekent dat het filament printen op de High Temp Plate " -"niet ondersteunt." +"This is the bed temperature when the high temperature plate is installed. A " +"value of 0 means the filament does not support printing on the High Temp " +"Plate." + +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Volumetric speed limitation" msgstr "Volumetrische snelheidsbeperking" @@ -3975,7 +4115,7 @@ msgstr "" "voorinstelling?" msgid "Extruders count" -msgstr "Extruder aantal" +msgstr "Extruder count" msgid "General" msgstr "Algemeen" @@ -3983,6 +4123,12 @@ msgstr "Algemeen" msgid "Capabilities" msgstr "Mogelijkheden" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Instellen als dekking" @@ -3994,7 +4140,7 @@ msgid "The name \"%1%\" already exists." msgstr "De naam \"%1%\" bestaat reeds." msgid "Basic Info" -msgstr "Basisinfo" +msgstr "Basic Info" msgid "Pictures" msgstr "Afbeeldingen" @@ -4008,15 +4154,15 @@ msgstr "Montagehandleiding" msgid "Choose files" msgstr "Kies bestanden" -msgid "Designer" -msgstr "Ontwerper" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Model naam" #, c-format, boost-format msgid "%s Update" -msgstr "%s Bijwerken" +msgstr "%s Update" msgid "A new version is available" msgstr "Er is een nieuwe versie beschikbaar" @@ -4065,7 +4211,7 @@ msgid "The configuration is up to date." msgstr "De configuratie is up to date." msgid "Auto-Calc" -msgstr "Automatisch berekenen" +msgstr "Auto-Calc" msgid "Flushing volumes for filament change" msgstr "Volumes reinigen voor filament wijziging" @@ -4074,7 +4220,7 @@ msgid "Flushing volume (mm³) for each filament pair." msgstr "Spoelvolume (mm³) voor elk filamentpaar." msgid "Flush multiplier" -msgstr "Flush-vermenigvuldiger" +msgstr "Flush multiplier" msgid "unloaded" msgstr "uitgeladen" @@ -4115,6 +4261,9 @@ msgstr "Kopieer naar klembord" msgid "Paste from clipboard" msgstr "Plakken vanuit klembord" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Toon lijst met sneltoetsen" @@ -4126,9 +4275,9 @@ msgid "" "objects, it just orientates the selected ones.Otherwise, it will orientates " "all objects in the current disk." msgstr "" -"Automatisch geselecteerde en georiënteerde objecten, of alle objecten.\n" -"Indien er objecten geselecteerd en georiënteerd zijn worden alleen deze " -"georiënteerd. Anders worden alle objecten op de huidige volume georiënteerd." +"Automatisch oriënteren. Als er geselecteerde objecten zijn worden alleen " +"deze georiënteert. Anders worden alle objecten op de huidige schijf " +"georiënteert." msgid "Collapse/Expand the sidebar" msgstr "De menubalk in-/uitschuiven" @@ -4256,6 +4405,9 @@ msgstr "⌘+muiswiel" msgid "Support/Color Painting: adjust pen radius" msgstr "Ondersteuning(support)/kleur intekenen: pas de pen diameter aan" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Ondersteuning(support)/kleur intekenen: pas de sectie positie aan" @@ -4299,10 +4451,10 @@ msgid "Vertical slider - Move active thumb Down" msgstr "Verticale schuifregelaar - Actieve thumb omlaag bewegen" msgid "Horizontal slider - Move active thumb Left" -msgstr "Horizontale schuifbalk - Beweeg actieve duim naar links" +msgstr "Horizontal slider - Move active thumb Left" msgid "Horizontal slider - Move active thumb Right" -msgstr "Horizontale schuifbalk - Beweeg actieve duim naar rechts" +msgstr "Horizontal slider - Move active thumb Right" msgid "On/Off one layer mode of the vertical slider" msgstr "On/Off one layer mode of the vertical slider" @@ -4579,16 +4731,16 @@ msgid "" "%1% is too close to exclusion area, there will be collisions when printing." msgstr "" "\n" -"%1% bevindt zich te dicht bij een uitgesloten gebied, er kunnen botsingen " +"%1% bevindt zich te dicht bij een uitgesloten gebied, er zullen botsingen " "optreden tijdens het printen." #, boost-format msgid "%1% is too close to others, and collisions may be caused." -msgstr "%1% staat te dicht bij anderen en er kunnen botsingen ontstaan." +msgstr "%1% is too close to others, and collisions may be caused." #, boost-format msgid "%1% is too tall, and collisions will be caused." -msgstr "%1% is te hoog en er kunnen botsingen ontstaan." +msgstr "%1% is too tall, and collisions will be caused." msgid " is too close to others, there will be collisions when printing.\n" msgstr "" @@ -4770,8 +4922,8 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Cool Plate" msgstr "" -"Dit is de bedtemperatuur voor alle lagen behalve de eerste. Een waarde van 0 " -"betekent dat het filament het afdrukken op de Cool Plate niet ondersteunt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Cool Plate." msgid "°C" msgstr "°C" @@ -4783,16 +4935,20 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Dit is de bedtemperatuur voor lagen, behalve voor de eerste. Een waarde van " -"0 betekent dat het filament afdrukken op de Engineering Plate niet " -"ondersteunt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Engineering Plate." msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Dit is de bedtemperatuur voor lagen, behalve voor de eerste. Een waarde van " -"0 betekent dat het filament printen op de High Temp Plate niet ondersteunt." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Initial layer" msgstr "Eerste laag" @@ -4804,22 +4960,27 @@ msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Cool Plate" msgstr "" -"Dit is de bedtemperatuur van de beginlaag. Een waarde van 0 betekent dat het " -"filament printen op de Cool Plate niet ondersteunt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Cool Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Engineering Plate" msgstr "" -"Dit is de bedtemperatuur van de beginlaag. Een waarde van 0 betekent dat het " -"filament afdrukken op de Engineering Plate niet ondersteunt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Engineering Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the High Temp Plate" msgstr "" -"Dit is de bedtemperatuur van de beginlaag. Een waarde van 0 betekent dat het " -"filament printen op de High Temp Plate niet ondersteunt." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" msgid "Bed types supported by the printer" msgstr "Printbedden ondersteund door de printer" @@ -4897,7 +5058,7 @@ msgstr "" "onderdeel deze waarde overschrijdt. Uitgedrukt als percentage " msgid "Bridge flow" -msgstr "Brugflow" +msgstr "Bridge flow" msgid "" "Decrease this value slightly(for example 0.9) to reduce the amount of " @@ -4955,8 +5116,9 @@ msgid "" "A gap between innermost brim line and object can make brim be removed more " "easily" msgstr "" -"Dit creëert ruimte tussen de binnenste brimlijn en het object en zorgt " -"ervoor dat het object eenvoudiger van het printbed kan worden verwijderd." +"Dit zorgt ervoor dat er een ruimte wordt vrijgelaten tussen de binnenste " +"randlijn en het object en zorgt ervoor dat het object eenvoudiger van het " +"printbed kan worden verwijderd" msgid "Compatible machine" msgstr "Geschikte machine" @@ -5039,15 +5201,15 @@ msgid "layers" msgstr "Lagen" msgid "Don't support bridges" -msgstr "Geen support bij bruggen toepassen" +msgstr "Geen brug ondersteuning toepassen" msgid "" "Don't support the whole bridge area which make support very large. Bridge " "usually can be printing directly without support if not very long" msgstr "" -"Dit schakelt de ondersteuning (support) voor bruggebieden uit, waardoor de " -"ondersteuning (support) erg groot kan worden. Bruggen kunnen meestal direct " -"zonder ondersteuning (support) worden afgedrukt als ze niet erg lang zijn." +"This disables supporting bridges, which decreasing the mount of support " +"required. Bridges can usually be printed directly without support for a " +"reasonable distance." msgid "Thick bridges" msgstr "" @@ -5174,7 +5336,7 @@ msgid "Extruder offset" msgstr "Extruder offset" msgid "Flow ratio" -msgstr "Flow verhouding" +msgstr "Flow ratio" msgid "" "The material may have volumetric change after switching between molten state " @@ -5372,8 +5534,8 @@ msgid "" "Acceleration of top surface infill. Using a lower value may improve top " "surface quality" msgstr "" -"Versnelling van de topoppervlakte-invulling. Gebruik van een lagere waarde " -"kan de kwaliteit van de bovenlaag verbeteren." +"Acceleration of top surface infill. Using a lower value may improve top " +"surface quality" msgid "" "Acceleration of initial layer. Using a lower value can improve build plate " @@ -5847,7 +6009,8 @@ msgid "Initial layer density" msgstr "Dichtheid van de eerste laag" msgid "Density of the first raft or support layer" -msgstr "Dit is de dichtheid van de eerste raft- of support laag." +msgstr "" +"Dit is de dichtheid van de eerste raft- of ondersteuning (support) laag." msgid "Initial layer expansion" msgstr "Vergroten van de eerste laag" @@ -5964,7 +6127,10 @@ msgid "Aligned" msgstr "Uitgelijnd" msgid "Back" -msgstr "Achterzijde" +msgstr "Terug" + +msgid "Random" +msgstr "" msgid "Skirt distance" msgstr "Rand (skirt) afstand" @@ -6022,15 +6188,13 @@ msgstr "" "met solide onderlagen. Het uiteindelijke gegenereerde model heeft geen naad." msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Record timelapse video of printing without showing the toolhead. In this " -"mode the toolhead docks near the excess chute at each layer change, and then " -"a snapshot is taken with the chamber camera. When printing finishes, a " -"timelapse video is created from all the snapshots." msgid "Temperature variation" msgstr "Temperatuur variatie" @@ -6045,10 +6209,10 @@ msgid "Start G-code when start the printing of this filament" msgstr "Start G-code wanneer het printen van dit filament begint" msgid "Enable support" -msgstr "Support inschakelen" +msgstr "Ondertsteuning (support) inschakelen" msgid "Enable support generation." -msgstr "Dit maakt het genereren van support mogelijk." +msgstr "Ondersteuning (support) genereren inschakelen." msgid "" "normal(auto) and tree(auto) is used to generate support automatically. If " @@ -6092,7 +6256,9 @@ msgid "On build plate only" msgstr "Alleen op het printbed" msgid "Don't create support on model surface, only on build plate" -msgstr "Deze instelling genereert alleen support die begint op het printbed." +msgstr "" +"Deze instelling genereert alleen ondersteuning (support) die begint op het " +"printbed" msgid "Top Z distance" msgstr "Top Z afstand" @@ -6106,11 +6272,12 @@ msgid "" "Filament to print support and skirt. 0 means no specific filament for " "support and current filament is used" msgstr "" -"Filament om randen (skirt) en support te printen. Indien u kiest voor 0 dan " -"is er geen specifiek filament en wordt het huidige filament gebruikt" +"Filament om randen (skirt) en ondersteuning (support) te printen. Indien u " +"kiest voor 0 dan is er geen specifiek filament en wordt het huidige filament " +"gebruikt" msgid "Line width of support" -msgstr "Lijn dikte van support" +msgstr "Lijn dikte van ondersteuning (support)" msgid "Interface use loop pattern" msgstr "Luspatroon interface" @@ -6118,15 +6285,15 @@ msgstr "Luspatroon interface" msgid "" "Cover the top contact layer of the supports with loops. Disabled by default." msgstr "" -"Dit bedekt de bovenste laag van de support met lussen. Het is standaard " -"uitgeschakeld." +"This covers the top contact layer of the supports with loops. It is disabled " +"by default." msgid "" "Filament to print support interface. 0 means no specific filament for " "support interface and current filament is used" msgstr "" -"Filament om support te printen. Indien u kiest voor 0 dan is er geen " -"specifiek filament en wordt het huidige filament gebruikt" +"Filament om ondersteuning (support) te printen. Indien u kiest voor 0 dan " +"is er geen specifiek filament en wordt het huidige filament gebruikt" msgid "Top interface layers" msgstr "Bovenste interface lagen" @@ -6160,7 +6327,7 @@ msgid "Base pattern" msgstr "Basis patroon" msgid "Line pattern of support" -msgstr "Dit is het lijnpatroon voor support." +msgstr "Dit is het lijnpatroon voor ondersteuning(support)" msgid "Rectilinear" msgstr "Rechtlijning" @@ -6176,9 +6343,10 @@ msgid "" "interface is Rectilinear, while default pattern for soluble support " "interface is Concentric" msgstr "" -"Dit is het lijnpatroon voor support interfaces. Het standaardpatroon voor " -"niet-oplosbare support interfaces is Rechtlijnig, terwijl het " -"standaardpatroon voor oplosbare support interfaces Concentrisch is." +"Dit is het lijnpatroon voor de ondersteuningsinterface (support). Het " +"standaardpatroon voor niet-oplosbare ondersteuningsinterface is rechtlijnig, " +"terwijl het standaardpatroon voor oplosbare ondersteuningsinterface " +"concentrisch is." msgid "Base pattern spacing" msgstr "Basis patroon afstand" @@ -6196,17 +6364,12 @@ msgid "Snug" msgstr "Nauwsluitend" msgid "Independent support layer height" -msgstr "Onafhankelijke support laaghoogte" +msgstr "Onafhankelijke support (ondersteuning) laaghoogte" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"De ondersteuningslaag (support layer) gebruikt een laaghoogte onafhankelijk " -"van objectlagen. Dit is ter ondersteuning van aangepaste " -"ondersteuningsgaten, maar kan extra filamentwisselingen veroorzaken indien " -"ondersteuning is gespecificeerd als een ander filament dan het object." msgid "Threshold angle" msgstr "Drempel hoek" @@ -6279,10 +6442,9 @@ msgid "" "layer for more than this threshold. Too low bed temperature of other layer " "may cause the model broken free from build plate" msgstr "" -"Een verschil in bedtemperatuur groter dan deze marge en lager dan de " -"bedtemperatuur van de eerste eerste laag, wordt niet geadviseerd. Een te " -"lage bedtemperatuur van de overige lagen kan ertoe leiden dat het model " -"loskomt van het printbed." +"Het is wordt niet geadviseerd dat de printbed temperatuur van een laag lager " +"is dan de eerste laag voor meer dan deze drempel. Een te lage bedtemperatuur " +"van een andere laag kan ertoe leiden dat het model losraakt van de bouwplaat" msgid "Detect thin wall" msgstr "Detecteer dunne wanden" @@ -6388,7 +6550,7 @@ msgid "Width of prime tower" msgstr "Dit is de breedte van de prime toren." msgid "Flush into objects' infill" -msgstr "Flush in de opvulling van objecten" +msgstr "Flush into objects' infill" msgid "" "Purging after filament change will be done inside objects' infills. This may " @@ -6401,7 +6563,7 @@ msgstr "" "printed with transparent filament, the mixed color infill will be visible." msgid "Flush into objects' support" -msgstr "Flush in de support van objecten" +msgstr "Flush into objects' support" msgid "" "Purging after filament change will be done inside objects' support. This may " @@ -6411,7 +6573,7 @@ msgstr "" "lower the amount of waste and decrease the print time." msgid "Flush into this object" -msgstr "Flush in dit object" +msgstr "Flush into this object" msgid "" "This object will be used to purge the nozzle after a filament change to save " @@ -6493,10 +6655,10 @@ msgid "Arrange options: 0-disable, 1-enable, others-auto" msgstr "Rangschik opties: 0-uitzetten, 1-aanzetten, anders-automatisch" msgid "Convert Unit" -msgstr "Eenheid converteren" +msgstr "Convert Unit" msgid "Convert the units of model" -msgstr "Converteer de eenheden van het model" +msgstr "Convert the units of model" msgid "Orient the model" msgstr "Oriënteer het model" @@ -6551,17 +6713,21 @@ msgid "Generating infill toolpath" msgstr "Infill toolpath genereren" msgid "Generating support" -msgstr "Support genereren" +msgstr "Ondersteuning (support) genereren" msgid "Checking support necessity" -msgstr "Controleren of support is noodzakelijk" +msgstr "Controleren of er behoefte is aan ondersteuning" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Het lijkt er op dat object %s support nodig heeft om te printen. Zet support " -"genereren aan indien nodig." msgid "Optimizing toolpath" msgstr "Optimaliseren van het pad" @@ -6571,14 +6737,8 @@ msgstr "" "Lege lagen in de buurt van de bodem worden vervangen door de dichtsbijzijnde " "normale lagen." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"Het model heeft overlappende of elkaar kruisende facetten. De software heeft " -"geprobeerd om het te repareren, maar misschien wilt u de resultaten " -"controleren of het invoerbestand repareren en het opnieuw proberen." msgid "Slicing mesh" msgstr "Slicing mesh" @@ -6621,6 +6781,90 @@ msgstr "Support: fix holes at layer %d" msgid "Support: propagate branches at layer %d" msgstr "Support: propagate branches at layer %d" +#~ msgid "the 3mf is not compatible, load geometry data only!" +#~ msgstr "" +#~ "Het 3mf bestand is niet compatibel, enkel de geometrische data wordt " +#~ "geladen!" + +#~ msgid "Save configuration as:" +#~ msgstr "Bewaar configuratie als:" + +#~ msgid "Line type" +#~ msgstr "Lijn-type" + +#~ msgid "Designer" +#~ msgstr "Ontwerper" + +#~ msgid "Report" +#~ msgstr "Rapport" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Apparaat:" + +#~ msgid "Translation" +#~ msgstr "Vertaling" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "" +#~ "Het lijkt er op dat object %s ondersteuning (support) nodig heeft om te " +#~ "printen. Zet ondersteuning (support) genereren aan indien nodig." + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "Het model heeft overlappende of elkaar kruisende facetten. De software " +#~ "heeft geprobeerd om het te repareren, maar misschien wilt u de resultaten " +#~ "controleren of het invoerbestand repareren en het opnieuw proberen." + +#~ msgid "" +#~ "Auto orientates selected objects or all objects.If there are selected " +#~ "objects, it just orientates the selected ones.Otherwise, it will " +#~ "orientates all objects in the project." +#~ msgstr "" +#~ "Automatisch oriënteren. Als er geselecteerde objecten zijn worden alleen " +#~ "deze georiënteert. Anders worden alle objecten op de huidige project " +#~ "georiënteert." + +#~ msgid "The Config is not compatible and can not be loaded." +#~ msgstr "De configuratie is niet compatibel en kan niet geladen worden!" + +#~ msgid "Creating" +#~ msgstr "Creating" + +#~ msgid "Uploading" +#~ msgstr "Uploading" + +#~ msgid "Sending" +#~ msgstr "Sending" + +#~ msgid "Please fill report first." +#~ msgstr "Gelieve eerst het rapport in te vullen." + +#~ msgid "Unable to create zip file" +#~ msgstr "Unable to create zip file" + +#~ msgid "Filaments Selection" +#~ msgstr "Filaments selectie" + +#~ msgid "Printer Selection" +#~ msgstr "Printer selectie" + +#~ msgid "Auto arrange" +#~ msgstr "Automatisch rangschikken" + +#~ msgid "Spiral mode" +#~ msgstr "Spiraal modus" + #~ msgid "Alt + Mouse wheel" #~ msgstr "Alt + muiswiel" @@ -6632,32 +6876,14 @@ msgstr "Support: propagate branches at layer %d" #~ "Los dit probleem op door het object geheel binnen of buiten de printplaat " #~ "te plaatsen." -#~ msgid "Auto arrange" -#~ msgstr "Automatisch rangschikken" - -#~ msgid "" -#~ "Auto orientates selected objects or all objects.If there are selected " -#~ "objects, it just orientates the selected ones.Otherwise, it will " -#~ "orientates all objects in the project." -#~ msgstr "" -#~ "Automatisch oriënteren. Als er geselecteerde objecten zijn worden alleen " -#~ "deze georiënteert. Anders worden alle objecten op de huidige project " -#~ "georiënteert." - #~ msgid "Clear all" #~ msgstr "Alles wissen" -#~ msgid "Creating" -#~ msgstr "Bezig met creëren" - #~ msgid "Ctrl + Any arrow" #~ msgstr "CTRL + willekeurige pijl" #~ msgid "Ctrl + Left mouse button" -#~ msgstr "Ctrl + Linkermuisknop" - -#~ msgid "Debug" -#~ msgstr "Debuggen" +#~ msgstr "Ctrl + Left mouse button" #~ msgid "Display printable box" #~ msgstr "Toon printbare box" @@ -6675,11 +6901,11 @@ msgstr "Support: propagate branches at layer %d" #~ "2. The Filament presets\n" #~ "3. The Printer presets\n" #~ msgstr "" -#~ "Wilt u uw persoonlijke gegevens van Bambu Cloud synchroniseren? \n" -#~ "Dit bevat de volgende informatie:\n" -#~ "1. Voorinstellingen voor processen\n" -#~ "2. Voorinstellingen voor filament\n" -#~ "3. Voorinstellingen voor printers\n" +#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" +#~ "Contains the following information:\n" +#~ "1. Process presets\n" +#~ "2. Filament presets\n" +#~ "3. Printer presets\n" #~ msgid "" #~ "Don't retract when the travel is in infill area absolutely. That means " @@ -6688,15 +6914,6 @@ msgstr "Support: propagate branches at layer %d" #~ "Dit schakelt terugtrekken (retraction) uit wanneer reizen volledig binnen " #~ "een opvulgebied is en het druppelen uit de nozzle niet kan worden gezien." -#~ msgid "Enter a search term" -#~ msgstr "Voer een zoekterm in" - -#~ msgid "Filaments Selection" -#~ msgstr "Filaments selectie" - -#~ msgid "Finished" -#~ msgstr "Voltooid" - #~ msgid "Fix model locally" #~ msgstr "Repareer model lokaal" @@ -6704,13 +6921,13 @@ msgstr "Support: propagate branches at layer %d" #~ msgstr "Repareer model in de cloud" #~ msgid "Fragment Filter" -#~ msgstr "Fragmentfilter" +#~ msgstr "Fragment Filter" #~ msgid "Fragment area" -#~ msgstr "Fragmentgebied" +#~ msgstr "Fragment area" #~ msgid "Fragment filter" -#~ msgstr "Fragmentfilter" +#~ msgstr "Fragment filter" #~ msgid "" #~ "Heat the nozzle to target \n" @@ -6718,10 +6935,10 @@ msgstr "Support: propagate branches at layer %d" #~ msgstr "Nozzle opwarmen tot doel temperatuur" #~ msgid "In the calibration of extrusion flow" -#~ msgstr "Bij de kalibratie van de extrusieflow" +#~ msgstr "In the calibration of extrusion flow" #~ msgid "In the calibration of laser scanner" -#~ msgstr "Bij de kalibratie van laserscanner" +#~ msgstr "In the calibration of laser scanner" #~ msgid "Module" #~ msgstr "Module" @@ -6741,9 +6958,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Pause(toolhead shell off)" #~ msgstr "Pause(toolhead shell off)" -#~ msgid "Please fill report first." -#~ msgstr "Gelieve eerst het rapport in te vullen." - #~ msgid "Please upgrade your printer first" #~ msgstr "Please upgrade your printer first" @@ -6760,17 +6974,11 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Preview only mode for gcode file." #~ msgstr "Preview only mode for G-code file." -#~ msgid "Printer Selection" -#~ msgstr "Printer selectie" - #~ msgid "" #~ "Push new filament \n" #~ "into extruder" #~ msgstr "Nieuw filament in de extruder laden" -#~ msgid "Sending" -#~ msgstr "Sending" - #~ msgid "Shift + Any arrow" #~ msgstr "Shift + willekeurige pijl" @@ -6786,9 +6994,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Show Printable Box(TODO)" #~ msgstr "Toon printbare uimte(TODO)" -#~ msgid "Spiral mode" -#~ msgstr "Spiraal modus" - #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" #~ msgstr "" #~ "Successfully sent. Will automatically jump to the device page in %s s" @@ -6796,9 +7001,6 @@ msgstr "Support: propagate branches at layer %d" #~ msgid "Swith cloud environment, Please login again!" #~ msgstr "De cloud omgeving is aangepast. Log opnieuw in aub." -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "De configuratie is niet compatibel en kan niet geladen worden!" - #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" @@ -6806,19 +7008,5 @@ msgstr "Support: propagate branches at layer %d" #~ "The firmware versions of the printer and AMS are too low. Please update " #~ "them to the latest version before sending any print jobs." -#~ msgid "Unable to create zip file" -#~ msgstr "Unable to create zip file" - -#~ msgid "Uploading" -#~ msgstr "Uploading" - #~ msgid "User pause" #~ msgstr "User pause" - -#~ msgid "Waiting" -#~ msgstr "Waiting" - -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "" -#~ "Het 3mf bestand is niet compatibel, enkel de geometrische data wordt " -#~ "geladen!" diff --git a/bbl/i18n/sv/BambuStudio_sv.po b/bbl/i18n/sv/BambuStudio_sv.po index a4810b1823..d2ac23ef09 100644 --- a/bbl/i18n/sv/BambuStudio_sv.po +++ b/bbl/i18n/sv/BambuStudio_sv.po @@ -2,13 +2,16 @@ msgid "" msgstr "" "Project-Id-Version: Bambu Studio\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Localazy (https://localazy.com)\n" "Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n" +"X-Generator: Poedit 3.1\n" msgid "Supports Painting" msgstr "Färgläggning av Support" @@ -47,7 +50,7 @@ msgid "Gap fill" msgstr "" msgid "Perform" -msgstr "Utför" +msgstr "Apply" msgid "Gap area" msgstr "" @@ -74,7 +77,7 @@ msgid "Sphere" msgstr "Sfär" msgid "Fill" -msgstr "Fyll" +msgstr "Fill" msgid "Gap Fill" msgstr "" @@ -143,10 +146,10 @@ msgid "Shortcut Key " msgstr "Snabbkommando " msgid "Triangle" -msgstr "Triangel" +msgstr "Triangle" msgid "Height Range" -msgstr "Höjd intervall" +msgstr "Height Range" msgid "Remove painted color" msgstr "Ta bort färgläggning" @@ -329,10 +332,10 @@ msgid "Operation already cancelling. Please wait few seconds." msgstr "Åtgärden avbryts redan. Vänligen vänta." msgid "Face recognition" -msgstr "Ansiktsigenkänning" +msgstr "Face recognition" msgid "Perform Recognition" -msgstr "Utför igenkänning" +msgstr "Perform Recognition" msgid "Reset direction" msgstr "" @@ -364,6 +367,21 @@ msgstr "" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "" + +msgid "Font" +msgstr "" + +msgid "Thickness" +msgstr "" + +msgid "Input text" +msgstr "" + +msgid "Add" +msgstr "Lägg till" + msgid "Notice" msgstr "Iakttag" @@ -519,8 +537,8 @@ msgid "" "The version of Bambu studio is too low and needs to be updated to the latest " "version before it can be used normally" msgstr "" -"Versionen av Bambu studio är för låg och behöver uppdateras till den senaste " -"versionen innan den kan användas normalt" +"The version of Bambu Studio is too low and needs to be updated to the latest " +"version before it can be used normally" msgid "Login information expired. Please login again." msgstr "Inloggningsinformationen har löpt ut. Logga in igen." @@ -529,7 +547,7 @@ msgid "Loading" msgstr "Laddar" msgid "Loading user preset" -msgstr "Laddar användarens förinställning" +msgstr "Loading user preset" msgid "Switching application language" msgstr "Byt applikationsspråk" @@ -547,11 +565,11 @@ msgid "Select a G-code file:" msgstr "Välj en G-kod fil:" msgid "Bambu Studio GUI initialization failed" -msgstr "Bambu Studio GUI-initiering misslyckades" +msgstr "Bambu Studio GUI initialization failed" #, boost-format msgid "Fatal error, exception catched: %1%" -msgstr "Allvarligt fel, undantag hittat: %1%" +msgstr "Fatal error, exception: %1%" msgid "Quality" msgstr "Kvalitet" @@ -640,9 +658,6 @@ msgstr "Cylinder" msgid "Cone" msgstr "Kon" -msgid "Timelapse Wipe Tower" -msgstr "Timelapse Wipe Tower" - msgid "Add settings" msgstr "Lägg till inställning" @@ -1056,10 +1071,10 @@ msgid "Push new filament into extruder" msgstr "" msgid "Purge old filament" -msgstr "Rensa gammalt filament" +msgstr "Purge old filament" msgid "?" -msgstr " ?" +msgstr "?" msgid "Empty" msgstr "Tom" @@ -1068,10 +1083,10 @@ msgid "Click the pencil icon to edit the filament." msgstr "Tryck på penn ikonen för att editera filament." msgid "Load Filament" -msgstr "Ladda Filament" +msgstr "Load" msgid "Unload Filament" -msgstr "Mata ut" +msgstr "Unload" msgid "Tips" msgstr "Tips" @@ -1178,64 +1193,62 @@ msgid "Exception" msgstr "Undantag" msgid "Logging in" -msgstr "Loggar in" +msgstr "Logging in" msgid "Login failed" -msgstr "Inloggning misslyckades" +msgstr "Login failed" msgid "The region parameter is incorrrect" -msgstr "Region parametern är felaktig." +msgstr "The region parameter is incorrrect." msgid "Failure of printer login" -msgstr "Fel i inloggningen till skrivaren" +msgstr "Printer login failure" msgid "Failed to get ticket" -msgstr "Misslyckades med att få en kvittering" +msgstr "Failed to get ticket" msgid "User authorization timeout" -msgstr "Timeout för användarauktorisering" +msgstr "User authorization timeout" msgid "Failure of bind" -msgstr "Fel vid sammankoppling" +msgstr "Binding failure" msgid "Unknown Failure" -msgstr "Okänt fel" +msgstr "Unknown Failure" msgid "Abnormal print file data. Please slice again" -msgstr "Onormal utskrifts fil data. Vänligen bered igen" +msgstr "Abnormal print file data. Please slice again" msgid "Task canceled" -msgstr "Uppgift avbruten" +msgstr "Task canceled" msgid "Upload task timed out. Please check the network problem and try again" -msgstr "" -"Uppladdningsuppgiften tog timeout. Kontrollera nätverksproblemet och försök " -"igen" +msgstr "Upload task timed out. Please check the network and try again" msgid "Cloud service connection failed. Please try again." -msgstr "Anslutningen till molntjänsten misslyckades. Försök igen." +msgstr "Cloud service connection failed. Please try again." msgid "Print file not found, please slice again" -msgstr "Det gick inte att hitta utskrifts filen, vänligen bered igen" +msgstr "Print file not found, please slice again" msgid "" "The print file exceeds the maximum allowable size (1GB). Please simplify the " "model and slice again" msgstr "" -"Utskrifts filen överskrider den högsta tillåtna storleken (1 GB). Förenkla " -"modellen och bered igen" +"The print file exceeds the maximum allowable size (1GB). Please simplify the " +"model and slice again" msgid "Failed uploading print file" -msgstr "Uppladdning av utskrifts filen misslyckades" +msgstr "Failed uploading print file" msgid "Wrong Access code" -msgstr "Fel åtkomstkod" +msgstr "Wrong Access code" msgid "Sending print job over LAN" -msgstr "Skicka utskriftsjobb via LAN" +msgstr "Sending print job over LAN" msgid "Sending print job through cloud service" -msgstr "Skicka utskriftsjobb via molntjänst" +msgstr "Sending print job through cloud service" msgid "Service Unavailable" msgstr "" @@ -1243,8 +1256,11 @@ msgstr "" msgid "Unkown Error." msgstr "" +msgid "Please Fill Task Report." +msgstr "" + msgid "Sending print configuration" -msgstr "Skicka utskrifts konfiguration" +msgstr "Sending print configuration" #, c-format, boost-format msgid "Successfully sent. Will automatically jump to the device page in %s s" @@ -1272,16 +1288,16 @@ msgid "Install failed" msgstr "" msgid "Portions copyright" -msgstr "Information om licens" +msgstr "License Info" msgid "Copyright" -msgstr "Upphovsrätt" +msgstr "Copyright" msgid "License" -msgstr "Licens" +msgstr "License" msgid "Bambu Studio is licensed under " -msgstr "Bambu Studio är licensierad under " +msgstr "Bambu Studio is licensed under " msgid "GNU Affero General Public License, version 3" msgstr "GNU Affero General Public License, version 3" @@ -1290,22 +1306,22 @@ msgid "" "Bambu Studio is based on PrusaSlicer by Prusa Research, which is from Slic3r " "by Alessandro Ranellucci and the RepRap community" msgstr "" -"Bambu Studio är baserad på PrusaSlicer av Prusa Research, som är från Slic3r " -"av Alessandro Ranellucci och RepRap-communityn" +"Bambu Studio is based on PrusaSlicer by Prusa Research, which is based on " +"Slic3r by Alessandro Ranellucci and the RepRap community" msgid "Libraries" -msgstr "Bibliotek" +msgstr "Libraries" msgid "" "This software uses open source components whose copyright and other " "proprietary rights belong to their respective owners" msgstr "" -"Denna programvara använder komponenter med öppen källkod vars upphovsrätt " -"och andra äganderätt tillhör respektive ägare" +"This software uses open source components whose copyright and other " +"proprietary rights belong to their respective owners" #, c-format, boost-format msgid "About %s" -msgstr "Om %s" +msgstr "About %s" msgid "" "Bambu Studio is based on PrusaSlicer by PrusaResearch and SuperSlicer by " @@ -1333,14 +1349,14 @@ msgid "AMSMaterialsSetting" msgstr "" msgid "Colour" -msgstr "Färg" +msgstr "Color" msgid "" "Nozzle\n" "Temperature" msgstr "" -"Nozzle \n" -"temperatur" +"Nozzle\n" +"Temperature" msgid "max" msgstr "max" @@ -1350,7 +1366,7 @@ msgstr "min" #, boost-format msgid "The input value should be greater than %1% and less than %2%" -msgstr "Inmatningsvärdet ska vara större än %1% och mindre än %2%" +msgstr "The input value should be greater than %1% and less than %2%" msgid "SN" msgstr "SN" @@ -1368,49 +1384,62 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" -msgstr "Infoga uppdatering" +msgstr "Insertion update" msgid "" "The AMS will automatically read the filament information when inserting a " "new Bambu Lab filament. This takes about 20 seconds." msgstr "" -"AMS läser automatiskt filament informationen när du sätter in ett nytt Bambu " -"Lab-filament. Det tar ungefär 20 sekunder." +"The AMS will automatically read the filament information when inserting a " +"new Bambu Lab filament spool. This takes about 20 seconds." msgid "" "Note: if new filament is inserted during printing, the AMS will not " "automatically read any information until printing is completed." msgstr "" -"Observera: Om nytt filament sätts in under utskrift kommer AMS inte " -"automatiskt att läsa av någon information förrän utskriften är avslutad." +"Note: if new filament is inserted during printing, the AMS will not " +"automatically read any information until printing has finished." msgid "" "When inserting a new filament, the AMS will not automatically read its " "information, leaving it blank for you to enter manually." msgstr "" -"Vid matning av nytt filament, AMS läser inte av dess information automatiskt " -"utan lämnar det blankt för dig att fylla i manuellt." +"When inserting a new filament, the AMS will not automatically read its " +"information, leaving it blank for you to enter manually." msgid "Power on update" -msgstr "Slå på uppdatering" +msgstr "Power on update" msgid "" "The AMS will automatically read the information of inserted filament on " "start-up. It will take about 1 minute.The reading process will roll filament " "spools." msgstr "" -"AMS läser automatiskt informationen om insatt Bambu Lab filament vid " -"uppstart. Det tar cirka 1 minut. Läsprocessen kommer att rulla " -"filamentspolarna." +"The AMS will automatically read the information of inserted filament on " +"start-up. It will take about 1 minute.The reading process will rotate the " +"filament spools." msgid "" "The AMS will not automatically read information from inserted filament " "during startup and will continue to use the information recorded before the " "last shutdown." msgstr "" -"AMS kommer inte att automatiskt läsa informationen ifrån imatat filament " -"under uppstart och senast använd information kommer att användas." +"The AMS will not automatically read information from inserted filament " +"during startup and will continue to use the information recorded before the " +"last shutdown." msgid "File" msgstr "Fil" @@ -1445,7 +1474,7 @@ msgid "Underflow" msgstr "Underflöde" msgid "Floating reserved operand" -msgstr "Reservations operand med flytande värde" +msgstr "Floating reserved operand" msgid "Stack overflow" msgstr "Lagra överflöde" @@ -1517,7 +1546,7 @@ msgid "Not found:" msgstr "Ej funnen:" msgid "Model" -msgstr "Modell" +msgstr "Model" msgid "Choose an STL file to import bed shape from:" msgstr "Välj en STL fil för att importera bygglattans form ifrån:" @@ -1704,67 +1733,67 @@ msgstr "" "NEJ - Återställ densiteten till standard inte 100% värdet automatiskt\n" msgid "Auto bed leveling" -msgstr "Auto justera byggplattan" +msgstr "Auto bed leveling" msgid "Heatbed preheating" -msgstr "Byggplattan förvärms" +msgstr "Heatbed preheating" msgid "Sweeping XY mech mode" -msgstr "Sveper XY mech-läge" +msgstr "Sweeping XY mech mode" msgid "Changing filament" -msgstr "Byter filament" +msgstr "Changing filament" msgid "M400 pause" -msgstr "M400 paus" +msgstr "M400 pause" msgid "Paused due to filament runout" -msgstr "Pausad på grund av filament slut" +msgstr "Paused due to filament runout" msgid "Heating hotend" -msgstr "Värmer hotend" +msgstr "Heating hotend" msgid "Calibrating extrusion" -msgstr "Kalibrerar extrudering" +msgstr "Calibrating extrusion" msgid "Scanning bed surface" -msgstr "Skannar byggplattan" +msgstr "Scanning bed surface" msgid "Inspecting first layer" -msgstr "Inspekterar första lager" +msgstr "Inspecting first layer" msgid "Identifying build plate type" -msgstr "Identifiering av byggplatta" +msgstr "Identifying build plate type" msgid "Calibrating Micro Lidar" -msgstr "Kalibrerar Micro Lidar" +msgstr "Calibrating Micro Lidar" msgid "Homing toolhead" -msgstr "Nollställer verktygshuvudet" +msgstr "Homing toolhead" msgid "Cleaning nozzle tip" -msgstr "Rengör nozzle spetsen" +msgstr "Cleaning nozzle tip" msgid "Checking extruder temperature" -msgstr "Kontrollerar extruderings temperatur" +msgstr "Checking extruder temperature" msgid "Printing was paused by the user" -msgstr "Utskriften pausades av användaren" +msgstr "Printing was paused by the user" msgid "Pause of front cover falling" -msgstr "Paus av front luckan faller" +msgstr "Pause of front cover falling" msgid "Calibrating the micro lida" -msgstr "Kalibrerar Micro Lidar" +msgstr "Calibrating the micro lidar" msgid "Calibrating extrusion flow" -msgstr "Kalibrerar extruderings flödet" +msgstr "Calibrating extrusion flow" msgid "Paused due to nozzle temperature malfunction" -msgstr "Pausad på grund av fel i nozzle temperaturen" +msgstr "Paused due to nozzle temperature malfunction" msgid "Paused due to heat bed temperature malfunction" -msgstr "Pausad på grund av fel i byggplattans temperatur" +msgstr "Paused due to heat bed temperature malfunction" msgid "MC" msgstr "MC" @@ -1899,9 +1928,6 @@ msgstr "Tid" msgid "Display" msgstr "Visa" -msgid "Line type" -msgstr "Linje typ" - msgid "Layer Height (mm)" msgstr "Lagerhöjd (mm)" @@ -1963,10 +1989,10 @@ msgid "Filament 1" msgstr "Filament 1" msgid "Flushed filament" -msgstr "Rensat filament" +msgstr "Flushed filament" msgid "Filament change times" -msgstr "Filament bytes tider" +msgstr "Filament change times" msgid "Color change" msgstr "Färg byte" @@ -1978,7 +2004,7 @@ msgid "Pause" msgstr "Paus" msgid "Printer" -msgstr "Skrivare" +msgstr "Printer" msgid "Print settings" msgstr "Utskrifts inställningar" @@ -1989,6 +2015,9 @@ msgstr "Total Uppskattning" msgid "Normal mode" msgstr "Normalt läge" +msgid "Cost" +msgstr "Kostnad" + msgid "Prepare time" msgstr "Förbered tid" @@ -1996,7 +2025,7 @@ msgid "Model printing time" msgstr "Utskriftstid för modellen" msgid "Total" -msgstr "Totalt" +msgstr "Total" msgid "Switch to silent mode" msgstr "Ändra till tyst läge" @@ -2043,9 +2072,6 @@ msgstr "Tillåt multipla material på samma byggplatta" msgid "Avoid extrusion calibration region" msgstr "Undvik kalibrerings området" -msgid "Add" -msgstr "Lägg till" - msgid "Add plate" msgstr "Lägg till byggplata" @@ -2074,7 +2100,7 @@ msgid "Assembly Return" msgstr "Monterings retur" msgid "return" -msgstr "tillbaka" +msgstr "return" msgid "Paint Toolbar" msgstr "Färgläggningsverktyg" @@ -2120,9 +2146,9 @@ msgid "" "minimize deviation.\n" "It keeps the device performing optimally." msgstr "" -"Kalibreringsprogrammet avläser status på enheten för att automatiskt " -"minimera avvikelser. \n" -"Detta gör att enheten kan fungera optimalt." +"The calibration program detects the status of your device automatically to " +"minimize deviation.\n" +"It keeps the device performing optimally." msgid "Calibration Flow" msgstr "Kalibrerings Flöde" @@ -2140,24 +2166,33 @@ msgid "Timelapse" msgstr "Timelapse" msgid "Monitoring Recording" -msgstr "Övervaknings Inspelning" +msgstr "Monitoring Recording" msgid "ConnectPrinter(LAN)" -msgstr "Anslut skrivare (LAN)" +msgstr "Connect Printer (LAN)" msgid "Please input the printer access code:" -msgstr "Ange skrivarens åtkomstkod:" +msgstr "Please input the printer access code:" msgid "" "You can find it in \"Settings > Network > Connection code\"\n" "on the printer, as shown in the figure:" msgstr "" -"Du hittar den i ”Inställningar> Nätverk> Anslutningskod”\n" -"på skrivaren, som visas i figuren:" +"You can find it in \"Settings > Network > Connection code\"\n" +"on the printer, as shown in the figure:" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "Enter a search term" + +msgid "Online" +msgstr "Online" + +msgid "Offline" +msgstr "Offline" + msgid "Application is closing" msgstr "Begäran avslutas" @@ -2171,14 +2206,17 @@ msgid "Prepare" msgstr "Förbered" msgid "Preview" -msgstr "Förhandsvisning" +msgstr "Förvisning" msgid "Device" -msgstr "Enhet" +msgstr "Device" msgid "Project" msgstr "Projekt" +msgid "Debug" +msgstr "Felsök" + msgid "Slice" msgstr "Bered" @@ -2216,12 +2254,18 @@ msgstr "Sök efter Uppdatering" msgid "&About %s" msgstr "&Om %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "Standard Vy" #. TRN To be shown in the main menu View->Top msgid "Top" -msgstr "Topplager" +msgstr "Top" msgid "Top View" msgstr "Vy Top" @@ -2287,9 +2331,24 @@ msgstr "Importera 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "Ladda modell" +msgid "Import Configs" +msgstr "" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "" + msgid "Export all objects as STL" msgstr "Exportera Alla Objekt som STL" +msgid "Export Generic 3MF" +msgstr "" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "" + msgid "Export current Sliced file" msgstr "Exportera nuvarande Beredda fil" @@ -2299,6 +2358,12 @@ msgstr "Exportera G-kod" msgid "Export current plate as G-code" msgstr "" +msgid "Export &Configs" +msgstr "" + +msgid "Export current configuration to files" +msgstr "" + msgid "Export" msgstr "Exportera" @@ -2365,60 +2430,85 @@ msgstr "Använd Ortogonal Vy" msgid "Preferences" msgstr "Inställningar" -msgid "About" -msgstr "" - msgid "View" msgstr "Vy" msgid "Help" msgstr "Hjälp" -msgid "&File" -msgstr "&Fil" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "&Visa" - -msgid "&Help" -msgstr "&Hjälp" - msgid "&Open G-code" -msgstr "&Öppna G-kod" +msgstr "&Open G-code" msgid "Open a G-code file" -msgstr "Öppna en G-kod fil" +msgstr "Open a G-code file" msgid "Re&load from Disk" -msgstr "Ladda om från disk" +msgstr "Re&load from Disk" msgid "Reload the plater from disk" -msgstr "Ladda om plattan från disken" +msgstr "Reload the plater from disk" msgid "Export &Toolpaths as OBJ" -msgstr "Exportera &Toolpaths som OBJ" +msgstr "Export &Toolpaths as OBJ" msgid "Export toolpaths as OBJ" -msgstr "Exportera toolpaths som OBJ" +msgstr "Export toolpaths as OBJ" msgid "Open &PrusaSlicer" -msgstr "Öppna &PrusaSlicer" +msgstr "Open &PrusaSlicer" msgid "Open PrusaSlicer" -msgstr "Öppna PrusaSlicer" +msgstr "Open PrusaSlicer" msgid "&Quit" -msgstr "&Avsluta" +msgstr "&Quit" #, c-format, boost-format msgid "Quit %s" -msgstr "Avsluta %s" +msgstr "Quit %s" -msgid "Save configuration as:" -msgstr "Spara konfigurationen som:" +msgid "&File" +msgstr "&File" + +msgid "&View" +msgstr "&View" + +msgid "&Help" +msgstr "&Help" + +msgid "Overwrite file" +msgstr "" + +msgid "Yes to All" +msgstr "" + +msgid "No to All" +msgstr "" + +msgid "Choose a directory" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Export result" +msgstr "" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "" +msgstr[1] "" + +msgid "Import result" +msgstr "" msgid "File is missing" msgstr "Filen saknas" @@ -2463,53 +2553,99 @@ msgstr "Spelar..." msgid "Load failed [%d]!" msgstr "Laddning misslyckad [%d]!" -msgid "3Dconnexion settings" -msgstr "3Dconnexion inställningar" +msgid "Year" +msgstr "" -msgid "Device:" -msgstr "Enhet:" +msgid "Month" +msgstr "" + +msgid "All Files" +msgstr "" + +msgid "Video" +msgstr "" + +msgid "Download" +msgstr "Ladda ner" + +msgid "Management" +msgstr "" + +msgid "No printers." +msgstr "" + +msgid "Connecting..." +msgstr "" + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "" + +msgid "Loading file list..." +msgstr "" + +msgid "No files" +msgstr "" + +msgid "Choose save directory" +msgstr "" + +msgid "Waiting" +msgstr "Waiting" + +msgid "Retry" +msgstr "" + +msgid "Failed" +msgstr "" + +msgid "Open" +msgstr "" + +msgid "Finished" +msgstr "Finished" msgid "Speed:" msgstr "Hastighet:" -msgid "Translation" -msgstr "Översättning" - -msgid "Zoom" -msgstr "Zooma" - msgid "Deadzone:" msgstr "Upphör:" msgid "Options:" msgstr "Val:" +msgid "Zoom" +msgstr "Zoom" + +msgid "Translation/Zoom" +msgstr "" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion inställningar" + msgid "Swap Y/Z axes" msgstr "Byta Y/Z axes" msgid "Camera" msgstr "" -msgid "Video" -msgstr "" - msgid "Printing Progress" msgstr "Utskriftsförlopp" -msgid "Report" -msgstr "Rapportera" +msgid "Resume" +msgstr "Återuppta" msgid "Stop" msgstr "Stopp" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "" msgid "Control" -msgstr "Kontroll" +msgstr "Control" msgid "Print Options" msgstr "" @@ -2541,9 +2677,6 @@ msgstr "Utskrifts Lista" msgid "Downloading..." msgstr "" -msgid "Resume" -msgstr "Återuppta" - msgid "Silent" msgstr "Tyst" @@ -2574,9 +2707,6 @@ msgstr "Uppkoppling till servern misslyckades" msgid "Failed to connect to the printer" msgstr "Uppkoppling till printern misslyckades" -msgid "Connecting..." -msgstr "" - msgid "OK" msgstr "OK" @@ -2610,9 +2740,6 @@ msgstr "%s info" msgid "%s information" msgstr "%s information" -msgid "Download" -msgstr "Ladda ner" - msgid "Skip" msgstr "Hoppa över" @@ -2804,9 +2931,6 @@ msgstr "Filament Åtgång (g)" msgid "Used Materials" msgstr "Material Åtgång" -msgid "Cost" -msgstr "Kostnad" - msgid "Estimated time" msgstr "Uppskattad tid" @@ -2865,6 +2989,12 @@ msgstr "Uppdatera mjukvaran.\n" msgid "Newer 3mf version" msgstr "Nyare 3mf version" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -2909,7 +3039,7 @@ msgid "Object with multiple parts was detected" msgstr "Ett objekt med multipla delar har upptäckts" msgid "The file does not contain any geometry data." -msgstr "Filen innehåller ingen geometrisk data." +msgstr "The file does not contain any geometry data." msgid "" "Your object appears to be too large, Do you want to scale it down to fit the " @@ -3003,10 +3133,10 @@ msgid "G-code files can not be loaded with models together!" msgstr "G-kod filer och modeller kan inte laddas tillsammans!!" msgid "Can not add models when in preview mode!" -msgstr "Det gick inte att lägga till modeller i förhandsvisningsläge" +msgstr "Unable to add models in preview mode" msgid "Add Models" -msgstr "Lägg till modeller" +msgstr "Add Models" msgid "All objects will be removed, continue?" msgstr "Alla objekt kommer att raderas, fortsätta?" @@ -3066,7 +3196,7 @@ msgstr "Storlek: %1% x %2% x %3% mm\n" #, boost-format msgid "Volume: %1% in³\n" -msgstr "Volym: %1% i³\n" +msgstr "Volume: %1% in³\n" #, boost-format msgid "Volume: %1% mm³\n" @@ -3092,34 +3222,34 @@ msgid "Changing application language" msgstr "Byter språk" msgid "Changing the region will log out your account.\n" -msgstr "Om du ändrar regionen loggas du ut från ditt konto.\n" +msgstr "Changing the region will log you out of your account.\n" msgid "Region selection" -msgstr "Val av region" +msgstr "Region selection" msgid "Second" msgstr "Andra" msgid "General Settings" -msgstr "Allmänna inställningar" +msgstr "General Settings" msgid "Asia-Pacific" -msgstr "Asien-Stillahavsområdet" +msgstr "Asia-Pacific" msgid "China" -msgstr "Kina" +msgstr "China" msgid "Europe" -msgstr "Europa" +msgstr "Europe" msgid "North America" -msgstr "Nordamerika" +msgstr "North America" msgid "Others" msgstr "Andra" msgid "Login Region" -msgstr "Logga in Region" +msgstr "Login Region" msgid "Metric" msgstr "Metrisk" @@ -3134,12 +3264,10 @@ msgid "User sync" msgstr "Användar synkronisering" msgid "Auto sync user presets(Printer/Filament/Process)" -msgstr "" -"Automatisk synkronisering av användarens förinställningar (skrivare/filament/" -"process)" +msgstr "Auto sync user presets (Printer/Filament/Process)" msgid "User Sync" -msgstr "Användar synkronisering" +msgstr "User Sync" msgid "Associate files to BambuStudio" msgstr "Associerade filer till Bambu Studio" @@ -3157,7 +3285,7 @@ msgid "If enabled, sets BambuStudio as default application to open .stl files" msgstr "Om aktiverad, väljs Bambu Studio som standard att öppna .stl filer" msgid "Associate .step/.stp files to BambuStudio" -msgstr "Associera .step/.stp-filer till BambuStudio" +msgstr "Associate .step/.stp files to Bambu Studio" msgid "If enabled, sets BambuStudio as default application to open .step files" msgstr "Om aktiverad, väljs Bambu Studio som standard att öppna .step filer" @@ -3232,7 +3360,7 @@ msgid "trace" msgstr "spåra" msgid "Host Setting" -msgstr "Värd Inställning" +msgstr "Host Setting" msgid "DEV host: api-dev.bambu-lab.com/v1" msgstr "DEV host: api-dev.bambu-lab.com/v1" @@ -3390,12 +3518,6 @@ msgstr "För \"%1%\", lägg till \"%2%\" som ny förinställning" msgid "Simply switch to \"%1%\"" msgstr "Byta till \"%1%\"" -msgid "Online" -msgstr "Online" - -msgid "Offline" -msgstr "Offline" - msgid "My Device" msgstr "Min Enhet" @@ -3403,13 +3525,13 @@ msgid "Other Device" msgstr "Andra Enheter" msgid "Input access code" -msgstr "Inmatning av åtkomstkod" +msgstr "Input access code" msgid "Log out successful." msgstr "Utloggning lyckades." msgid "Busy" -msgstr "Upptagen" +msgstr "Busy" msgid "Bambu Cool Plate" msgstr "Bambu Cool Plate" @@ -3424,7 +3546,7 @@ msgid "Send print job to" msgstr "Skicka utskriftsjobb till" msgid "Refresh" -msgstr "Uppdatera" +msgstr "Refresh" msgid "Bed Leveling" msgstr "Justering av Byggplattan" @@ -3439,28 +3561,27 @@ msgid "send completed" msgstr "Skicka komplett" msgid "No login account, only printers in LAN mode are displayed" -msgstr "Inget inloggningskonto, bara skrivare i LAN-läge visas" +msgstr "No login account, only printers in LAN mode are displayed" msgid "Connecting to server" -msgstr "Ansluter till server" +msgstr "Connecting to server" msgid "Synchronizing device information" -msgstr "Synkroniserar enhetsinformation" +msgstr "Synchronizing device information" msgid "Synchronizing device information time out" -msgstr "Time-out för synkronisering av enhetsinformation" +msgstr "Synchronizing device information time out" msgid "Cannot send the print task when the upgrade is in progress" -msgstr "Det går inte att skicka utskriftsuppgiften när uppgraderingen pågår" +msgstr "Cannot send the print task when the upgrade is in progress" msgid "" "The printer is executing instructions. Please restart printing after it ends" msgstr "" -"Skrivaren utför instruktioner. Vänligen starta utskriften igen när den är " -"avslutad." +"The printer is executing instructions. Please restart printing after it ends" msgid "The printer is busy on other print job" -msgstr "Skrivaren är upptagen med ett annat utskriftsjobb." +msgstr "The printer is busy with another print job." #, c-format, boost-format msgid "" @@ -3477,15 +3598,15 @@ msgid "" "Filaments to AMS slots mappings have been established. You can click a " "filament above to change its mapping AMS slot" msgstr "" -"Filament i AMS facken har fastställts. Du kan klicka på ett filament ovan " -"för att ändra dess plats i AMS facken" +"Filaments to AMS slots mappings have been established. You can click a " +"filament above to change its mapping AMS slot" msgid "" "Please click each filament above to specify its mapping AMS slot before " "sending the print job" msgstr "" -"Klicka på varje filament ovan för att ange dess plats i AMS-facken innan du " -"skickar utskriftsjobbet" +"Please click each filament above to specify its mapping AMS slot before " +"sending the print job" #, c-format, boost-format msgid "" @@ -3504,10 +3625,10 @@ msgid "" msgstr "" msgid "Preparing print job" -msgstr "Förbereder utskriftsjobb" +msgstr "Preparing print job" msgid "Modifying the device name" -msgstr "Ändra enhetens namn" +msgstr "Modifying the device name" msgid "Log in printer" msgstr "Logga in skrivare" @@ -3541,6 +3662,15 @@ msgstr "Spara nuvarande %s" msgid "Delete this preset" msgstr "Radera denna förinställning" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3594,7 +3724,7 @@ msgid "Prime tower" msgstr "Prime torn" msgid "Flush options" -msgstr "Rensnings alternativ" +msgstr "Flush options" msgid "Special mode" msgstr "Special läge" @@ -3631,7 +3761,7 @@ msgid "Reserved keywords found" msgstr "Hittade reserverade nyckelord" msgid "Setting Overrides" -msgstr "Åsidosätter inställningar" +msgstr "Setting Overrides" msgid "Retraction" msgstr "Reduktion" @@ -3666,8 +3796,8 @@ msgid "" "Bed temperature when cool plate is installed. Value 0 means the filament " "does not support to print on the Cool Plate" msgstr "" -"Detta är byggplattans temperatur när Cool Plate är installerad. Värdet 0 " -"betyder att filamentet inte stöder utskrift på Cool Plate." +"This is the bed temperature when the cool plate is installed. A value of 0 " +"means the filament does not support printing on the Cool Plate." msgid "Engineering plate" msgstr "Engineering plate" @@ -3676,8 +3806,8 @@ msgid "" "Bed temperature when engineering plate is installed. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Detta är byggplattans temperatur när Engineering Plate är installerad. Ett " -"värde på 0 betyder att filamentet inte stöder utskrift på Engineering Plate." +"This is the bed temperature when the engineering plate is installed. A value " +"of 0 means the filament does not support printing on the Engineering Plate." msgid "High Temp Plate" msgstr "High Temp Plate" @@ -3686,8 +3816,17 @@ msgid "" "Bed temperature when high temperature plate is installed. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Detta är byggplattans temperatur när High Temp Plate är installerad. Värdet " -"0 betyder att filamentet inte stöder utskrift på High Temp Plate." +"This is the bed temperature when the high temperature plate is installed. A " +"value of 0 means the filament does not support printing on the High Temp " +"Plate." + +msgid "Textured PEI Plate" +msgstr "" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Volumetric speed limitation" msgstr "Volumetrisk hastighets begränsning" @@ -3840,7 +3979,7 @@ msgid "New Value" msgstr "Nytt värde" msgid "Transfer" -msgstr "Överför" +msgstr "Transfer" msgid "Don't save" msgstr "Spara inte" @@ -3918,6 +4057,12 @@ msgstr "Allmän" msgid "Capabilities" msgstr "Förmågor" +msgid "Show all presets (including incompatible)" +msgstr "" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "Ställ in som skydd" @@ -3929,7 +4074,7 @@ msgid "The name \"%1%\" already exists." msgstr "Namnet \"%1%\" finns redan." msgid "Basic Info" -msgstr "Grundläggande information" +msgstr "Basic Info" msgid "Pictures" msgstr "Bilder" @@ -3943,8 +4088,8 @@ msgstr "Monterings Guide" msgid "Choose files" msgstr "Välj filer" -msgid "Designer" -msgstr "Designer" +msgid "Author" +msgstr "" msgid "Model Name" msgstr "Modell Namn" @@ -3981,7 +4126,7 @@ msgstr "" #, c-format, boost-format msgid "Exit %s" -msgstr "Avsluta %s" +msgstr "Exit %s" msgid "the Configuration package is incompatible with current APP." msgstr "" @@ -3998,7 +4143,7 @@ msgid "The configuration is up to date." msgstr "Konfigurationen är aktuell." msgid "Auto-Calc" -msgstr "Autoberäkna" +msgstr "Auto-Calc" msgid "Flushing volumes for filament change" msgstr "Rensnings volym för filament byte" @@ -4007,7 +4152,7 @@ msgid "Flushing volume (mm³) for each filament pair." msgstr "Rensnings volym (mm³) för varje filament." msgid "Flush multiplier" -msgstr "Rensnings multiplikator" +msgstr "Flush multiplier" msgid "unloaded" msgstr "utmatad" @@ -4048,6 +4193,9 @@ msgstr "Kopiera till urklipp" msgid "Paste from clipboard" msgstr "Klistra in ifrån urklipp" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "" + msgid "Show keyboard shortcuts list" msgstr "Visa tangentbordets genvägs lista" @@ -4188,6 +4336,9 @@ msgstr "" msgid "Support/Color Painting: adjust pen radius" msgstr "Support/Färgläggning: justera penn radie" +msgid "⌥+Mouse wheel" +msgstr "" + msgid "Support/Color Painting: adjust section position" msgstr "Support/Färgläggning:justera sektions positionen" @@ -4207,7 +4358,7 @@ msgid "Delete objects, parts, modifiers " msgstr "Radera objekten, delarna och anpassningar " msgid "Space" -msgstr "Mellanslag" +msgstr "Space" msgid "Select the object/part and press space to change the name" msgstr "Välj objektet/delen och tryck space för att ändra namnet" @@ -4505,11 +4656,11 @@ msgstr "" #, boost-format msgid "%1% is too close to others, and collisions may be caused." -msgstr "%1% är för nära andra och kan orsaka kollisioner." +msgstr "%1% is too close to others, and collisions may be caused." #, boost-format msgid "%1% is too tall, and collisions will be caused." -msgstr "%1% är för hög, och kollisioner kommer att uppstå." +msgstr "%1% is too tall, and collisions will be caused." msgid " is too close to others, there will be collisions when printing.\n" msgstr " för tätt inpå andra, utskriften kolliderar.\n" @@ -4522,11 +4673,10 @@ msgid "Prime Tower" msgstr "Prime Torn" msgid " is too close to others, and collisions may be caused.\n" -msgstr "är för nära andra och kollisioner kan orsakas.\n" +msgstr " is too close to others, and collisions may be caused.\n" msgid " is too close to exclusion area, and collisions will be caused.\n" -msgstr "" -" är för nära uteslutningsområdet, och kollisioner kommer att orsakas.\n" +msgstr " is too close to an exclusion area, and collisions will be caused.\n" msgid "" "Can not print multiple filaments which have large difference of temperature " @@ -4676,11 +4826,11 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Cool Plate" msgstr "" -"Detta är byggplattans temperatur för lager förutom det första. Värdet 0 " -"betyder att filamentet inte stöder utskrift på Cool Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Cool Plate." msgid "°C" -msgstr "° C" +msgstr "°C" msgid "Bed temperature" msgstr "Byggplattans temperatur" @@ -4689,15 +4839,20 @@ msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the Engineering Plate" msgstr "" -"Detta är byggplattans temperatur för lager förutom det första. Ett värde på " -"0 betyder att filamentet inte stöder utskrift på Engineering Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the Engineering Plate." msgid "" "Bed temperature for layers except the initial one. Value 0 means the " "filament does not support to print on the High Temp Plate" msgstr "" -"Detta är byggplattans temperatur för lager förutom det första. Värdet 0 " -"betyder att filamentet inte stöder utskrift på High Temp Plate." +"This is the bed temperature for layers except for the first one. A value of " +"0 means the filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "" msgid "Initial layer" msgstr "Första lager" @@ -4709,22 +4864,27 @@ msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Cool Plate" msgstr "" -"Detta är byggplattans temperatur för första lager. Värdet 0 betyder att " -"filamentet inte stöder utskrift på Cool Plate." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Cool Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the Engineering Plate" msgstr "" -"Detta är byggplattans temperatur för första lager. Värdet 0 betyder att " -"filamentet inte stöder utskrift på Engineering Plate." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the Engineering Plate." msgid "" "Bed temperature of the initial layer. Value 0 means the filament does not " "support to print on the High Temp Plate" msgstr "" -"Detta är byggplattans temperatur för första lager. Värdet 0 betyder att " -"filamentet inte stöder utskrift på High Temp Plate." +"This is the bed temperature of the first layer. A value of 0 means the " +"filament does not support printing on the High Temp Plate." + +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "" msgid "Bed types supported by the printer" msgstr "Byggplattans typ stöds av skrivaren" @@ -4810,14 +4970,14 @@ msgstr "" "bridges/bryggor, detta för att förbättra kvaliteten" msgid "Only one wall on top surfaces" -msgstr "Endast en vägg på topp ytan" +msgstr "Only one wall on top surfaces" msgid "" "Use only one wall on flat top surface, to give more space to the top infill " "pattern" msgstr "" -"Använd endast en vägg på topp ytan, för att ge mer utrymme till det övre " -"ifyllningsmönstret" +"Use only one wall on flat top surfaces, to give more space to the top infill " +"pattern" msgid "Slow down for overhang" msgstr "Sakta ner vid överhäng" @@ -4960,16 +5120,16 @@ msgid "" msgstr "" msgid "Max bridge length" -msgstr "Max bridge/brygg längd" +msgstr "Max bridge length" msgid "" "Max length of bridges that don't need support. Set it to 0 if you want all " "bridges to be supported, and set it to a very large value if you don't want " "any bridges to be supported." msgstr "" -"Maxlängd för bridge/brygga som inte behöver support. Ange 0 om du vill att " -"alla bridges/bryggor ska få support, och ett mycket stort värde om du inte " -"vill att några bridges/bryggor ska få support." +"This is the maximum length of bridges that don't need support. Set it to 0 " +"if you want all bridges to be supported, and set it to a very large value if " +"you don't want any bridges to be supported." msgid "End G-code" msgstr "Slut G-kod" @@ -4996,7 +5156,7 @@ msgid "Monotonic" msgstr "Monoton" msgid "Monotonic line" -msgstr "Monoton linje" +msgstr "Monotonic line" msgid "Bottom surface pattern" msgstr "Botten ytans mönster" @@ -5186,8 +5346,7 @@ msgstr "Support material" msgid "" "Support material is commonly used to print support and support interface" msgstr "" -"Support material används ofta för att skriva ut support och stödja " -"gränssnittet" +"Support material is commonly used to print support and support interfaces." msgid "Temperature of vitrificaiton" msgstr "Kristalliserings temperatur" @@ -5242,7 +5401,7 @@ msgid "Line" msgstr "Linje" msgid "Cubic" -msgstr "Kubisk" +msgstr "Cubic" msgid "Tri-hexagon" msgstr "Tri-hexagon" @@ -5260,8 +5419,8 @@ msgid "" "Acceleration of top surface infill. Using a lower value may improve top " "surface quality" msgstr "" -"Acceleration av fyllning av toppytan. Att använda ett lägre värde kan " -"förbättra ytkvaliteten" +"Acceleration of top surface infill. Using a lower value may improve top " +"surface quality" msgid "" "Acceleration of initial layer. Using a lower value can improve build plate " @@ -5664,10 +5823,10 @@ msgid "Diameter of nozzle" msgstr "Diametern på nozzeln" msgid "Nozzle volume" -msgstr "Nozzle volym" +msgstr "Nozzle volume" msgid "Volume of nozzle between the cutter and the end of nozzle" -msgstr "Volymen av nozzlen mellan skäraren och nozzlens ände" +msgstr "Volume of nozzle between the filament cutter and the end of the nozzle" msgid "Reduce infill retraction" msgstr "Minska ifyllnads retraktionen" @@ -5832,7 +5991,7 @@ msgid "The start position to print each part of outer wall" msgstr "Utskriftens start position för varje del av yttre väggen" msgid "Nearest" -msgstr "Närmaste" +msgstr "Nearest" msgid "Aligned" msgstr "Linjerad" @@ -5840,6 +5999,9 @@ msgstr "Linjerad" msgid "Back" msgstr "Tillbaka" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Skirt avstånd" @@ -5892,15 +6054,13 @@ msgstr "" "solida bottenlager. Den slutgiltligt genererade modellen har ingen söm" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"Record timelapse video of printing without showing the toolhead. In this " -"mode the toolhead docks near the excess chute at each layer change, and then " -"a snapshot is taken with the chamber camera. When printing finishes, a " -"timelapse video is created from all the snapshots." msgid "Temperature variation" msgstr "Temperatur variation" @@ -5929,10 +6089,10 @@ msgstr "" "skapas" msgid "normal(auto)" -msgstr "normal (auto)" +msgstr "normal(auto)" msgid "tree(auto)" -msgstr "träd(auto)" +msgstr "tree(auto)" msgid "hybrid(auto)" msgstr "hybrid(auto)" @@ -5941,7 +6101,7 @@ msgid "normal" msgstr "normal" msgid "tree" -msgstr "träd" +msgstr "tree" msgid "Support/object xy distance" msgstr "Support/objekt xy distans" @@ -6042,8 +6202,8 @@ msgid "" "interface is Concentric" msgstr "" "Linje mönster för support gränssnittsytan .Standardmönstret för olösligt " -"(material) support gränssnittet är Räta medan standardmönstret för " -"lösligt(material) stödgränssnittet är koncentriskt" +"(material) support gränssnittet är Räta medan standardmönstret för lösligt" +"(material) stödgränssnittet är koncentriskt" msgid "Base pattern spacing" msgstr "Basens mönster mellanrum" @@ -6065,12 +6225,8 @@ msgstr "Oberoende support lagerhöjd" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"Support lager använder lagerhöjd oberoende av objekt lager. Detta för att " -"stöda custom support mellanrum, detta kan orsaka extra filament byten om " -"support (materialet) är vald som en annan extruder än objektets" msgid "Threshold angle" msgstr "Gräns vinkel" @@ -6239,7 +6395,7 @@ msgid "Width of prime tower" msgstr "Prime tornets bredd" msgid "Flush into objects' infill" -msgstr "Rensa in i föremålens ifyllnad" +msgstr "Flush into objects' infill" msgid "" "Purging after filament change will be done inside objects' infills. This may " @@ -6247,32 +6403,31 @@ msgid "" "printed with transparent filament, the mixed color infill will be seen " "outside" msgstr "" -"Rensning efter filamentbyte kommer att göras inuti objektens fyllningar. " -"Detta kan minska mängden avfall och minska utskriftstiden. Om väggarna är " -"tryckta med transparent filament kommer den blandade färgfyllningen att " -"synas." +"Purging after filament change will be done inside objects' infills. This may " +"lower the amount of waste and decrease the print time. If the walls are " +"printed with transparent filament, the mixed color infill will be visible." msgid "Flush into objects' support" -msgstr "Rensa in i objektets support" +msgstr "Flush into objects' support" msgid "" "Purging after filament change will be done inside objects' support. This may " "lower the amount of waste and decrease the print time" msgstr "" -"Rensning efter filamentändring kommer att göras inuti objektens support. " -"Detta kan minska mängden avfall och minska utskriftstiden." +"Purging after filament change will be done inside objects' support. This may " +"lower the amount of waste and decrease the print time." msgid "Flush into this object" -msgstr "Rensa in i det här objektet" +msgstr "Flush into this object" msgid "" "This object will be used to purge the nozzle after a filament change to save " "filament and decrease the print time. Colours of the objects will be mixed " "as a result" msgstr "" -"Detta objekt kommer att användas för att rensa nozzlen efter ett filament " -"byte för att spara filament och minska utskriftstiden. Objektens färger " -"blandas som ett resultat" +"This object will be used to purge the nozzle after a filament change to save " +"filament and decrease the print time. Colors of the objects will be mixed as " +"a result." msgid "X-Y hole compensation" msgstr "X-Y håls kompensation" @@ -6345,10 +6500,10 @@ msgid "Arrange options: 0-disable, 1-enable, others-auto" msgstr "Placera val: 0-inaktivera, 1-aktivera, andra-auto" msgid "Convert Unit" -msgstr "Konvertera enhet" +msgstr "Convert Unit" msgid "Convert the units of model" -msgstr "Konvertera modellens enheter" +msgstr "Convert the units of model" msgid "Orient the model" msgstr "Orientera modellen" @@ -6410,9 +6565,14 @@ msgstr "Kontrollera supportens nödvändighet" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." msgstr "" -"Objekt verkar %s behöva support för att skrivas ut. Aktivera support valen." msgid "Optimizing toolpath" msgstr "Optimerar verktygsbanan" @@ -6420,13 +6580,8 @@ msgstr "Optimerar verktygsbanan" msgid "Empty layers around bottom are replaced by nearest normal layers." msgstr "Tomma lager runt botten ersätts med närmast normala lager." -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"Modellen har överlappande eller självkorsande aspekter.Reparation utförd, " -"men kontrollera resultaten eller reparera indatafilen och försöka igen." msgid "Slicing mesh" msgstr "Bereder mesh" @@ -6440,47 +6595,76 @@ msgstr "Fel i linje %1%:\n" #, c-format, boost-format msgid "Support: generate toolpath at layer %d" -msgstr "Support: generera verktygsbana vid lager %d" +msgstr "Support: generate toolpath at layer %d" msgid "Support: detect overhangs" -msgstr "Support: upptäck överhäng" +msgstr "Support: detect overhangs" msgid "Support: generate contact points" -msgstr "Support: generera kontaktpunkter" +msgstr "Support: generate contact points" msgid "Support: propagate branches" -msgstr "Support: föröka grenar" +msgstr "Support: propagate branches" msgid "Support: draw polygons" -msgstr "Support: rita polygoner" +msgstr "Support: draw polygons" msgid "Support: generate toolpath" -msgstr "Support: generera verktygsbana" +msgstr "Support: generate toolpath" #, c-format, boost-format msgid "Support: generate polygons at layer %d" -msgstr "Support: generera polygoner vid lager %d" +msgstr "Support: generate polygons at layer %d" #, c-format, boost-format msgid "Support: fix holes at layer %d" -msgstr "Support: åtgärda hål vid lager %d" +msgstr "Support: fix holes at layer %d" #, c-format, boost-format msgid "Support: propagate branches at layer %d" -msgstr "Support: föröka grenar vid lager %d" +msgstr "Support: propagate branches at layer %d" -#~ msgid "Alt + Mouse wheel" -#~ msgstr "Alt + mushjul" +#~ msgid "the 3mf is not compatible, load geometry data only!" +#~ msgstr "3mf ej kompatibel, laddar endast geometrin !" + +#~ msgid "Save configuration as:" +#~ msgstr "Spara konfigurationen som:" + +#~ msgid "Line type" +#~ msgstr "Linje typ" + +#~ msgid "Designer" +#~ msgstr "Designer" + +#~ msgid "Report" +#~ msgstr "Rapportera" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "Timelapse Wipe Tower" + +#~ msgid "Device:" +#~ msgstr "Enhet:" + +#~ msgid "Translation" +#~ msgstr "Översättning" #~ msgid "" -#~ "An object is layed over the boundary of plate.\n" -#~ "Please solve the problem by moving it totally inside or outside plate." +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." #~ msgstr "" -#~ "Ett objekt är placerad över byggplattans begränsningar.\n" -#~ "Flytta objektet så det är helt inom eller utom byggplattans begränsningar." +#~ "Objekt verkar %s behöva support för att skrivas ut. Aktivera support " +#~ "valen." -#~ msgid "Auto arrange" -#~ msgstr "Auto arrangera" +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "Modellen har överlappande eller självkorsande aspekter.Reparation utförd, " +#~ "men kontrollera resultaten eller reparera indatafilen och försöka igen." #~ msgid "" #~ "Auto orientates selected objects or all objects.If there are selected " @@ -6490,20 +6674,54 @@ msgstr "Support: föröka grenar vid lager %d" #~ "Auto placera valda objekt eller alla objekt. Om det finns valda objekt så " #~ "placeras endast dem. Alternativt så placeras alla objekt i projektet." +#~ msgid "The Config is not compatible and can not be loaded." +#~ msgstr "Ej kompatibel konfiguration; kan inte laddas." + +#~ msgid "Creating" +#~ msgstr "Creating" + +#~ msgid "Uploading" +#~ msgstr "Uploading" + +#~ msgid "Sending" +#~ msgstr "Sending" + +#~ msgid "Please fill report first." +#~ msgstr "Fyll i rapporten först." + +#~ msgid "Unable to create zip file" +#~ msgstr "Unable to create zip file" + +#~ msgid "Filaments Selection" +#~ msgstr "Filament Val" + +#~ msgid "Printer Selection" +#~ msgstr "Skrivar Val" + +#~ msgid "Auto arrange" +#~ msgstr "Auto arrangera" + +#~ msgid "Spiral mode" +#~ msgstr "Spiral läge" + +#~ msgid "Alt + Mouse wheel" +#~ msgstr "Alt + Mouse wheel" + +#~ msgid "" +#~ "An object is layed over the boundary of plate.\n" +#~ "Please solve the problem by moving it totally inside or outside plate." +#~ msgstr "" +#~ "Ett objekt är placerad över byggplattans begränsningar.\n" +#~ "Flytta objektet så det är helt inom eller utom byggplattans begränsningar." + #~ msgid "Clear all" #~ msgstr "Rensa allt" -#~ msgid "Creating" -#~ msgstr "Skapar" - #~ msgid "Ctrl + Any arrow" -#~ msgstr "Ctrl + Valfri pil" +#~ msgstr "Ctrl + Any arrow" #~ msgid "Ctrl + Left mouse button" -#~ msgstr "Ctrl + Vänster musknapp" - -#~ msgid "Debug" -#~ msgstr "Felsök" +#~ msgstr "Ctrl + Left mouse button" #~ msgid "Display printable box" #~ msgstr "Visa utskriftbar box" @@ -6521,11 +6739,11 @@ msgstr "Support: föröka grenar vid lager %d" #~ "2. The Filament presets\n" #~ "3. The Printer presets\n" #~ msgstr "" -#~ "Vill du synkronisera din personliga data från Bambu Cloud?\n" -#~ "Innehåller följande information:\n" -#~ "1. Process förinställningar\n" -#~ "2. Filament förinställningar\n" -#~ "3. Skrivare förinställningar\n" +#~ "Do you want to synchronize your personal data from Bambu Cloud? \n" +#~ "Contains the following information:\n" +#~ "1. Process presets\n" +#~ "2. Filament presets\n" +#~ "3. Printer presets\n" #~ msgid "" #~ "Don't retract when the travel is in infill area absolutely. That means " @@ -6534,26 +6752,17 @@ msgstr "Support: föröka grenar vid lager %d" #~ "Detta inaktiverar retraktion när rörelsen är helt inom ett ifyllnads " #~ "området och det inte kan läcka filament" -#~ msgid "Enter a search term" -#~ msgstr "Ange ett sökord" - -#~ msgid "Filaments Selection" -#~ msgstr "Filament Val" - -#~ msgid "Finished" -#~ msgstr "Färdig" - #~ msgid "Fix model locally" -#~ msgstr "Åtgärda modellen lokalt" +#~ msgstr "Fix model locally" #~ msgid "Fix model through cloud" -#~ msgstr "Åtgärda modellen via molnet" +#~ msgstr "Fix model through cloud" #~ msgid "Fragment Filter" #~ msgstr "Fragment Filter" #~ msgid "Fragment area" -#~ msgstr "Fragmentområde" +#~ msgstr "Fragment area" #~ msgid "Fragment filter" #~ msgstr "Fragment filter" @@ -6566,13 +6775,13 @@ msgstr "Support: föröka grenar vid lager %d" #~ "temperatur" #~ msgid "In the calibration of extrusion flow" -#~ msgstr "Vid kalibrering av extruderingsflödet" +#~ msgstr "In the calibration of extrusion flow" #~ msgid "In the calibration of laser scanner" -#~ msgstr "Vid kalibrering av laserskanner" +#~ msgstr "In the calibration of laser scanner" #~ msgid "Module" -#~ msgstr "Modul" +#~ msgstr "Module" #~ msgid "Monitoring" #~ msgstr "Övervakar" @@ -6581,19 +6790,16 @@ msgstr "Support: föröka grenar vid lager %d" #~ msgstr "Utdatafil" #~ msgid "Pause(heated bed temperature error)" -#~ msgstr "Paus (temperaturfel i byggplattan)" +#~ msgstr "Pause(heated bed temperature error)" #~ msgid "Pause(hotend temperature error)" -#~ msgstr "Paus (fel på temperaturen i hotend)" +#~ msgstr "Pause(hotend temperature error)" #~ msgid "Pause(toolhead shell off)" -#~ msgstr "Paus (verktygshuvudets skal är av)" - -#~ msgid "Please fill report first." -#~ msgstr "Fyll i rapporten först." +#~ msgstr "Pause(toolhead shell off)" #~ msgid "Please upgrade your printer first" -#~ msgstr "Uppgradera din skrivare först" +#~ msgstr "Please upgrade your printer first" #~ msgid "Position:" #~ msgstr "Position:" @@ -6602,14 +6808,11 @@ msgstr "Support: föröka grenar vid lager %d" #~ "Preview only mode:\n" #~ "The loaded file contains gcode only." #~ msgstr "" -#~ "Endast förhandsgranskningsläge:\n" -#~ "Den inlästa filen innehåller endast G-kod." +#~ "Preview only mode:\n" +#~ "The loaded file contains G-code only." #~ msgid "Preview only mode for gcode file." -#~ msgstr "Endast förhandsgranskningsläge för G-kod." - -#~ msgid "Printer Selection" -#~ msgstr "Skrivar Val" +#~ msgstr "Preview only mode for G-code file." #~ msgid "" #~ "Push new filament \n" @@ -6618,14 +6821,11 @@ msgstr "Support: föröka grenar vid lager %d" #~ "Mata nytt filament\n" #~ "till extrudern" -#~ msgid "Sending" -#~ msgstr "Skickar" - #~ msgid "Shift + Any arrow" -#~ msgstr "Skift+valfri pil" +#~ msgstr "Shift + Any arrow" #~ msgid "Shift + Mouse wheel" -#~ msgstr "Shift+mushjulet" +#~ msgstr "Shift + Mouse wheel" #~ msgid "Show Model Mesh(TODO)" #~ msgstr "Visa Modell Mesh(TODO)" @@ -6636,38 +6836,19 @@ msgstr "Support: föröka grenar vid lager %d" #~ msgid "Show Printable Box(TODO)" #~ msgstr "Visa Utskriftbar Box(TODO)" -#~ msgid "Spiral mode" -#~ msgstr "Spiral läge" - #~ msgid "Successfully sent.Will automatically jump to the device page in %s s" #~ msgstr "" -#~ "Framgångsrikt skickat. Kommer automatiskt att hoppa till enhetssidan om " -#~ "%s s" +#~ "Successfully sent. Will automatically jump to the device page in %s s" #~ msgid "Swith cloud environment, Please login again!" #~ msgstr "Byte av moln miljö, Logga in igen!" -#~ msgid "The Config is not compatible and can not be loaded." -#~ msgstr "Ej kompatibel konfiguration; kan inte laddas." - #~ msgid "" #~ "The firmware versions of printer and AMS are too low.Please update to the " #~ "latest version before sending the print job" #~ msgstr "" -#~ "Programvarans version av skrivare och AMS är för låga. Uppdatera till den " -#~ "senaste versionen innan du skickar utskriftsjobbet" - -#~ msgid "Unable to create zip file" -#~ msgstr "Det gick inte att skapa zip-fil" - -#~ msgid "Uploading" -#~ msgstr "Laddar upp" +#~ "The firmware versions of the printer and AMS are too low. Please update " +#~ "them to the latest version before sending any print jobs." #~ msgid "User pause" -#~ msgstr "Användarpaus" - -#~ msgid "Waiting" -#~ msgstr "Väntar" - -#~ msgid "the 3mf is not compatible, load geometry data only!" -#~ msgstr "3mf ej kompatibel, laddar endast geometrin !" +#~ msgstr "User pause" diff --git a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po index 66a940c724..c7533d0ceb 100644 --- a/bbl/i18n/zh_cn/BambuStudio_zh_CN.po +++ b/bbl/i18n/zh_cn/BambuStudio_zh_CN.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-12 15:19+0800\n" -"PO-Revision-Date: 2022-08-07 21:57+0800\n" +"POT-Creation-Date: 2022-09-01 09:20+0800\n" +"PO-Revision-Date: 2022-08-05 11:49+0800\n" "Last-Translator: Jiang Yue \n" "Language-Team: \n" "Language: zh_CN\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.0.1\n" +"X-Generator: Poedit 3.1\n" msgid "Supports Painting" msgstr "支撑绘制" @@ -57,7 +57,7 @@ msgid "Perform" msgstr "执行" msgid "Gap area" -msgstr "" +msgstr "间隙面积" msgid "Set pen size" msgstr "设置画笔大小" @@ -366,6 +366,21 @@ msgstr "推出Z缝绘制" msgid "Paint-on seam editing" msgstr "" +msgid "Text shape" +msgstr "文本形状" + +msgid "Font" +msgstr "字体" + +msgid "Thickness" +msgstr "厚度" + +msgid "Input text" +msgstr "输入文本" + +msgid "Add" +msgstr "添加" + msgid "Notice" msgstr "通知" @@ -440,7 +455,7 @@ msgstr "访问码不正确" #, c-format, boost-format msgid "Connect %s failed! [SN:%s, code=%s]" -msgstr "连接 %s 失败 [SN:%s, code=%s]" +msgstr "连接 %s 失败。[SN:%s, code=%s]" msgid "" "BambuStudio configuration file may be corrupted and is not abled to be " @@ -634,9 +649,6 @@ msgstr "圆柱体" msgid "Cone" msgstr "锥体" -msgid "Timelapse Wipe Tower" -msgstr "延时摄影擦料塔" - msgid "Add settings" msgstr "添加设置" @@ -1100,7 +1112,7 @@ msgid "" msgstr "自动摆放失败,处理对象几何数据时遇到异常。" msgid "Arranging" -msgstr "自动摆盘中" +msgstr "自动摆放" msgid "Arranging canceled." msgstr "已取消自动摆放。" @@ -1209,6 +1221,9 @@ msgstr "服务不可用" msgid "Unkown Error." msgstr "未知错误" +msgid "Please Fill Task Report." +msgstr "请填写打印报告" + msgid "Sending print configuration" msgstr "正在发送打印配置" @@ -1334,6 +1349,18 @@ msgid "" "Note: Only the AMS slots loaded with the same material type can be selected." msgstr "仅允许选择放入同种材质耗材丝的AMS槽位" +msgid "Enable AMS" +msgstr "" + +msgid "Print with filaments in the AMS" +msgstr "" + +msgid "Disable AMS" +msgstr "" + +msgid "Print with the filament mounted on the back of chassis" +msgstr "" + msgid "Insertion update" msgstr "插入料时更新" @@ -1843,9 +1870,6 @@ msgstr "时间" msgid "Display" msgstr "显示" -msgid "Line type" -msgstr "走线类型" - msgid "Layer Height (mm)" msgstr "层高(mm)" @@ -1933,6 +1957,9 @@ msgstr "总预估" msgid "Normal mode" msgstr "普通模式" +msgid "Cost" +msgstr "成本" + msgid "Prepare time" msgstr "准备时间" @@ -1988,9 +2015,6 @@ msgstr "允许同一盘中包含多种材料" msgid "Avoid extrusion calibration region" msgstr "避开挤出标定区域" -msgid "Add" -msgstr "添加" - msgid "Add plate" msgstr "添加新盘" @@ -2104,6 +2128,15 @@ msgstr "" msgid "Invalid input." msgstr "" +msgid "Enter a search term" +msgstr "输入搜索内容" + +msgid "Online" +msgstr "在线" + +msgid "Offline" +msgstr "离线" + msgid "Application is closing" msgstr "正在关闭应用程序" @@ -2125,6 +2158,9 @@ msgstr "设备" msgid "Project" msgstr "项目" +msgid "Debug" +msgstr "调试" + msgid "Slice" msgstr "切片" @@ -2162,6 +2198,12 @@ msgstr "检查新版本" msgid "&About %s" msgstr "关于 %s" +msgid "Show Log" +msgstr "" + +msgid "Open Network Test" +msgstr "" + msgid "Default View" msgstr "默认视图" @@ -2233,9 +2275,24 @@ msgstr "导入 3MF/STL/STEP/OBJ/AMF" msgid "Load a model" msgstr "加载模型" +msgid "Import Configs" +msgstr "导入预设" + +msgid "Load configs" +msgstr "" + +msgid "Import" +msgstr "导入" + msgid "Export all objects as STL" msgstr "导出所有对象为STL" +msgid "Export Generic 3MF" +msgstr "导出通用 3MF" + +msgid "Export 3mf file without using some 3mf-extensions" +msgstr "导出不含 3mf 扩展的 3mf 文件" + msgid "Export current Sliced file" msgstr "导出当前已切片的文件" @@ -2245,6 +2302,12 @@ msgstr "导出 G-code" msgid "Export current plate as G-code" msgstr "导出当前盘的G-code" +msgid "Export &Configs" +msgstr "导出预设" + +msgid "Export current configuration to files" +msgstr "导出当前选择的预设" + msgid "Export" msgstr "导出" @@ -2311,27 +2374,12 @@ msgstr "使用正交视角" msgid "Preferences" msgstr "偏好设置" -msgid "About" -msgstr "" - msgid "View" msgstr "视图" msgid "Help" msgstr "帮助" -msgid "&File" -msgstr "" - -msgid "&Edit" -msgstr "" - -msgid "&View" -msgstr "" - -msgid "&Help" -msgstr "" - msgid "&Open G-code" msgstr "打开G-code" @@ -2363,8 +2411,46 @@ msgstr "" msgid "Quit %s" msgstr "" -msgid "Save configuration as:" -msgstr "预设另存为:" +msgid "&File" +msgstr "" + +msgid "&View" +msgstr "" + +msgid "&Help" +msgstr "" + +msgid "Overwrite file" +msgstr "覆盖文件" + +msgid "Yes to All" +msgstr "全是" + +msgid "No to All" +msgstr "全否" + +msgid "Choose a directory" +msgstr "选择目录" + +#, c-format, boost-format +msgid "There is %d config exported. (Only non-system configs)" +msgid_plural "There are %d configs exported. (Only non-system configs)" +msgstr[0] "共导出 %d 组预设(仅包含当前使用的非系统的预设)" + +msgid "Export result" +msgstr "导出结果" + +msgid "Select profile to load:" +msgstr "" + +#, c-format, boost-format +msgid "There is %d config imported. (Only non-system and compatible configs)" +msgid_plural "" +"There are %d configs imported. (Only non-system and compatible configs)" +msgstr[0] "共导入 %d 组预设(仅包含非系统且与当前配置兼容的预设)" + +msgid "Import result" +msgstr "导入结果" msgid "File is missing" msgstr "文件丢失" @@ -2414,47 +2500,93 @@ msgstr "正在播放中……" msgid "Load failed [%d]!" msgstr "加载失败 [%d]!" -msgid "3Dconnexion settings" -msgstr "3Dconnexion设置" +msgid "Year" +msgstr "年" -msgid "Device:" -msgstr "设备:" +msgid "Month" +msgstr "月" + +msgid "All Files" +msgstr "所有文件" + +msgid "Video" +msgstr "录像" + +msgid "Download" +msgstr "下载" + +msgid "Management" +msgstr "管理" + +msgid "No printers." +msgstr "未选择打印机" + +msgid "Connecting..." +msgstr "连接中..." + +#, c-format, boost-format +msgid "Connect failed [%d]!" +msgstr "连接失败 [%d]!" + +msgid "Loading file list..." +msgstr "加载文件列表..." + +msgid "No files" +msgstr "文件列表为空" + +msgid "Choose save directory" +msgstr "选择保存目录" + +msgid "Waiting" +msgstr "等待中" + +msgid "Retry" +msgstr "重试" + +msgid "Failed" +msgstr "失败" + +msgid "Open" +msgstr "打开" + +msgid "Finished" +msgstr "完成" msgid "Speed:" msgstr "速度:" -msgid "Translation" -msgstr "翻译" - -msgid "Zoom" -msgstr "视角缩放" - msgid "Deadzone:" msgstr "死区:" msgid "Options:" msgstr "选项:" +msgid "Zoom" +msgstr "视角缩放" + +msgid "Translation/Zoom" +msgstr "平移/缩放" + +msgid "3Dconnexion settings" +msgstr "3Dconnexion设置" + msgid "Swap Y/Z axes" msgstr "交换Y/Z轴" msgid "Camera" msgstr "摄像机" -msgid "Video" -msgstr "录像" - msgid "Printing Progress" msgstr "打印进度" -msgid "Report" -msgstr "报告" +msgid "Resume" +msgstr "继续" msgid "Stop" msgstr "停止" -msgid "0%" -msgstr "0%" +msgid "0" +msgstr "" msgid "Clean" msgstr "清除" @@ -2492,9 +2624,6 @@ msgstr "项目切片" msgid "Downloading..." msgstr "下载中..." -msgid "Resume" -msgstr "继续" - msgid "Silent" msgstr "静音" @@ -2525,9 +2654,6 @@ msgstr "无法连接服务器" msgid "Failed to connect to the printer" msgstr "无法连接打印机" -msgid "Connecting..." -msgstr "连接中..." - msgid "OK" msgstr "确认" @@ -2561,9 +2687,6 @@ msgstr "%s 信息" msgid "%s information" msgstr "%s 信息" -msgid "Download" -msgstr "下载" - msgid "Skip" msgstr "跳过" @@ -2750,9 +2873,6 @@ msgstr "耗材丝消耗重量(g)" msgid "Used Materials" msgstr "材料消耗" -msgid "Cost" -msgstr "成本" - msgid "Estimated time" msgstr "预估打印时间" @@ -2786,10 +2906,10 @@ msgid "Loading file: %s" msgstr "加载文件:%s" msgid "The 3mf is not from Bambu Lab, load geometry data only." -msgstr "该3mf文件不兼容,仅加载几何数据。" +msgstr "" msgid "Load 3mf" -msgstr "加载3mf" +msgstr "" msgid "The Config can not be loaded." msgstr "" @@ -2809,6 +2929,12 @@ msgstr "建议升级您的软件版本。\n" msgid "Newer 3mf version" msgstr "较新的3mf版本" +#, c-format, boost-format +msgid "" +"The 3mf's version %s is newer than %s's version %s, Suggest to upgrade your " +"software.\n" +msgstr "" + msgid "The 3mf is not compatible, load geometry data only!" msgstr "" @@ -3329,12 +3455,6 @@ msgstr "为“%1%”,添加“%2%”为一个新预设" msgid "Simply switch to \"%1%\"" msgstr "直接切换到“%1%”" -msgid "Online" -msgstr "在线" - -msgid "Offline" -msgstr "离线" - msgid "My Device" msgstr "我的设备" @@ -3439,7 +3559,9 @@ msgstr "" msgid "" "The printer firmware only supports sequential mapping of filament => AMS " "slot." -msgstr "打印机固件版本仅支持材料=>AMS槽位的顺序映射。" +msgstr "" +"已自动建立 \"耗材丝列表=>AMS槽位\" 的映射关系。 可点击上方具体的耗材丝手动设" +"置其所对应的AMS槽位" msgid "Preparing print job" msgstr "正在准备打印任务" @@ -3479,6 +3601,15 @@ msgstr "保存当前 %s" msgid "Delete this preset" msgstr "删除此预设" +msgid "" +"Prime tower is required by timeplase. Are you sure you want to disable both " +"of them?" +msgstr "延时摄影需要使用擦拭塔,是否同时禁用?" + +msgid "" +"Prime tower is required by timelapse. Do you want to enable both of them?" +msgstr "延时摄影需要使用擦拭塔,是否同时启用?" + msgid "" "When recording timelapse without toolhead, it is recommended to add a " "\"Timelapse Wipe Tower\" \n" @@ -3611,6 +3742,14 @@ msgid "" "filament does not support to print on the High Temp Plate" msgstr "安装高温打印热床时的热床温度。0值表示这个耗材丝不支持高温打印热床" +msgid "Textured PEI Plate" +msgstr "纹理PEI热床" + +msgid "" +"Bed temperature when Textured PEI Plate is installed. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "安装纹理PEI热床时的热床温度。0值表示这个耗材丝不支持纹理PEI热床" + msgid "Volumetric speed limitation" msgstr "体积速度限制" @@ -3824,6 +3963,12 @@ msgstr "常规" msgid "Capabilities" msgstr "能力" +msgid "Show all presets (including incompatible)" +msgstr "显示所有预设(包括不兼容的)" + +msgid "Add File" +msgstr "" + msgid "Set as cover" msgstr "设置为封面" @@ -3849,8 +3994,8 @@ msgstr "组装指南" msgid "Choose files" msgstr "选择文件" -msgid "Designer" -msgstr "设计师" +msgid "Author" +msgstr "作者" msgid "Model Name" msgstr "模型名字" @@ -3952,6 +4097,9 @@ msgstr "复制到剪贴板" msgid "Paste from clipboard" msgstr "从剪切板粘贴" +msgid "Show/Hide 3Dconnexion devices settings dialog" +msgstr "显示/隐藏 3Dconnexion设备的设置对话框" + msgid "Show keyboard shortcuts list" msgstr "显示键盘快捷键列表" @@ -4060,16 +4208,16 @@ msgid "Select all objects" msgstr "选择所有对象" msgid "Gizmo move" -msgstr "移动工具" +msgstr "线框移动" msgid "Gizmo scale" -msgstr "缩放工具" +msgstr "线框缩放" msgid "Gizmo rotate" -msgstr "旋转工具" +msgstr "旋转物件" msgid "Gizmo cut" -msgstr "剪切工具" +msgstr "剪切物件" msgid "Gizmo Place face on bed" msgstr "选择底面" @@ -4078,7 +4226,7 @@ msgid "Gizmo SLA support points" msgstr "SLA支撑点" msgid "Gizmo FDM paint-on seam" -msgstr "FDM绘制接缝" +msgstr "FDM涂装接缝" msgid "Plater" msgstr "准备" @@ -4092,6 +4240,9 @@ msgstr "⌘+鼠标滚轮" msgid "Support/Color Painting: adjust pen radius" msgstr "支撑/颜色绘制:调节画笔半径" +msgid "⌥+Mouse wheel" +msgstr "⌥+鼠标滚轮" + msgid "Support/Color Painting: adjust section position" msgstr "支撑/色彩绘制:调节剖面位置" @@ -4577,6 +4728,11 @@ msgid "" "filament does not support to print on the High Temp Plate" msgstr "非首层热床温度。0值表示这个耗材丝不支持高温打印热床" +msgid "" +"Bed temperature for layers except the initial one. Value 0 means the " +"filament does not support to print on the Textured PEI Plate" +msgstr "非首层热床温度。0值表示这个耗材丝不支持纹理PEI热床" + msgid "Initial layer" msgstr "首层" @@ -4598,6 +4754,11 @@ msgid "" "support to print on the High Temp Plate" msgstr "首层热床温度。0值表示这个耗材丝不支持高温打印热床" +msgid "" +"Bed temperature of the initial layer. Value 0 means the filament does not " +"support to print on the Textured PEI Plate" +msgstr "首层热床温度。0值表示这个耗材丝不支持纹理PEI热床" + msgid "Bed types supported by the printer" msgstr "打印机所支持的热床类型" @@ -5623,6 +5784,9 @@ msgstr "对齐" msgid "Back" msgstr "背面" +msgid "Random" +msgstr "" + msgid "Skirt distance" msgstr "Skirt距离" @@ -5670,13 +5834,17 @@ msgstr "" "印。最后生成的打印件没有接缝。" msgid "" -"Record timelapse video of printing without showing toolhead. In this mode " -"the toolhead docks near the excess chute at each layer change, and then a " -"snapshot is taken with the chamber camera. When printing finishes a " -"timelapse video is composed of all the snapshots." +"If enabled, a timelapse video will be generated for each print. After each " +"layer is printed, the toolhead will move to the excess chute, and then a " +"snapshot is taken with the chamber camera. All of these snapshots are " +"composed into a timelapse video when printing completes. Since the melt " +"filament may leak from the nozzle during the process of taking a snapshot, " +"prime tower is required for nozzle priming." msgstr "" -"录制打印的延时摄影视频,但不显示工具头。在该模式下,工具头会在换层时停靠在吐" -"料槽附近,然后用内置相机拍摄快照。打印完成后,把所有快照组成延时摄影视频。" +"如果启用延时摄影,将在每次打印时生成延时摄影视频。打印完每层后,工具头将移动" +"到吐料槽,然后用内置相机拍摄快照。打印完成后,所有这些快照会组合成一个延时视" +"频。由于在拍摄快照的过程中熔丝可能会从喷嘴中泄漏,因此需要使用擦拭塔进行喷嘴" +"擦拭。" msgid "Temperature variation" msgstr "软化温度" @@ -5829,11 +5997,8 @@ msgstr "支撑独立层高" msgid "" "Support layer uses layer height independent with object layer. This is to " -"support custom support gap,but may cause extra filament switches if support " -"is specified as different extruder with object" +"support customizing z-gap and save print time." msgstr "" -"支撑层使用独立于对象层的层高。这是为了支持自定义间隙,但是会在支撑和对象使用" -"不同耗材丝的时候造成额外的耗材丝切换次数。" msgid "Threshold angle" msgstr "阈值角度" @@ -6152,8 +6317,14 @@ msgstr "正在检查支撑必要性" #, c-format, boost-format msgid "" -"It seems object %s needs support to print. Please enable support generation." -msgstr "对象“%s”可能需要添加支撑才能打印。建议开启支撑生成。" +"It seems object %s has completely floating regions. Please re-orient the " +"object or enable support generation." +msgstr "" + +#, c-format, boost-format +msgid "" +"It seems object %s has large overhangs. Please enable support generation." +msgstr "" msgid "Optimizing toolpath" msgstr "正在优化走线" @@ -6161,13 +6332,8 @@ msgstr "正在优化走线" msgid "Empty layers around bottom are replaced by nearest normal layers." msgstr "底部出现空层,已被最近的正常层替换。" -msgid "" -"The model has overlapping or self-intersecting facets. I tried to repair it, " -"however you might want to check the results or repair the input file and " -"retry." +msgid "The model has too many empty layers." msgstr "" -"模型有重叠或自交的面片。已尝试修复,请检查结果是否正确,或修复输入文件后重" -"试。" msgid "Slicing mesh" msgstr "正在切片网格" @@ -6216,6 +6382,46 @@ msgstr "支撑:正在生长层%d的树枝" #~ msgid "the 3mf is not compatible, load geometry data only!" #~ msgstr "该3mf文件不兼容,仅加载几何数据!" +#~ msgid "Save configuration as:" +#~ msgstr "预设另存为:" + +#~ msgid "Line type" +#~ msgstr "走线类型" + +#~ msgid "Abort" +#~ msgstr "终止" + +#~ msgid "Designer" +#~ msgstr "设计师" + +#~ msgid "Report" +#~ msgstr "报告" + +#~ msgid "0%" +#~ msgstr "0%" + +#~ msgid "Timelapse Wipe Tower" +#~ msgstr "延时摄影擦料塔" + +#~ msgid "Device:" +#~ msgstr "设备:" + +#~ msgid "Translation" +#~ msgstr "翻译" + +#~ msgid "" +#~ "It seems object %s needs support to print. Please enable support " +#~ "generation." +#~ msgstr "对象“%s”可能需要添加支撑才能打印。建议开启支撑生成。" + +#~ msgid "" +#~ "The model has overlapping or self-intersecting facets. I tried to repair " +#~ "it, however you might want to check the results or repair the input file " +#~ "and retry." +#~ msgstr "" +#~ "模型有重叠或自交的面片。已尝试修复,请检查结果是否正确,或修复输入文件后重" +#~ "试。" + #~ msgid "" #~ "Auto orientates selected objects or all objects.If there are selected " #~ "objects, it just orientates the selected ones.Otherwise, it will " @@ -6230,9 +6436,6 @@ msgstr "支撑:正在生长层%d的树枝" #~ msgid "default value" #~ msgstr "默认值" -#~ msgid "Auto arrange" -#~ msgstr "自动摆盘" - #~ msgid "" #~ "The filament index exceeds the AMS's slot count and cannot send the print " #~ "job." @@ -6246,53 +6449,52 @@ msgstr "支撑:正在生长层%d的树枝" #~ msgid "Downloading Bambu Network plug-in" #~ msgstr "正在下载Bambu网络插件" -#~ msgid "Filaments Selection" -#~ msgstr "材料选择" - -#~ msgid "Printer Selection" -#~ msgstr "打印机选择" - -#~ msgid "Spiral mode" -#~ msgstr "旋转模式" - -#~ msgid "Fragment area" -#~ msgstr "碎片面积阈值" - -#~ msgid "Clear all" -#~ msgstr "清除所有" - -#~ msgid "Connect %s[SN:%s] failed!" -#~ msgstr "连接 %s[SN:%s]失败." - -#~ msgid "Printer firmware does not support material = >ams slot mapping." -#~ msgstr "打印机固件不支持材料=>AMS槽位映射" - #~ msgid "Creating" #~ msgstr "正在创建" #~ msgid "Uploading" #~ msgstr "正在上传" -#~ msgid "Waiting" -#~ msgstr "等待中" - #~ msgid "Sending" #~ msgstr "发送中" -#~ msgid "Finished" -#~ msgstr "完成" - #~ msgid "Please fill report first." #~ msgstr "请先填写报告。" #~ msgid "Unable to create zip file" #~ msgstr "无法创建zip压缩文件" -#~ msgid "Enter a search term" -#~ msgstr "输入搜索内容" +#~ msgid "Printer firmware does not support material = >ams slot mapping." +#~ msgstr "打印机固件不支持材料=>AMS槽位映射" -#~ msgid "Debug" -#~ msgstr "调试" +#~ msgid "Filaments Selection" +#~ msgstr "材料选择" + +#~ msgid "Printer Selection" +#~ msgstr "打印机选择" + +#~ msgid "Auto arrange" +#~ msgstr "自动摆盘" + +#~ msgid "Spiral mode" +#~ msgstr "旋转模式" + +#~ msgid "" +#~ "Unprintable area in XY plane. For example, X1 Series printers use the " +#~ "front left corner to cut filament in multi-material printing. The area is " +#~ "expressed as polygon by points in following format: \"XxY, XxY, ...\"" +#~ msgstr "" +#~ "XY平面上的不可打印区域。例如,X1系列打印机在换料过程中,会使用左前角区域来" +#~ "切断耗材丝。这个多边形区域由以下格式的点表示:“XxY,XxY,…”" + +#~ msgid "Connect %s[SN:%s] failed!" +#~ msgstr "连接 %s[SN:%s]失败." + +#~ msgid "Fragment area" +#~ msgstr "碎片面积阈值" + +#~ msgid "Clear all" +#~ msgstr "清除所有" #~ msgid "Monitoring" #~ msgstr "实时视频" @@ -6404,9 +6606,6 @@ msgstr "支撑:正在生长层%d的树枝" #~ "the oozing can't been seen" #~ msgstr "当完全在填充区域内部空驶时不会抽,即便渗出滴料也是不可见的。" -#~ msgid "⌥+Mouse wheel" -#~ msgstr "⌥+鼠标滚轮" - #~ msgid "sdfsadf Any arrow" #~ msgstr "方向键" @@ -7372,9 +7571,6 @@ msgstr "支撑:正在生长层%d的树枝" #~ msgid "Unable to get printer status" #~ msgstr "无法获取打印机状态" -#~ msgid "Abort" -#~ msgstr "终止" - #~ msgid "Tip: Click the button to edit your filament" #~ msgstr "提示:点击此按钮以编辑耗材丝" @@ -7426,9 +7622,6 @@ msgstr "支撑:正在生长层%d的树枝" #~ msgid "Current bed type do not support filament " #~ msgstr "当前热床不支持耗材丝" -#~ msgid "Open" -#~ msgstr "打开" - #~ msgid "Load from disk" #~ msgstr "从硬盘加载" @@ -9348,9 +9541,6 @@ msgstr "支撑:正在生长层%d的树枝" #~ "\n" #~ "是否导入这个配置?" -#~ msgid "Import" -#~ msgstr "导入" - #~ msgid "Don't import" #~ msgstr "不导入" diff --git a/resources/config.json b/resources/config.json new file mode 100644 index 0000000000..767235566b --- /dev/null +++ b/resources/config.json @@ -0,0 +1,14 @@ +{ + "printers": [ + { + "display_name": "Bambu Lab X1", + "model_id": "BL-P002", + "printer_type": "3DPrinter-X1" + }, + { + "display_name": "Bambu Lab X1 Carbon", + "model_id": "BL-P001", + "printer_type": "3DPrinter-X1-Carbon" + } + ] +} diff --git a/resources/i18n/de/BambuStudio.mo b/resources/i18n/de/BambuStudio.mo index c954408e1e..13bbb7d580 100644 Binary files a/resources/i18n/de/BambuStudio.mo and b/resources/i18n/de/BambuStudio.mo differ diff --git a/resources/i18n/en/BambuStudio.mo b/resources/i18n/en/BambuStudio.mo index af36af44df..2173f8a0df 100644 Binary files a/resources/i18n/en/BambuStudio.mo and b/resources/i18n/en/BambuStudio.mo differ diff --git a/resources/i18n/es/BambuStudio.mo b/resources/i18n/es/BambuStudio.mo index 5266e7ac15..98293b9962 100644 Binary files a/resources/i18n/es/BambuStudio.mo and b/resources/i18n/es/BambuStudio.mo differ diff --git a/resources/i18n/fr/BambuStudio.mo b/resources/i18n/fr/BambuStudio.mo index fa03152dc9..f9283dd05a 100644 Binary files a/resources/i18n/fr/BambuStudio.mo and b/resources/i18n/fr/BambuStudio.mo differ diff --git a/resources/i18n/hu/BambuStudio.mo b/resources/i18n/hu/BambuStudio.mo index 712afaed1b..1cba109af0 100644 Binary files a/resources/i18n/hu/BambuStudio.mo and b/resources/i18n/hu/BambuStudio.mo differ diff --git a/resources/i18n/nl/BambuStudio.mo b/resources/i18n/nl/BambuStudio.mo index 4a0f6d9e73..a8a112f11a 100644 Binary files a/resources/i18n/nl/BambuStudio.mo and b/resources/i18n/nl/BambuStudio.mo differ diff --git a/resources/i18n/sv/BambuStudio.mo b/resources/i18n/sv/BambuStudio.mo index 7c77ba48cf..b596012bee 100644 Binary files a/resources/i18n/sv/BambuStudio.mo and b/resources/i18n/sv/BambuStudio.mo differ diff --git a/resources/i18n/zh_cn/BambuStudio.mo b/resources/i18n/zh_cn/BambuStudio.mo index c5a2d5dab4..4d6f1251a1 100644 Binary files a/resources/i18n/zh_cn/BambuStudio.mo and b/resources/i18n/zh_cn/BambuStudio.mo differ diff --git a/resources/images/disable_ams_demo_icon.svg b/resources/images/disable_ams_demo_icon.svg new file mode 100644 index 0000000000..25022741c3 --- /dev/null +++ b/resources/images/disable_ams_demo_icon.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/enable_ams.svg b/resources/images/enable_ams.svg new file mode 100644 index 0000000000..22c049e776 --- /dev/null +++ b/resources/images/enable_ams.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/menu_add_negative.svg b/resources/images/menu_add_negative.svg index f1cc3659cf..eabe44e001 100644 --- a/resources/images/menu_add_negative.svg +++ b/resources/images/menu_add_negative.svg @@ -1,4 +1,4 @@ - - + + diff --git a/resources/images/menu_export_config.svg b/resources/images/menu_export_config.svg new file mode 100644 index 0000000000..1f09490f1a --- /dev/null +++ b/resources/images/menu_export_config.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/menu_support_blocker.svg b/resources/images/menu_support_blocker.svg index 76b548b9b7..e3ceb94082 100644 --- a/resources/images/menu_support_blocker.svg +++ b/resources/images/menu_support_blocker.svg @@ -1,12 +1,22 @@ - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/menu_support_enforcer.svg b/resources/images/menu_support_enforcer.svg index 89c2aab252..16e9099bc9 100644 --- a/resources/images/menu_support_enforcer.svg +++ b/resources/images/menu_support_enforcer.svg @@ -1,4 +1,4 @@ - - + + diff --git a/resources/images/placeholder_excel.svg b/resources/images/placeholder_excel.svg index bbee00a8ba..15b84b4b90 100644 --- a/resources/images/placeholder_excel.svg +++ b/resources/images/placeholder_excel.svg @@ -1,19 +1,9 @@ - - - Layer 1 - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + diff --git a/resources/images/placeholder_pdf.svg b/resources/images/placeholder_pdf.svg index 683ff95642..158444c430 100644 --- a/resources/images/placeholder_pdf.svg +++ b/resources/images/placeholder_pdf.svg @@ -1,15 +1,9 @@ - - - Layer 1 - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + diff --git a/resources/images/placeholder_txt.svg b/resources/images/placeholder_txt.svg index 7c47a9cadc..dcad481d9d 100644 --- a/resources/images/placeholder_txt.svg +++ b/resources/images/placeholder_txt.svg @@ -1,17 +1,13 @@ - - - Layer 1 - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + diff --git a/resources/images/print_control_pause.svg b/resources/images/print_control_pause.svg new file mode 100644 index 0000000000..7625ec8020 --- /dev/null +++ b/resources/images/print_control_pause.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/print_control_pause_disable.svg b/resources/images/print_control_pause_disable.svg new file mode 100644 index 0000000000..2e1d511765 --- /dev/null +++ b/resources/images/print_control_pause_disable.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/print_control_pause_hover.svg b/resources/images/print_control_pause_hover.svg new file mode 100644 index 0000000000..27be647ccb --- /dev/null +++ b/resources/images/print_control_pause_hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/print_control_resume.svg b/resources/images/print_control_resume.svg new file mode 100644 index 0000000000..292da3d3b3 --- /dev/null +++ b/resources/images/print_control_resume.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/print_control_resume_disable.svg b/resources/images/print_control_resume_disable.svg new file mode 100644 index 0000000000..fb1ad8adb2 --- /dev/null +++ b/resources/images/print_control_resume_disable.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/print_control_resume_hover.svg b/resources/images/print_control_resume_hover.svg new file mode 100644 index 0000000000..bd25d224d8 --- /dev/null +++ b/resources/images/print_control_resume_hover.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/images/print_control_stop.svg b/resources/images/print_control_stop.svg new file mode 100644 index 0000000000..8fd730fc63 --- /dev/null +++ b/resources/images/print_control_stop.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/print_control_stop_disable.svg b/resources/images/print_control_stop_disable.svg new file mode 100644 index 0000000000..3d2a99afaf --- /dev/null +++ b/resources/images/print_control_stop_disable.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/print_control_stop_hover.svg b/resources/images/print_control_stop_hover.svg new file mode 100644 index 0000000000..b75770370c --- /dev/null +++ b/resources/images/print_control_stop_hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/print_info_time.svg b/resources/images/print_info_time.svg new file mode 100644 index 0000000000..63af49a7fc --- /dev/null +++ b/resources/images/print_info_time.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/print_info_weight.svg b/resources/images/print_info_weight.svg new file mode 100644 index 0000000000..e4deb77c39 --- /dev/null +++ b/resources/images/print_info_weight.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/images/recording_off_hover.svg b/resources/images/recording_off_hover.svg index 729484ea2d..0f59b4deee 100644 --- a/resources/images/recording_off_hover.svg +++ b/resources/images/recording_off_hover.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/resources/images/recording_off_normal.svg b/resources/images/recording_off_normal.svg index 1a4d357621..3ba0450e8b 100644 --- a/resources/images/recording_off_normal.svg +++ b/resources/images/recording_off_normal.svg @@ -1,6 +1,6 @@ - - - - - + + + + + diff --git a/resources/images/recording_on_hover.svg b/resources/images/recording_on_hover.svg index c2cd0833a0..45a46c0fdf 100644 --- a/resources/images/recording_on_hover.svg +++ b/resources/images/recording_on_hover.svg @@ -1,7 +1,6 @@ - - - - - - + + + + + diff --git a/resources/images/recording_on_normal.svg b/resources/images/recording_on_normal.svg index f1984fbf19..b75b916e95 100644 --- a/resources/images/recording_on_normal.svg +++ b/resources/images/recording_on_normal.svg @@ -1,7 +1,6 @@ - - - - - - + + + + + diff --git a/resources/images/sdcard_state_off.svg b/resources/images/sdcard_state_off.svg index 5e9fa83a88..97b4866def 100644 --- a/resources/images/sdcard_state_off.svg +++ b/resources/images/sdcard_state_off.svg @@ -1,20 +1,10 @@ - - - - - - - - Layer 1 - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + diff --git a/resources/images/sdcard_state_on.svg b/resources/images/sdcard_state_on.svg index c82fdd317c..deef48a11b 100644 --- a/resources/images/sdcard_state_on.svg +++ b/resources/images/sdcard_state_on.svg @@ -1,17 +1,7 @@ - - - - - - - - Layer 1 - - - - - - - - - \ No newline at end of file + + + + + + + diff --git a/resources/images/seperator.svg b/resources/images/seperator.svg index d8313899c7..c053a0aa4a 100644 --- a/resources/images/seperator.svg +++ b/resources/images/seperator.svg @@ -1,69 +1,3 @@ - - - - - - - - - - - - - + + diff --git a/resources/images/text_B.svg b/resources/images/text_B.svg new file mode 100644 index 0000000000..c792b4be4d --- /dev/null +++ b/resources/images/text_B.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/text_B_hover.svg b/resources/images/text_B_hover.svg new file mode 100644 index 0000000000..2242afa388 --- /dev/null +++ b/resources/images/text_B_hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/text_B_press.svg b/resources/images/text_B_press.svg new file mode 100644 index 0000000000..5333b0ef6f --- /dev/null +++ b/resources/images/text_B_press.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/text_T.svg b/resources/images/text_T.svg new file mode 100644 index 0000000000..fa5cb783b3 --- /dev/null +++ b/resources/images/text_T.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/text_T_hover.svg b/resources/images/text_T_hover.svg new file mode 100644 index 0000000000..2a7880cee0 --- /dev/null +++ b/resources/images/text_T_hover.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/resources/images/text_T_press.svg b/resources/images/text_T_press.svg new file mode 100644 index 0000000000..9d1da57e2b --- /dev/null +++ b/resources/images/text_T_press.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/resources/images/timelapse_off_hover.svg b/resources/images/timelapse_off_hover.svg index 583bfd0469..d21e599c2e 100644 --- a/resources/images/timelapse_off_hover.svg +++ b/resources/images/timelapse_off_hover.svg @@ -1,12 +1,15 @@ - - - - - + + + + + + + + - - + + diff --git a/resources/images/timelapse_off_normal.svg b/resources/images/timelapse_off_normal.svg index b8f0505d93..ec30c1b720 100644 --- a/resources/images/timelapse_off_normal.svg +++ b/resources/images/timelapse_off_normal.svg @@ -1,12 +1,15 @@ - - - - - + + + + + + + + - - + + diff --git a/resources/images/timelapse_on_hover.svg b/resources/images/timelapse_on_hover.svg index e46f1015fd..7ea45dc911 100644 --- a/resources/images/timelapse_on_hover.svg +++ b/resources/images/timelapse_on_hover.svg @@ -1,13 +1,16 @@ - - - - - - + + + + + + + + + - - + + diff --git a/resources/images/timelapse_on_normal.svg b/resources/images/timelapse_on_normal.svg index bd8898b5df..09655e1349 100644 --- a/resources/images/timelapse_on_normal.svg +++ b/resources/images/timelapse_on_normal.svg @@ -1,13 +1,16 @@ - - - - - - + + + + + + + + + - - + + diff --git a/resources/images/toolbar_text.svg b/resources/images/toolbar_text.svg new file mode 100644 index 0000000000..392ae36851 --- /dev/null +++ b/resources/images/toolbar_text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 5888a97c25..cc3e819e49 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.01.01.03", + "version": "01.02.00.00", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ @@ -91,9 +91,17 @@ "name": "0.30mm Standard @BBL X1C 0.6 nozzle", "sub_path": "process/0.30mm Standard @BBL X1C 0.6 nozzle.json" }, + { + "name": "0.30mm Standard @BBL X1 0.6 nozzle", + "sub_path": "process/0.30mm Standard @BBL X1 0.6 nozzle.json" + }, { "name": "0.40mm Standard @BBL X1C 0.8 nozzle", "sub_path": "process/0.40mm Standard @BBL X1C 0.8 nozzle.json" + }, + { + "name": "0.40mm Standard @BBL X1 0.8 nozzle", + "sub_path": "process/0.40mm Standard @BBL X1 0.8 nozzle.json" } ], "filament_list": [ @@ -185,30 +193,70 @@ "name": "PolyLite PLA @base", "sub_path": "filament/PolyLite PLA @base.json" }, + { + "name": "Generic PLA @base", + "sub_path": "filament/Generic PLA @base.json" + }, { "name": "Generic PLA", "sub_path": "filament/Generic PLA.json" }, + { + "name": "Generic PLA @0.2 nozzle", + "sub_path": "filament/Generic PLA @0.2 nozzle.json" + }, { "name": "Generic PLA-CF", "sub_path": "filament/Generic PLA-CF.json" }, + { + "name": "Generic PETG @base", + "sub_path": "filament/Generic PETG @base.json" + }, + { + "name": "Generic PETG @0.2 nozzle", + "sub_path": "filament/Generic PETG @0.2 nozzle.json" + }, { "name": "Generic PETG", "sub_path": "filament/Generic PETG.json" }, + { + "name": "Generic ABS @base", + "sub_path": "filament/Generic ABS @base.json" + }, { "name": "Generic ABS", "sub_path": "filament/Generic ABS.json" }, + { + "name": "Generic ABS @0.2 nozzle", + "sub_path": "filament/Generic ABS @0.2 nozzle.json" + }, { "name": "Generic TPU", "sub_path": "filament/Generic TPU.json" }, + { + "name": "Generic ASA @base", + "sub_path": "filament/Generic ASA @base.json" + }, + { + "name": "Generic ASA @0.2 nozzle", + "sub_path": "filament/Generic ASA @0.2 nozzle.json" + }, { "name": "Generic ASA", "sub_path": "filament/Generic ASA.json" }, + { + "name": "Generic PC @base", + "sub_path": "filament/Generic PC @base.json" + }, + { + "name": "Generic PC @0.2 nozzle", + "sub_path": "filament/Generic PC @0.2 nozzle.json" + }, { "name": "Generic PC", "sub_path": "filament/Generic PC.json" @@ -229,6 +277,10 @@ "name": "Bambu TPU 95A @BBL X1C", "sub_path": "filament/Bambu TPU 95A @BBL X1C.json" }, + { + "name": "Bambu TPU 95A @BBL X1C 0.2 nozzle", + "sub_path": "filament/Bambu TPU 95A @BBL X1C 0.2 nozzle.json" + }, { "name": "Bambu TPU 95A @BBL X1", "sub_path": "filament/Bambu TPU 95A @BBL X1.json" @@ -281,6 +333,10 @@ "name": "Bambu Support W @BBL X1C", "sub_path": "filament/Bambu Support W @BBL X1C.json" }, + { + "name": "Bambu Support W @BBL X1C 0.2 nozzle", + "sub_path": "filament/Bambu Support W @BBL X1C 0.2 nozzle.json" + }, { "name": "Bambu Support W @BBL X1", "sub_path": "filament/Bambu Support W @BBL X1.json" @@ -297,6 +353,10 @@ "name": "Bambu PC @BBL X1C", "sub_path": "filament/Bambu PC @BBL X1C.json" }, + { + "name": "Bambu PC @BBL X1C 0.2 nozzle", + "sub_path": "filament/Bambu PC @BBL X1C 0.2 nozzle.json" + }, { "name": "Bambu PC @BBL X1C 0.8 nozzle", "sub_path": "filament/Bambu PC @BBL X1C 0.8 nozzle.json" @@ -339,6 +399,14 @@ "name": "Bambu Lab X1 0.4 nozzle", "sub_path": "machine/Bambu Lab X1 0.4 nozzle.json" }, + { + "name": "Bambu Lab X1 0.8 nozzle", + "sub_path": "machine/Bambu Lab X1 0.8 nozzle.json" + }, + { + "name": "Bambu Lab X1 0.6 nozzle", + "sub_path": "machine/Bambu Lab X1 0.6 nozzle.json" + }, { "name": "Bambu Lab X1 Carbon 0.2 nozzle", "sub_path": "machine/Bambu Lab X1 Carbon 0.2 nozzle.json" diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json index 3e546157c6..3dac721007 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.2 nozzle.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "Bambu ABS @base", "filament_max_volumetric_speed": [ - "2" + "4" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.2 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json index e91cb8154b..c3230932b0 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C 0.8 nozzle.json @@ -15,6 +15,7 @@ "10" ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json index e1fc9845e5..fdaaec3bf2 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL X1C.json @@ -11,6 +11,7 @@ "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", - "Bambu Lab X1 Carbon 0.6 nozzle" + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 0.6 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu ABS @base.json b/resources/profiles/BBL/filament/Bambu ABS @base.json index 165b1e676a..f32991617c 100644 --- a/resources/profiles/BBL/filament/Bambu ABS @base.json +++ b/resources/profiles/BBL/filament/Bambu ABS @base.json @@ -8,6 +8,9 @@ "filament_flow_ratio": [ "0.95" ], + "filament_cost": [ + "24.99" + ], "filament_vendor": [ "Bambu Lab" ] diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json index b5e5767a53..944c053686 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL X1C.json @@ -8,7 +8,29 @@ "filament_max_volumetric_speed": [ "8" ], + "nozzle_temperature_initial_layer": [ + "290" + ], + "nozzle_temperature": [ + "290" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "10" + ], + "fan_cooling_layer_time": [ + "6" + ], + "full_fan_speed_layer": [ + "2" + ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.4 nozzle" + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @base.json b/resources/profiles/BBL/filament/Bambu PA-CF @base.json index a9b6f16874..f4be03cdcd 100644 --- a/resources/profiles/BBL/filament/Bambu PA-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PA-CF @base.json @@ -20,6 +20,9 @@ "filament_type": [ "PA-CF" ], + "filament_cost": [ + "44.99" + ], "nozzle_temperature": [ "280" ] diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json new file mode 100644 index 0000000000..1ba66f49df --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.2 nozzle.json @@ -0,0 +1,17 @@ +{ + "type": "filament", + "setting_id": "GFSC00_02", + "name": "Bambu PC @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Bambu PC @base", + "filament_max_volumetric_speed": [ + "1" + ], + "nozzle_temperature": [ + "260" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json index 82f7bc217a..d770c69d27 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.6 nozzle.json @@ -9,6 +9,7 @@ "260" ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.6 nozzle" + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 0.6 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json index f10699dd06..141a95002c 100644 --- a/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PC @BBL X1C 0.8 nozzle.json @@ -9,6 +9,7 @@ "260" ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu PC @base.json b/resources/profiles/BBL/filament/Bambu PC @base.json index 5a507a2b42..c8f76b80af 100644 --- a/resources/profiles/BBL/filament/Bambu PC @base.json +++ b/resources/profiles/BBL/filament/Bambu PC @base.json @@ -8,6 +8,9 @@ "filament_vendor": [ "Bambu Lab" ], + "filament_cost": [ + "34.99" + ], "filament_flow_ratio": [ "0.94" ] diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1.json index 8ebcaa36d5..0957d4dd0f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1.json @@ -12,6 +12,8 @@ "8" ], "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle" - ] + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" + ] } diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.2 nozzle.json index 1d178e4082..feb592f8ab 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.2 nozzle.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "Bambu PLA Basic @base", "filament_max_volumetric_speed": [ - "2.5" + "4" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.2 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.8 nozzle.json index b839b9bfc4..aca84b0d7a 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL X1C 0.8 nozzle.json @@ -9,7 +9,7 @@ "21" ], "slow_down_min_speed": [ - "30" + "20" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.8 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @base.json b/resources/profiles/BBL/filament/Bambu PLA Basic @base.json index d450ad4320..5f936cec7f 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Basic @base.json +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @base.json @@ -9,7 +9,7 @@ "Bambu Lab" ], "filament_cost": [ - "25.4" + "24.99" ], "filament_flow_ratio": [ "0.98" diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1.json index 02ded53c2f..83332e44ca 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1.json @@ -12,6 +12,8 @@ "8" ], "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle" + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.2 nozzle.json index 15993f4cee..e3a2fd5ae4 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.2 nozzle.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "Bambu PLA Matte @base", "filament_max_volumetric_speed": [ - "2.5" + "4" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.2 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.8 nozzle.json index d59a62fba1..7d46ab5456 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.8 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL X1C 0.8 nozzle.json @@ -9,7 +9,7 @@ "22" ], "slow_down_min_speed": [ - "30" + "20" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.8 nozzle" diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @base.json b/resources/profiles/BBL/filament/Bambu PLA Matte @base.json index b6001992d9..af1d3e1f21 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Matte @base.json +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @base.json @@ -9,7 +9,7 @@ "Bambu Lab" ], "filament_cost": [ - "25.4" + "24.99" ], "filament_density": [ "1.32" diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL X1C.json b/resources/profiles/BBL/filament/Bambu Support G @BBL X1C.json index d78aa93bfc..3692f2dcc1 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL X1C.json @@ -8,6 +8,8 @@ "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu Support G @base.json b/resources/profiles/BBL/filament/Bambu Support G @base.json index f9d1637e30..21d303dbac 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @base.json +++ b/resources/profiles/BBL/filament/Bambu Support G @base.json @@ -23,6 +23,9 @@ "fan_cooling_layer_time": [ "10" ], + "filament_cost": [ + "34.99" + ], "slow_down_layer_time":[ "6" ] diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL X1.json b/resources/profiles/BBL/filament/Bambu Support W @BBL X1.json index 070b48af75..c5f6c4454f 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL X1.json @@ -6,6 +6,8 @@ "instantiation": "true", "inherits": "Bambu Support W @base", "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle" + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL X1C 0.2 nozzle.json new file mode 100644 index 0000000000..75e31aed23 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL X1C 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSS00_00", + "name": "Bambu Support W @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Bambu Support W @base", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} \ No newline at end of file diff --git a/resources/profiles/BBL/filament/Bambu Support W @base.json b/resources/profiles/BBL/filament/Bambu Support W @base.json index 62ca849148..8a5f3fbbc5 100644 --- a/resources/profiles/BBL/filament/Bambu Support W @base.json +++ b/resources/profiles/BBL/filament/Bambu Support W @base.json @@ -20,12 +20,21 @@ "hot_plate_temp": [ "40" ], + "textured_plate_temp": [ + "40" + ], "cool_plate_temp_initial_layer": [ "40" ], "hot_plate_temp_initial_layer": [ "40" ], + "textured_plate_temp_initial_layer": [ + "40" + ], + "filament_cost": [ + "29.99" + ], "slow_down_layer_time": [ "8" ] diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1.json index 2f6278877d..9c041fa4f9 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1.json @@ -9,6 +9,8 @@ "6.4" ], "compatible_printers": [ - "Bambu Lab X1 0.4 nozzle" + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C 0.2 nozzle.json new file mode 100644 index 0000000000..b9850d224c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C 0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSU00_00", + "name": "Bambu TPU 95A @BBL X1C 0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Bambu TPU 95A @base", + "filament_max_volumetric_speed": [ + "0.5" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C.json index 35c3322605..2ef09cab10 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL X1C.json @@ -6,7 +6,7 @@ "instantiation": "true", "inherits": "Bambu TPU 95A @base", "filament_max_volumetric_speed": [ - "6.4" + "3.6" ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @base.json b/resources/profiles/BBL/filament/Bambu TPU 95A @base.json index 8006c0adcc..58e83618c9 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @base.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @base.json @@ -14,6 +14,9 @@ "nozzle_temperature_initial_layer": [ "230" ], + "filament_cost": [ + "36.99" + ], "nozzle_temperature": [ "230" ] diff --git a/resources/profiles/BBL/filament/Generic ABS @0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @0.2 nozzle.json new file mode 100644 index 0000000000..df120b8dfe --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ABS @0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSB99_00", + "name": "Generic ABS @0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Generic ABS @base", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ABS @base.json b/resources/profiles/BBL/filament/Generic ABS @base.json new file mode 100644 index 0000000000..044703f6a9 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ABS @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "filament_id": "GFB99", + "name": "Generic ABS @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_abs", + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "16" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ABS.json b/resources/profiles/BBL/filament/Generic ABS.json index a2f2fa1597..256bc5674f 100644 --- a/resources/profiles/BBL/filament/Generic ABS.json +++ b/resources/profiles/BBL/filament/Generic ABS.json @@ -1,21 +1,16 @@ { "type": "filament", - "filament_id": "GFB99", "setting_id": "GFSB99", "name": "Generic ABS", "from": "system", "instantiation": "true", - "inherits": "fdm_filament_abs", - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "16" - ], + "inherits": "Generic ABS @base", "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic ASA @0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @0.2 nozzle.json new file mode 100644 index 0000000000..50e258da07 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ASA @0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSB98_00", + "name": "Generic ASA @0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Generic ASA @base", + "filament_max_volumetric_speed": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ASA @base.json b/resources/profiles/BBL/filament/Generic ASA @base.json new file mode 100644 index 0000000000..ac74598de7 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ASA @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "filament_id": "GFB98", + "name": "Generic ASA @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_asa", + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "12" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ASA.json b/resources/profiles/BBL/filament/Generic ASA.json index 2d63f41ec2..b2187b615f 100644 --- a/resources/profiles/BBL/filament/Generic ASA.json +++ b/resources/profiles/BBL/filament/Generic ASA.json @@ -1,21 +1,16 @@ { "type": "filament", - "filament_id": "GFB98", "setting_id": "GFSB98", "name": "Generic ASA", "from": "system", "instantiation": "true", - "inherits": "fdm_filament_asa", - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "12" - ], + "inherits": "Generic ASA @base", "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic PA-CF.json b/resources/profiles/BBL/filament/Generic PA-CF.json index e99b4ce59d..55b8285143 100644 --- a/resources/profiles/BBL/filament/Generic PA-CF.json +++ b/resources/profiles/BBL/filament/Generic PA-CF.json @@ -7,18 +7,34 @@ "instantiation": "true", "inherits": "fdm_filament_pa", "filament_type": [ - "PA-CF" + "PA-CF" + ], + "nozzle_temperature_initial_layer": [ + "290" + ], + "nozzle_temperature": [ + "290" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "fan_max_speed": [ + "40" ], - "nozzle_temperature_initial_layer": [ - "280" - ], - "nozzle_temperature": [ - "280" - ], - "filament_max_volumetric_speed": [ - "8" + "fan_min_speed": [ + "10" + ], + "fan_cooling_layer_time": [ + "6" + ], + "full_fan_speed_layer": [ + "2" ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.4 nozzle" - ] + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" + ] } diff --git a/resources/profiles/BBL/filament/Generic PA.json b/resources/profiles/BBL/filament/Generic PA.json index 401f1278a1..f6baca4474 100644 --- a/resources/profiles/BBL/filament/Generic PA.json +++ b/resources/profiles/BBL/filament/Generic PA.json @@ -7,15 +7,19 @@ "instantiation": "true", "inherits": "fdm_filament_pa", "nozzle_temperature_initial_layer": [ - "280" + "280" ], "nozzle_temperature": [ - "280" + "280" ], "filament_max_volumetric_speed": [ - "16" + "16" ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.4 nozzle" + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic PC @0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PC @0.2 nozzle.json new file mode 100644 index 0000000000..c6ee4b7fb7 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PC @0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSC99_00", + "name": "Generic PC @0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Generic PC @base", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PC @base.json b/resources/profiles/BBL/filament/Generic PC @base.json new file mode 100644 index 0000000000..dc053680d1 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PC @base.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "filament_id": "GFC99", + "name": "Generic PC @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pc", + "filament_max_volumetric_speed": [ + "16" + ], + "filament_flow_ratio": [ + "0.94" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PC.json b/resources/profiles/BBL/filament/Generic PC.json index 35d6fcd54a..6556f61cd5 100644 --- a/resources/profiles/BBL/filament/Generic PC.json +++ b/resources/profiles/BBL/filament/Generic PC.json @@ -1,20 +1,15 @@ { - "type": "filament", - "filament_id": "GFC99", - "setting_id": "GFSC99", - "name": "Generic PC", - "from": "system", - "instantiation": "true", - "inherits": "fdm_filament_pc", - "filament_max_volumetric_speed": [ - "16" - ], - "filament_flow_ratio": [ - "0.94" - ], - "compatible_printers": [ - "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" - ] + "type": "filament", + "setting_id": "GFSC99", + "name": "Generic PC", + "from": "system", + "instantiation": "true", + "inherits": "Generic PC @base", + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" + ] } diff --git a/resources/profiles/BBL/filament/Generic PETG @0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @0.2 nozzle.json new file mode 100644 index 0000000000..c35fae366c --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @0.2 nozzle.json @@ -0,0 +1,14 @@ +{ + "type": "filament", + "setting_id": "GFSG99_00", + "name": "Generic PETG @0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Generic PETG @base", + "filament_max_volumetric_speed": [ + "1" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @base.json b/resources/profiles/BBL/filament/Generic PETG @base.json new file mode 100644 index 0000000000..55989d9ff8 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @base.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "filament_id": "GFG99", + "name": "Generic PETG @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pet", + "reduce_fan_stop_start_freq": [ + "1" + ], + "slow_down_for_layer_cooling": [ + "1" + ], + "fan_cooling_layer_time": [ + "30" + ], + "overhang_fan_speed": [ + "90" + ], + "overhang_fan_threshold": [ + "25%" + ], + "fan_max_speed": [ + "90" + ], + "fan_min_speed": [ + "40" + ], + "slow_down_min_speed": [ + "20" + ], + "slow_down_layer_time": [ + "8" + ], + "filament_flow_ratio": [ + "0.95" + ], + "filament_max_volumetric_speed": [ + "10" + ], + "nozzle_temperature_range_high": [ + "270" + ], + "filament_start_gcode": [ + " ; filament start gcode\n{if (bed_temperature[current_extruder] >60)||(bed_temperature_initial_layer[current_extruder] >60)}M106 P3 S255\n{elsif (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S180\n{endif}" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG.json b/resources/profiles/BBL/filament/Generic PETG.json index 8d5fe9aa1c..6171ba8a84 100644 --- a/resources/profiles/BBL/filament/Generic PETG.json +++ b/resources/profiles/BBL/filament/Generic PETG.json @@ -1,51 +1,16 @@ { "type": "filament", - "filament_id": "GFG99", "setting_id": "GFSG99", "name": "Generic PETG", "from": "system", "instantiation": "true", - "inherits": "fdm_filament_pet", - "reduce_fan_stop_start_freq": [ - "1" - ], - "slow_down_for_layer_cooling": [ - "1" - ], - "fan_cooling_layer_time": [ - "30" - ], - "overhang_fan_speed": [ - "90" - ], - "overhang_fan_threshold": [ - "25%" - ], - "fan_max_speed": [ - "90" - ], - "fan_min_speed": [ - "40" - ], - "slow_down_min_speed": [ - "20" - ], - "slow_down_layer_time": [ - "8" - ], - "filament_flow_ratio": [ - "0.95" - ], - "filament_max_volumetric_speed": [ - "10" - ], - "filament_start_gcode": [ - "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S180\n{elsif (bed_temperature[current_extruder] >60)||(bed_temperature_initial_layer[current_extruder] >60)}M106 P3 S255\n{endif};Prevent PETG from jamming" - ], + "inherits": "Generic PETG @base", "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic PLA @0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @0.2 nozzle.json new file mode 100644 index 0000000000..d42c175c22 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @0.2 nozzle.json @@ -0,0 +1,17 @@ +{ + "type": "filament", + "setting_id": "GFSL99_00", + "name": "Generic PLA @0.2 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Generic PLA @base", + "filament_max_volumetric_speed": [ + "2" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >30)||(bed_temperature_initial_layer[current_extruder] >30)}M106 P3 S180\n{endif}" + ], + "compatible_printers": [ + "Bambu Lab X1 Carbon 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @base.json b/resources/profiles/BBL/filament/Generic PLA @base.json new file mode 100644 index 0000000000..43de916b4a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @base.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "filament_id": "GFL99", + "name": "Generic PLA @base", + "from": "system", + "instantiation": "false", + "inherits": "fdm_filament_pla", + "filament_flow_ratio": [ + "0.98" + ], + "filament_max_volumetric_speed": [ + "12" + ], + "slow_down_layer_time": [ + "8" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif};Prevent PLA from jamming" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA-CF.json b/resources/profiles/BBL/filament/Generic PLA-CF.json index 01d3ae4bbf..3e28238475 100644 --- a/resources/profiles/BBL/filament/Generic PLA-CF.json +++ b/resources/profiles/BBL/filament/Generic PLA-CF.json @@ -21,7 +21,23 @@ "additional_cooling_fan_speed": [ "0" ], + "temperature_vitrification": [ + "55" + ], + "nozzle_temperature_range_low": [ + "190" + ], + "nozzle_temperature_range_high": [ + "240" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif}" + ], "compatible_printers": [ - "Bambu Lab X1 Carbon 0.4 nozzle" + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic PLA.json b/resources/profiles/BBL/filament/Generic PLA.json index 014cd3942f..0546d2e84e 100644 --- a/resources/profiles/BBL/filament/Generic PLA.json +++ b/resources/profiles/BBL/filament/Generic PLA.json @@ -1,24 +1,16 @@ { "type": "filament", - "filament_id": "GFL99", "setting_id": "GFSL99", "name": "Generic PLA", "from": "system", "instantiation": "true", - "inherits": "fdm_filament_pla", - "filament_flow_ratio": [ - "0.98" - ], - "filament_max_volumetric_speed": [ - "12" - ], - "slow_down_layer_time": [ - "8" - ], + "inherits": "Generic PLA @base", "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic PVA.json b/resources/profiles/BBL/filament/Generic PVA.json index f592862e7c..04f533f0ae 100644 --- a/resources/profiles/BBL/filament/Generic PVA.json +++ b/resources/profiles/BBL/filament/Generic PVA.json @@ -20,6 +20,9 @@ ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", - "Bambu Lab X1 0.4 nozzle" + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/Generic TPU.json b/resources/profiles/BBL/filament/Generic TPU.json index 163440eb56..a03c7a253a 100644 --- a/resources/profiles/BBL/filament/Generic TPU.json +++ b/resources/profiles/BBL/filament/Generic TPU.json @@ -9,10 +9,15 @@ "filament_max_volumetric_speed": [ "3.2" ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S255\n{elsif (bed_temperature[current_extruder] >30)||(bed_temperature_initial_layer[current_extruder] >30)}M106 P3 S180\n{endif}" + ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle", "Bambu Lab X1 0.4 nozzle", "Bambu Lab X1 Carbon 0.6 nozzle", - "Bambu Lab X1 Carbon 0.8 nozzle" + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 0.8 nozzle" ] } diff --git a/resources/profiles/BBL/filament/PolyLite PLA @BBL X1C.json b/resources/profiles/BBL/filament/PolyLite PLA @BBL X1C.json index 292239380f..c4a4ec1b10 100644 --- a/resources/profiles/BBL/filament/PolyLite PLA @BBL X1C.json +++ b/resources/profiles/BBL/filament/PolyLite PLA @BBL X1C.json @@ -8,6 +8,9 @@ "filament_max_volumetric_speed": [ "15" ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif}" + ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle" ] diff --git a/resources/profiles/BBL/filament/PolyTerra PLA @BBL X1C.json b/resources/profiles/BBL/filament/PolyTerra PLA @BBL X1C.json index 365b882631..4eb5b3376d 100644 --- a/resources/profiles/BBL/filament/PolyTerra PLA @BBL X1C.json +++ b/resources/profiles/BBL/filament/PolyTerra PLA @BBL X1C.json @@ -8,6 +8,9 @@ "filament_max_volumetric_speed": [ "22" ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif}" + ], "compatible_printers": [ "Bambu Lab X1 Carbon 0.4 nozzle" ] diff --git a/resources/profiles/BBL/filament/fdm_filament_abs.json b/resources/profiles/BBL/filament/fdm_filament_abs.json index 1c601318d9..c89c9bf55f 100644 --- a/resources/profiles/BBL/filament/fdm_filament_abs.json +++ b/resources/profiles/BBL/filament/fdm_filament_abs.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "90" ], + "textured_plate_temp" : [ + "90" + ], "cool_plate_temp_initial_layer" : [ "90" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "90" ], + "textured_plate_temp_initial_layer" : [ + "90" + ], "slow_down_for_layer_cooling": [ "1" ], @@ -71,7 +77,7 @@ "240" ], "nozzle_temperature_range_high": [ - "270" + "280" ], "slow_down_min_speed": [ "20" diff --git a/resources/profiles/BBL/filament/fdm_filament_asa.json b/resources/profiles/BBL/filament/fdm_filament_asa.json index 3eeac3e3a4..7f05e2b3c2 100644 --- a/resources/profiles/BBL/filament/fdm_filament_asa.json +++ b/resources/profiles/BBL/filament/fdm_filament_asa.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "90" ], + "textured_plate_temp" : [ + "90" + ], "cool_plate_temp_initial_layer" : [ "90" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "90" ], + "textured_plate_temp_initial_layer" : [ + "90" + ], "slow_down_for_layer_cooling": [ "1" ], @@ -71,7 +77,7 @@ "240" ], "nozzle_temperature_range_high": [ - "270" + "280" ], "slow_down_min_speed": [ "20" diff --git a/resources/profiles/BBL/filament/fdm_filament_common.json b/resources/profiles/BBL/filament/fdm_filament_common.json index f8dc0a70ca..208d6ac175 100644 --- a/resources/profiles/BBL/filament/fdm_filament_common.json +++ b/resources/profiles/BBL/filament/fdm_filament_common.json @@ -12,6 +12,9 @@ "hot_plate_temp" : [ "60" ], + "textured_plate_temp" : [ + "60" + ], "cool_plate_temp_initial_layer" : [ "60" ], @@ -21,6 +24,9 @@ "hot_plate_temp_initial_layer" : [ "60" ], + "textured_plate_temp_initial_layer" : [ + "60" + ], "overhang_fan_threshold": [ "95%" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pa.json b/resources/profiles/BBL/filament/fdm_filament_pa.json index 67c8ff050f..ce1b3d653c 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pa.json +++ b/resources/profiles/BBL/filament/fdm_filament_pa.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "100" ], + "textured_plate_temp" : [ + "100" + ], "cool_plate_temp_initial_layer" : [ "0" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "100" ], + "textured_plate_temp_initial_layer" : [ + "100" + ], "slow_down_for_layer_cooling": [ "1" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pc.json b/resources/profiles/BBL/filament/fdm_filament_pc.json index 9174d53530..375b776812 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pc.json +++ b/resources/profiles/BBL/filament/fdm_filament_pc.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "110" ], + "textured_plate_temp" : [ + "110" + ], "cool_plate_temp_initial_layer" : [ "0" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "110" ], + "textured_plate_temp_initial_layer" : [ + "110" + ], "slow_down_for_layer_cooling": [ "1" ], @@ -65,7 +71,7 @@ "280" ], "temperature_vitrification": [ - "140" + "120" ], "nozzle_temperature_range_low": [ "260" diff --git a/resources/profiles/BBL/filament/fdm_filament_pet.json b/resources/profiles/BBL/filament/fdm_filament_pet.json index b7f725968a..e32da82499 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pet.json +++ b/resources/profiles/BBL/filament/fdm_filament_pet.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "80" ], + "textured_plate_temp" : [ + "80" + ], "cool_plate_temp_initial_layer" : [ "60" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "80" ], + "textured_plate_temp_initial_layer" : [ + "80" + ], "slow_down_for_layer_cooling": [ "1" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pla.json b/resources/profiles/BBL/filament/fdm_filament_pla.json index a3b8a8f889..92ecf94c67 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pla.json +++ b/resources/profiles/BBL/filament/fdm_filament_pla.json @@ -28,6 +28,9 @@ "hot_plate_temp" : [ "45" ], + "textured_plate_temp" : [ + "45" + ], "cool_plate_temp_initial_layer" : [ "35" ], @@ -37,6 +40,9 @@ "hot_plate_temp_initial_layer" : [ "45" ], + "textured_plate_temp_initial_layer" : [ + "45" + ], "nozzle_temperature_initial_layer": [ "220" ], @@ -65,13 +71,13 @@ "220" ], "temperature_vitrification": [ - "45" + "55" ], "nozzle_temperature_range_low": [ "190" ], "nozzle_temperature_range_high": [ - "230" + "240" ], "slow_down_min_speed": [ "20" @@ -83,6 +89,6 @@ "70" ], "filament_start_gcode": [ - "; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{elsif (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{endif};Prevent PLA from jamming" + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif}" ] } diff --git a/resources/profiles/BBL/filament/fdm_filament_pva.json b/resources/profiles/BBL/filament/fdm_filament_pva.json index d8bb1b18c7..e3cbf9fa2a 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pva.json +++ b/resources/profiles/BBL/filament/fdm_filament_pva.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "45" ], + "textured_plate_temp" : [ + "45" + ], "cool_plate_temp_initial_layer" : [ "35" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "45" ], + "textured_plate_temp_initial_layer" : [ + "45" + ], "fan_cooling_layer_time": [ "100" ], @@ -71,13 +77,13 @@ "220" ], "temperature_vitrification": [ - "50" + "55" ], "nozzle_temperature_range_low": [ "190" ], "nozzle_temperature_range_high": [ - "250" + "240" ], "slow_down_min_speed": [ "50" @@ -89,6 +95,6 @@ "70" ], "filament_start_gcode": [ - "; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{elsif (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{endif};Prevent PLA from jamming" + "; filament start gcode\n{if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S180\n{endif}" ] } diff --git a/resources/profiles/BBL/filament/fdm_filament_tpu.json b/resources/profiles/BBL/filament/fdm_filament_tpu.json index 39597c7a56..2bbfefdd82 100644 --- a/resources/profiles/BBL/filament/fdm_filament_tpu.json +++ b/resources/profiles/BBL/filament/fdm_filament_tpu.json @@ -13,6 +13,9 @@ "hot_plate_temp" : [ "35" ], + "textured_plate_temp" : [ + "35" + ], "cool_plate_temp_initial_layer" : [ "30" ], @@ -22,6 +25,9 @@ "hot_plate_temp_initial_layer" : [ "35" ], + "textured_plate_temp_initial_layer" : [ + "35" + ], "fan_cooling_layer_time": [ "100" ], @@ -68,7 +74,7 @@ "240" ], "temperature_vitrification": [ - "60" + "30" ], "nozzle_temperature_range_low": [ "200" @@ -77,6 +83,6 @@ "250" ], "filament_start_gcode": [ - "; filament start gcode\n{if (bed_temperature[current_extruder] >30)||(bed_temperature_initial_layer[current_extruder]>30)}M106 P3 S255\n{endif};Prevent TPU from jamming" + "; filament start gcode\n{if (bed_temperature[current_extruder] >35)||(bed_temperature_initial_layer[current_extruder] >35)}M106 P3 S255\n{elsif(bed_temperature[current_extruder] >30)||(bed_temperature_initial_layer[current_extruder] >30)}M106 P3 S180\n{endif}" ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json index e2de9f562d..642bc72179 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json @@ -22,8 +22,8 @@ "18x28", "0x28" ], - "machine_start_gcode": "\n;===== date: 202200731 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", - "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 1.0} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nM17 S\nM17 Z0.5 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F900\n{else}\n G1 Z250 F900\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0", + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\nM221 X0 Y0 Z0 ; turn off soft endstop to prevent protential logic problem\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_end_gcode": ";===== date: 202200810 =====================\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 0.5} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nM17 S\nM17 Z0.35 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F600\n G1 Z{max_layer_z +98.0}\n{else}\n G1 Z250 F600\n G1 Z248\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0\n\nM17 X0.8 Y0.8 Z0.5 ; lower motor current to 45% power\n\n", "scan_first_layer": "1", "machine_load_filament_time": "17", "machine_unload_filament_time": "16", diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.6 nozzle.json new file mode 100644 index 0000000000..72f97d6de0 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.6 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "machine", + "setting_id": "GM006", + "name": "Bambu Lab X1 0.6 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Bambu Lab X1 0.4 nozzle", + "printer_model": "Bambu Lab X1", + "default_filament_profile": [ + "Bambu PLA Basic @BBL X1" + ], + "default_print_profile": "0.30mm Standard @BBL X1 0.6 nozzle", + "nozzle_diameter": [ + "0.6" + ], + "printer_variant": "0.6", + "max_layer_height": [ + "0.42" + ], + "min_layer_height": [ + "0.12" + ], + "retraction_length": [ + "1.4" + ], + "retraction_minimum_travel": [ + "3" + ], + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\nM221 X0 Y0 Z0 ; turn off soft endstop to prevent protential logic problem\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \nG0 Y5.5 \nG0 X18 E25\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.679 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.032 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.679 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.164 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.944 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.428 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.725 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.329 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.725 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.362 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.910 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.186 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.384 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.318 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.461 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.318 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n ;G0 Y0.9\n ;G0 X18 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E16.9 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.030 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.015 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.015 K0.030\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.015 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.015}\n M623 \n\n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "nozzle_type": "hardened_steel" +} \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.8 nozzle.json new file mode 100644 index 0000000000..940e33fc62 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.8 nozzle.json @@ -0,0 +1,35 @@ +{ + "type": "machine", + "setting_id": "GM007", + "name": "Bambu Lab X1 0.8 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "Bambu Lab X1 0.4 nozzle", + "printer_model": "Bambu Lab X1", + "default_filament_profile": [ + "Bambu PLA Basic @BBL X1" + ], + "nozzle_diameter": [ + "0.8" + ], + "printer_variant": "0.8", + "default_print_profile": "0.40mm Standard @BBL X1 0.8 nozzle", + "max_layer_height": [ + "0.56" + ], + "min_layer_height": [ + "0.16" + ], + "retraction_length": [ + "3" + ], + "retraction_minimum_travel": [ + "1" + ], + "retract_length_toolchange": [ + "3" + ], + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y4.5 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X129 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 Y5.5 \nG0 X129 E15\nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.8660 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.0360 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.8660 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.1820 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E2.1600 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.4760 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.8060 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.3660 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.8060 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.4020 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E2.1220 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.3180 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.5380 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.4640 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.5120 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.4640 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n\n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X110.000 E9.35441 F4800 \n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.010 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.010 K0.020\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.01 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14) *0.01}\n M623 \n\n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X185.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X190.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X195.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X200.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X205.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X210.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X215.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X220.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X225.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "nozzle_type": "hardened_steel" + } + \ No newline at end of file diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json index 80a46ba7cf..74f6c6ee9a 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.2 nozzle.json @@ -26,6 +26,6 @@ "retraction_minimum_travel": [ "5" ], - "machine_start_gcode": "\n;===== date: 202200731 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.160 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.080 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.080 K0.160\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.08 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.08}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\nM221 X0 Y0 Z0 ; turn off soft endstop to prevent protential logic problem\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.160 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.080 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.080 K0.160\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.08 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.08}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", "nozzle_type": "stainless_steel" } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json index 8ed4e921a1..3d7cd43f8b 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.4 nozzle.json @@ -22,8 +22,8 @@ "18x28", "0x28" ], - "machine_start_gcode": "\n;===== date: 202200731 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", - "machine_end_gcode": "M400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 1.0} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nM17 S\nM17 Z0.5 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F900\n{else}\n G1 Z250 F900\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0", + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\nM221 X0 Y0 Z0 ; turn off soft endstop to prevent protential logic problem\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \nG0 Y5.5 \nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E0.933 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.018 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E0.933 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.091 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.080 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.238 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.403 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.183 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.403 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.201 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.061 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E0.659 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E0.769 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E0.732 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.256 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E0.732 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n ;G0 Y0.5\n ;G0 X18 E18 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E9.35441 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.040 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.020 K0.040\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E1.24726 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.02 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.02}\n M623 \n\n G1 X140.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.31181 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4", + "machine_end_gcode": ";===== date: 202200810 =====================\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 0.5} F900 ; lower z a little\nG1 X65 Y245 F12000 ; move to safe pos \nG1 Y265 F3000\n\nG1 X65 Y245 F12000\nG1 Y265 F3000\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\n\nG1 X100 F12000 ; wipe\n; pull back filament to AMS\nM620 S255\nG1 X20 Y50 F12000\nG1 Y-3\nT255\nG1 X65 F12000\nG1 Y265\nG1 X100 F12000 ; wipe\nM621 S255\nM104 S0 ; turn off hotend\n\nM17 S\nM17 Z0.35 ; lower z motor current to reduce impact if there is something in the bottom\n{if (max_layer_z + 100.0) < 250}\n G1 Z{max_layer_z + 100.0} F600\n G1 Z{max_layer_z +98.0}\n{else}\n G1 Z250 F600\n G1 Z248\n{endif}\nM400 P100\nM17 R ; restore z current\n\nG90\nG1 X128 Y250 F3600\n\nM220 S100 ; Reset feedrate magnitude\nM201.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 0\n\nM17 X0.8 Y0.8 Z0.5 ; lower motor current to 45% power\n\n", "scan_first_layer": "1", "machine_load_filament_time": "17", "machine_unload_filament_time": "16", diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json index e00b134574..b7cf921fd3 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.6 nozzle.json @@ -26,5 +26,5 @@ "retraction_minimum_travel": [ "3" ], - "machine_start_gcode": "\n;===== date: 202200731 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \nG0 Y5.5 \nG0 X18 E25\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.679 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.032 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.679 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.164 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.944 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.428 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.725 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.329 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.725 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.362 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.910 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.186 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.384 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.318 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.461 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.318 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n ;G0 Y0.9\n ;G0 X18 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E16.9 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.030 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.015 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.015 K0.030\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.015 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.015}\n M623 \n\n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\nM221 X0 Y0 Z0 ; turn off soft endstop to prevent protential logic problem\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y5.0 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature[initial_extruder]}\nG0 E3 F300\nG0 X240 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \nG0 Y5.5 \nG0 X18 E25\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.679 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.032 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.679 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.164 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E1.944 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.428 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.725 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.329 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.725 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.362 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E1.910 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.186 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.384 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.318 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.461 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.318 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n T1000 \n M83 \n\n ;G0 X18 Y28 F20000\n ;G0 Y0\n ;G0 Z0.3\n ;G0 X250 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n ;G0 Y0.9\n ;G0 X18 E25 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n\n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X185.000 E16.9 F{outer_wall_volumetric_speed/(0.3*0.9) * 60}\n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.030 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.015 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.9) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.015 K0.030\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature[initial_extruder]}\n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.25000 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60}\n G1 X70.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X75.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X80.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X85.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X90.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X95.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X100.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X105.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X110.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X115.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X120.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X125.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X130.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X135.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.015 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*0.015}\n M623 \n\n G1 X140.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X145.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X150.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X155.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X160.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X165.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X170.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X175.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X180.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X185.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X190.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X195.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X200.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X205.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X210.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X215.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n G1 X220.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5)/ 4 * 60} \n G1 X225.000 E0.56250 F{outer_wall_volumetric_speed/(0.3*0.5) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json index e06a0c188f..b02c38d6a9 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 Carbon 0.8 nozzle.json @@ -29,5 +29,5 @@ "retract_length_toolchange": [ "3" ], - "machine_start_gcode": "\n;===== date: 202200731 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\nM975 S1\n;===== prepare print temperature and material end =====\n\n\n;===== wipe mouth ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nG0 X126 F120\nG0 X130\nG0 X126\nG0 X130\nG0 X128\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe mouth end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 P500\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \nM400 S3\n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y4.5 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X129 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 Y5.5 \nG0 X129 E15\nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.8660 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.0360 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.8660 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.1820 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E2.1600 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.4760 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.8060 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.3660 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.8060 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.4020 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E2.1220 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.3180 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.5380 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.4640 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.5120 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.4640 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n\n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X110.000 E9.35441 F4800 \n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.010 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.010 K0.020\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.01 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14) *0.01}\n M623 \n\n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X185.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X190.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X195.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X200.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X205.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X210.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X215.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X220.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X225.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" + "machine_start_gcode": "\n;===== date: 202200815 =====================\n;===== reset machine status =================\nG91\nM17 Z0.3 ; lower the z-motor current\nG0 Z7 F300 ; lower the hotbed , to prevent the nozzle is below the hotbed\nG90\nM17 X1.2 Y1.2 Z0.75 ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nM1002 set_gcode_claim_speed_level : 5\n\n;===== heatbed preheat ====================\nM1002 gcode_claim_action : 2\n{if bbl_bed_temperature_gcode}\nM1002 set_heatbed_surface_temp:[bed_temperature_initial_layer_vector] ;config bed temps\nM140 A S[bed_temperature_initial_layer_single] ;set bed temp\nM190 A S[bed_temperature_initial_layer_single] ;wait for bed temp\n{else}\nM140 S[bed_temperature_initial_layer_single] ;set bed temp\nM190 S[bed_temperature_initial_layer_single] ;wait for bed temp\n{endif}\n\n{if scan_first_layer}\n;=========register first layer scan=====\nM977 S1 P60\n{endif}\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n;===== prepare print temperature and material ==========\nM104 S[nozzle_temperature_initial_layer] ;set extruder temp\nG91\nG0 Z2 F1200\nG90\nG28 X\nM975 S1 ; turn on \nG1 X60 F12000\nG1 Y245\nG1 Y265 F3000\nM620 M\nM620 S[initial_tool]A ; switch material if AMS exist\n M109 S[nozzle_temperature_initial_layer]\n G1 X120 F12000\n\n G1 X20 Y50 F12000\n G1 Y-3\n T[initial_tool]\n G1 X54 F12000\n G1 Y265\n M400\nM621 S[initial_tool]A\n\nM412 S1 ; ===turn on filament runout detection===\n\nM109 S250 ;set nozzle to common flush temp\nM106 P1 S0\nG92 E0\nG1 E50 F200\nM400\nM104 S[nozzle_temperature_initial_layer]\nG92 E0\nG1 E50 F200\nM400\nM106 P1 S255\nG92 E0\nG1 E5 F300\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20} ; drop nozzle temp, make filament shink a bit\nG92 E0\nG1 E-0.5 F300\n\nG1 X70 F9000\nG1 X76 F15000\nG1 X65 F15000\nG1 X76 F15000\nG1 X65 F15000; shake to put down garbage\nG1 X80 F6000\nG1 X95 F15000\nG1 X80 F15000\nG1 X165 F15000; wipe and shake\nM400\nM106 P1 S0\n;===== prepare print temperature and material end =====\n\n\n;===== wipe nozzle ===============================\nM1002 gcode_claim_action : 14\nM975 S1\nM106 S255\nG1 X65 Y230 F18000\nG1 Y264 F6000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]-20}\nG1 X100 F18000 ; first wipe mouth\n\nG0 X135 Y253 F20000 ; move to exposed steel surface edge\nG28 Z P0 T300; home z with low precision,permit 300deg temperature\nG29.2 S0 ; turn off ABL\nG0 Z2 F20000\n\nG1 X60 Y265\nG92 E0\nG1 E-0.5 F300 ; retrack more\nG1 X100 F5000; second wipe mouth\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X100 F5000\nG1 X70 F15000\nG1 X90 F5000\nG0 X128 Y261 Z-1.5 F20000 ; move to exposed steel surface and stop the nozzle\nM104 S140 ; set temp down to heatbed acceptable\nM106 S255 ; turn on fan (G28 has turn off fan)\n\nM221 S; push soft endstop status\nM221 Z0 ;turn off Z axis endstop\nG0 Z0.5 F20000\nG0 X125 Y259.5 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y262.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y260.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.5\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 Z0.5 F20000\nG0 X125 Y261.0\nG0 Z-1.01\nG0 X131 F211\nG0 X124\nG0 X128\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\nG2 I0.5 J0 F300\n\nM109 S140 ; wait nozzle temp down to heatbed acceptable\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\nG2 I0.5 J0 F3000\n\nM221 R; pop softend status\nG1 Z10 F1200\nM400\nG1 Z10\nG1 F30000\nG1 X230 Y15\nG29.2 S1 ; turn on ABL\n;G28 ; home again after hard wipe mouth\nM106 S0 ; turn off fan , too noisy\n;===== wipe nozzle end ================================\n\n\n;===== bed leveling ==================================\nM1002 judge_flag g29_before_print_flag\nM622 J1\n\n M1002 gcode_claim_action : 1\n G29 A X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\n\nM623\n;===== bed leveling end ================================\n\n;===== home after wipe mouth============================\nM1002 judge_flag g29_before_print_flag\nM622 J0\n\n M1002 gcode_claim_action : 13\n G28\n\nM623\n;===== home after wipe mouth end =======================\n\nM975 S1 ; turn on vibration supression\n\n;===== check scanner clarity ===========================\nM972 S5 P0 \nM400 S1\n;===== check scanner clarity end =======================\n\n=============turn on fans to prevent PLA jamming=================\n{if filament_type[initial_tool]==\"PLA\"}\n {if (bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}\n M106 P3 S180\n {elsif (bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}\n M106 P3 S255\n {endif};Prevent PLA from jamming\n{endif}\nM106 P2 S100 ; turn on big fan ,to cool down toolhead\n\n{if scan_first_layer}\n;start heatbed scan====================================\nM976 S2 P1 \n{endif}\n\nM104 S{nozzle_temperature_initial_layer[initial_extruder]} ; set extrude temp earlier, to reduce wait time\n\n;===== mech mode fast check============================\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q1 A7 B30 C80 H15 K0\nM974 Q1 S2 P0\n\nG1 X128 Y128 Z5 F20000\nM400 P200\nM970.3 Q0 A7 B30 C90 Q0 H15 K0\nM974 Q0 S2 P0\n\nM975 S1\nG1 F30000\nG1 X230 Y15\nG28 X ; re-home XY \n;===== fmech mode fast check============================\n\n\n;===== noozle load line ===============================\nM975 S1\nG90 \nM83\nT1000\nG1 X18.0 Y4.5 Z0.3 F18000;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 E3 F300\nG0 X129 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 X240 E15 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \nG0 Y5.5 \nG0 X129 E15\nG0 X18 E15\nM400\n\n;===== draw extrinsic para cali paint =================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M1002 gcode_claim_action : 8\n\n T1000 \n G0 F3000 X28.000 Y19.500 Z0.200\n G1 F1200.0 X28.000 Y45.000 Z0.200 E1.8660 \n G1 F1200.0 X28.500 Y45.000 Z0.200 E0.0360 \n G1 F1200.0 X28.500 Y19.500 Z0.200 E1.8660 \n G1 F1200.0 X31.000 Y19.500 Z0.200 E0.1820 \n G1 F1200.0 X31.000 Y49.000 Z0.200 E2.1600 \n G1 F1200.0 X37.500 Y49.000 Z0.200 E0.4760 \n G1 F1200.0 X37.500 Y60.000 Z0.200 E0.8060 \n G1 F1200.0 X42.500 Y60.000 Z0.200 E0.3660 \n G1 F1200.0 X42.500 Y49.000 Z0.200 E0.8060 \n G1 F1200.0 X48.000 Y49.000 Z0.200 E0.4020 \n G1 F1200.0 X48.000 Y20.000 Z0.200 E2.1220 \n G1 F1200.0 X30.000 Y20.000 Z0.200 E1.3180 \n G1 F1200.0 X30.000 Y41.000 Z0.200 E1.5380 \n G1 F1200.0 X50.000 Y41.000 Z0.200 E1.4640 \n G1 F1200.0 X50.000 Y34.000 Z0.200 E0.5120 \n G1 F1200.0 X30.000 Y34.000 Z0.200 E1.4640 \n G1 F1500.000 E-0.800 \n\n ;=========== extruder cali extrusion ================== \n\n T1000 \n M83 \n G0 X35.000 Y18.000 Z0.300 F30000 E0\n G1 F1500.000 E0.800 \n M106 S0 ; turn off fan\n G0 X110.000 E9.35441 F4800 \n G0 X185.000 E9.35441 F4800 \n G0 X187 Z0\n G1 F1500.000 E-0.800 \n G0 Z1\n G0 X180 Z0.3 F18000\n \n M900 L1000.0 M1.0\n M900 K0.020 \n G0 X45.000 F30000 \n G0 Y20.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.010 \n G0 X45.000 F30000 \n G0 Y22.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800 \n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n M400\n\n G0 X45.000 F30000 \n M900 K0.000 \n G0 X45.000 F30000 \n G0 Y24.000 F30000 \n G1 F1500.000 E0.800 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 F1500.000 E-0.800\n G1 X183 Z0.15 F30000\n G1 X185\n G1 Z1.0\n G0 Y18.000 F30000 ; move y to clear pos \n G1 Z0.3\n\n G0 X45.000 F30000 ; move to start point\n\nM623 ; end of \"draw extrinsic para cali paint\"\n\nM104 S140\n\n\n;=========== laser and rgb calibration =========== \nM400\nM18 E\nM500 R\n\nM973 S3 P14\n\nG1 X120 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\nT1100\nG1 X143.0 Y5.0 Z0.3 F18000.0;Move to first extrude line pos\n\nM400 P100\n\nM960 S1 P1\nM400 P100\nM973 S6 ; use auto exposure by xcam\nM960 S0 P0\n\n;=========== handeye calibration ======================\nM1002 judge_flag extrude_cali_flag\nM622 J1\n\n M973 S3 P1 ; camera start stream\n M400 P500\n M973 S1 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G0 F6000 X40.000 Y54.500 Z0.000 \n M960 S0 P1\n M973 S1\n M400 P800\n M971 S6 P0\n M973 S2 P16000\n M400 P500 \n G0 Z0.000 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P1 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P200 \n M971 S5 P3 \n G0 Z0.500 F12000\n M960 S0 P0\n M960 S1 P1 \n G0 Y37.50 \n M400 P200\n M971 S5 P2 \n M960 S0 P0\n M960 S2 P1 \n G0 Y54.50 \n M400 P500 \n M971 S5 P4 \n M963 S1 \n M400 P1500 \n M964 \n T1100 \n G1 Z3 F3000 \n\n M400\n M500 ; save cali data\n\n M104 S{nozzle_temperature_initial_layer[initial_extruder]} ; rise nozzle temp now ,to reduce temp waiting time.\n\n T1100 \n M400 P400 \n M960 S0 P0\n G0 F30000.000 Y22.000 X65.000 Z0.000\n M400 P400 \n M960 S1 P1 \n M400 P50 \n\n M969 S1 N3 A2000 \n G0 F360.000 X181.000 Z0.000\n M980.3 A70.000 B{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60/4} C5.000 D{outer_wall_volumetric_speed/(1.75*1.75/4*3.14)*60} E5.000 F175.000 H1.000 I0.000 J0.010 K0.020\n M400 P100 \n G0 F20000\n G0 Z1 ; rise nozzle up\n T1000 ; change to nozzle space\n G0 X45.000 Y16.000 F30000 ; move to test line pos\n M969 S0 ; turn off scanning\n M960 S0 P0\n\n\n G1 Z2 F20000 \n T1000 \n G0 X45.000 Y16.000 F30000 E0\n M109 S{nozzle_temperature_initial_layer[initial_extruder]} \n G0 Z0.3\n G1 F1500.000 E3.600 \n G1 X65.000 E2.4945 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60}\n G1 X70.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X75.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X80.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X85.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X90.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X95.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X100.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X105.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X110.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X115.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X120.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X125.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X130.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X135.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60}\n\n ; see if extrude cali success, if not ,use default value\n M1002 judge_last_extrude_cali_success\n M622 J0\n M400\n M900 K0.01 M{outer_wall_volumetric_speed/(1.75*1.75/4*3.14) *0.01}\n M623 \n\n G1 X140.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X145.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X150.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X155.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X160.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X165.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X170.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X175.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X180.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X185.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X190.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X195.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X200.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X205.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X210.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X215.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n G1 X220.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) / 4 * 60} \n G1 X225.000 E0.6236 F{outer_wall_volumetric_speed/(0.3*1.0) * 60} \n M973 S4 \n\nM623\n\n;========turn off light and wait extrude temperature =============\nM1002 gcode_claim_action : 0\nM973 S4 ; turn off scanner\nM400 ; wait all motion done before implement the emprical L parameters\n;M900 L500.0 ; Empirical parameters\nM109 S[nozzle_temperature_initial_layer]\nM960 S1 P0 ; turn off laser\nM960 S2 P0 ; turn off laser\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off big fan \nM106 P3 S0 ; turn off chamber fan\n\nM975 S1 ; turn on mech mode supression\nG90 \nM83\nT1000\nG1 X128.0 Y253.0 Z0.2 F6000.0;Move to start position\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG0 X253 E6.4 F{outer_wall_volumetric_speed/(0.3*0.6) * 60} \nG0 Y128 E6.4\nG0 X252.5\nG0 Y252.5 E6.4\nG0 X128 E6.4" } diff --git a/resources/profiles/BBL/machine/Bambu Lab X1.json b/resources/profiles/BBL/machine/Bambu Lab X1.json index 1ebc1a3cee..943fb3c074 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1.json @@ -3,7 +3,7 @@ "name": "Bambu Lab X1", "model_id": "BL-P002", "url": "http://www.bambulab.com/Parameters/printer_model/Bambu Lab X1.json", - "nozzle_diameter": "0.4", + "nozzle_diameter": "0.4;0.6;0.8", "machine_tech": "FFF", "family": "BBL-3DP", "bed_model": "bbl-3dp-X1.stl", diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL X1 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL X1 0.6 nozzle.json new file mode 100644 index 0000000000..174a8c3460 --- /dev/null +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL X1 0.6 nozzle.json @@ -0,0 +1,11 @@ +{ + "type": "process", + "setting_id": "GP011", + "name": "0.30mm Standard @BBL X1 0.6 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "fdm_process_bbl_0.30_nozzle_0.6", + "compatible_printers": [ + "Bambu Lab X1 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.40mm Standard @BBL X1 0.8 nozzle.json b/resources/profiles/BBL/process/0.40mm Standard @BBL X1 0.8 nozzle.json new file mode 100644 index 0000000000..29bfa35644 --- /dev/null +++ b/resources/profiles/BBL/process/0.40mm Standard @BBL X1 0.8 nozzle.json @@ -0,0 +1,11 @@ +{ + "type": "process", + "setting_id": "GP012", + "name": "0.40mm Standard @BBL X1 0.8 nozzle", + "from": "system", + "instantiation": "true", + "inherits": "fdm_process_bbl_0.40_nozzle_0.8", + "compatible_printers": [ + "Bambu Lab X1 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/fdm_process_bbl_0.10_nozzle_0.2.json b/resources/profiles/BBL/process/fdm_process_bbl_0.10_nozzle_0.2.json index a33070f2e5..a53df8b5a9 100644 --- a/resources/profiles/BBL/process/fdm_process_bbl_0.10_nozzle_0.2.json +++ b/resources/profiles/BBL/process/fdm_process_bbl_0.10_nozzle_0.2.json @@ -11,13 +11,13 @@ "top_shell_layers": "7", "bridge_flow": "1", "line_width": "0.22", - "outer_wall_line_width": "0.2", + "outer_wall_line_width": "0.22", "initial_layer_line_width": "0.25", "sparse_infill_line_width": "0.22", "inner_wall_line_width": "0.22", "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.21", - "top_surface_line_width": "0.2", + "support_line_width": "0.22", + "top_surface_line_width": "0.22", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/BBL/process/fdm_process_bbl_0.30_nozzle_0.6.json b/resources/profiles/BBL/process/fdm_process_bbl_0.30_nozzle_0.6.json index 32925c7057..8a3ee1da12 100644 --- a/resources/profiles/BBL/process/fdm_process_bbl_0.30_nozzle_0.6.json +++ b/resources/profiles/BBL/process/fdm_process_bbl_0.30_nozzle_0.6.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "3", "top_shell_layers": "3", "bridge_flow": "1", - "line_width": "0.6", - "outer_wall_line_width": "0.6", - "initial_layer_line_width": "0.6", - "sparse_infill_line_width": "0.6", - "inner_wall_line_width": "0.6", - "internal_solid_infill_line_width": "0.6", - "support_line_width": "0.6", - "top_surface_line_width": "0.6", + "line_width": "0.62", + "outer_wall_line_width": "0.62", + "initial_layer_line_width": "0.62", + "sparse_infill_line_width": "0.62", + "inner_wall_line_width": "0.62", + "internal_solid_infill_line_width": "0.62", + "support_line_width": "0.62", + "top_surface_line_width": "0.62", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "outer_wall_speed": "120", diff --git a/resources/profiles/BBL/process/fdm_process_bbl_0.40_nozzle_0.8.json b/resources/profiles/BBL/process/fdm_process_bbl_0.40_nozzle_0.8.json index 1b316059e9..3948f1b903 100644 --- a/resources/profiles/BBL/process/fdm_process_bbl_0.40_nozzle_0.8.json +++ b/resources/profiles/BBL/process/fdm_process_bbl_0.40_nozzle_0.8.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "3", "top_shell_layers": "3", "bridge_flow": "1", - "line_width": "0.8", - "outer_wall_line_width": "0.8", - "initial_layer_line_width": "0.8", - "sparse_infill_line_width": "0.8", - "inner_wall_line_width": "0.8", - "internal_solid_infill_line_width": "0.8", - "support_line_width": "0.8", - "top_surface_line_width": "0.8", + "line_width": "0.82", + "outer_wall_line_width": "0.82", + "initial_layer_line_width": "0.82", + "sparse_infill_line_width": "0.82", + "inner_wall_line_width": "0.82", + "internal_solid_infill_line_width": "0.82", + "support_line_width": "0.82", + "top_surface_line_width": "0.82", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/BBL/process/fdm_process_bbl_common.json b/resources/profiles/BBL/process/fdm_process_bbl_common.json index 729080de57..e8574725de 100644 --- a/resources/profiles/BBL/process/fdm_process_bbl_common.json +++ b/resources/profiles/BBL/process/fdm_process_bbl_common.json @@ -22,10 +22,10 @@ "draft_shield": "disabled", "elefant_foot_compensation": "0", "enable_arc_fitting": "1", - "outer_wall_line_width": "0.4", + "outer_wall_line_width": "0.42", "outer_wall_speed": "120", "wall_infill_order": "inner wall/outer wall/infill", - "line_width": "0.4", + "line_width": "0.42", "infill_direction": "45", "sparse_infill_density": "15%", "sparse_infill_pattern": "grid", @@ -61,7 +61,7 @@ "skirt_height": "1", "skirt_loops": "0", "minimum_sparse_infill_area": "15", - "internal_solid_infill_line_width": "0.4", + "internal_solid_infill_line_width": "0.42", "internal_solid_infill_speed": "150", "spiral_mode": "0", "initial_layer_infill_speed": "60", @@ -72,7 +72,7 @@ "support_on_build_plate_only": "0", "support_top_z_distance": "0.2", "support_filament": "0", - "support_line_width": "0.4", + "support_line_width": "0.42", "support_interface_loop_pattern": "0", "support_interface_filament": "0", "support_interface_top_layers": "2", @@ -89,7 +89,7 @@ "tree_support_with_infill": "0", "detect_thin_wall": "0", "top_surface_pattern": "monotonicline", - "top_surface_line_width": "0.4", + "top_surface_line_width": "0.42", "top_surface_speed": "200", "top_shell_layers": "3", "top_shell_thickness": "0.8", diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 2f46423f61..0343476333 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -13,7 +13,7 @@ "default_acceleration": "10000", "bridge_no_support": "0", "elefant_foot_compensation": "0.1", - "outer_wall_line_width": "0.4", + "outer_wall_line_width": "0.42", "outer_wall_speed": "120", "line_width": "0.45", "infill_direction": "45", @@ -61,7 +61,7 @@ "support_object_xy_distance": "0.5", "tree_support_with_infill": "1", "detect_thin_wall": "0", - "top_surface_line_width": "0.4", + "top_surface_line_width": "0.42", "top_surface_speed": "30", "travel_speed": "400", "enable_prime_tower": "0", diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index d5f7442d44..3aa2b02942 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -64,6 +64,23 @@ void main() alpha = 1.0; } + // if the fragment is outside the print volume -> use darker color + vec3 pv_check_min = ZERO; + vec3 pv_check_max = ZERO; + if (print_volume.type == 0) { + // rectangle + pv_check_min = world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, print_volume.z_data.x); + pv_check_max = world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, print_volume.z_data.y); + color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; + } + else if (print_volume.type == 1) { + // circle + float delta_radius = print_volume.xy_data.z - distance(world_pos.xy, print_volume.xy_data.xy); + pv_check_min = vec3(delta_radius, 0.0, world_pos.z - print_volume.z_data.x); + pv_check_max = vec3(0.0, 0.0, world_pos.z - print_volume.z_data.y); + color = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color, ZERO, 0.3333) : color; + } + //BBS: add outline_color if (is_outline) gl_FragColor = uniform_color; diff --git a/resources/web/data/text.js b/resources/web/data/text.js index aeb67a253f..e267a7b2ca 100644 --- a/resources/web/data/text.js +++ b/resources/web/data/text.js @@ -78,7 +78,10 @@ var LangText={ "t83":"2, Close all open Bambu Studio", "t84":"3, Delete all files under the plug-in directory", "t85":"4, Reopen Bambu studio and install the plug-in again", - "t86":"Close" + "t86":"Close", + "t87":"User Manual", + "t88":"clear", + "t89":"show in explorer" }, "zh_CN":{ "t1":"欢迎使用Bambu Studio", @@ -159,7 +162,10 @@ var LangText={ "t83":"2, 关闭所有Bambu Studio", "t84":"3, 删除插件所在目录下的所有文件", "t85":"4, 重新启动Bambu Studio并尝试安装插件", - "t86":"关闭" + "t86":"关闭", + "t87":"使用引导", + "t88":"清除", + "t89":"打开文件所在路径" } }; diff --git a/resources/web/guide/23/index.html b/resources/web/guide/23/index.html index cffa328c14..fcafcff7b1 100644 --- a/resources/web/guide/23/index.html +++ b/resources/web/guide/23/index.html @@ -146,4 +146,22 @@ + diff --git a/resources/web/guide/24/index.html b/resources/web/guide/24/index.html index 6349a09957..6f77f8e09b 100644 --- a/resources/web/guide/24/index.html +++ b/resources/web/guide/24/index.html @@ -99,4 +99,17 @@ + diff --git a/resources/web/guide/js/common.js b/resources/web/guide/js/common.js index e69de29bb2..b0aafeaf37 100644 --- a/resources/web/guide/js/common.js +++ b/resources/web/guide/js/common.js @@ -0,0 +1,21 @@ +function ClosePage() { + var tSend = {}; + tSend['sequence_id'] = Math.round(new Date() / 1000); + tSend['command'] = "close_page"; + SendWXMessage(JSON.stringify(tSend)); +} + +document.onkeydown = function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + + if (window.event) { + try { e.keyCode = 0; } catch (e) { } + e.returnValue = false; + } +}; + +window.addEventListener('wheel', function (event) { + if (event.ctrlKey === true || event.metaKey) { + event.preventDefault(); + } +}, { passive: false }); diff --git a/resources/web/homepage/css/home.css b/resources/web/homepage/css/home.css index 6e2c322dd4..e25c9570f6 100644 --- a/resources/web/homepage/css/home.css +++ b/resources/web/homepage/css/home.css @@ -33,6 +33,12 @@ html, body { text-decoration:underline; } +/*------------------*/ +#DebugText +{ + height:30px; +} + /*------------------*/ body { @@ -208,6 +214,7 @@ body padding: 0px 40px; display: flex; flex-direction: column; + position: relative; } #MenuArea @@ -274,9 +281,31 @@ body flex-direction: column; } +#RecentTitleBlock +{ + display:flex; + align-items: center; + padding: 6px; + border-bottom: 1px solid #D9D9D9; +} + +#RecentClearAllBtn +{ + border: 1px solid #C4C4C4; + padding: 0px 10px; + border-radius: 6px; + line-height: 26px; + height: 26px; + margin-left: 20px; + cursor: pointer; + background-color: #00AE42; + color: #fff; + display: inline; +} + #RecentTitle { - border-bottom: 1px solid #D9D9D9; + } #FileList @@ -331,6 +360,68 @@ body color: #A8A8A8; } +#recnet_context_menu +{ + position: absolute; + margin: 0px; + padding: 0px; + border: 0px; + min-width: 100px; + top: 800px; + border: 1px solid #C5C5C5; + border-radius: 6px; + background-color: #fff; +} + +.CT_Item +{ + line-height:30px; + padding: 0px 10px; + display: flex; + flex-direction: row; + align-content: center; + align-items: center; +} + +.CT_Item:hover +{ + background-color: #E9E9E9; + cursor: pointer; +} + + +.CT_Icon +{ + margin-right: 6px; + width: 16px; + height: 16px; +} + +.CT_Delete +{ + background: url("../img/delete.png"); + background-repeat: no-repeat; + background-size: contain; +} + +.CT_Explore +{ + background: url("../img/folder.png"); + background-repeat: no-repeat; + background-size: contain; +} + + +.CT_Seperate +{ + border-bottom:1px solid #C5C5C5; +} + +.CT_Text +{ + +} + /*--------Mall------*/ #MallBoard { @@ -363,4 +454,59 @@ body width: 100%; height: 95%; border: 1px solid #D9D9D9; -} \ No newline at end of file +} + + +/*---------Wiki----------*/ +#WikiGuideBigBoard +{ + display:none; +} + + +#WikiGuideBoard +{ + display: flex; + flex-wrap: wrap; + align-content: flex-start; + overflow-y: auto; + padding: 50px; +} + +.GuideBlock +{ + width: 320px; + margin: 0px; + margin: 0px 12px 30px 12px; + cursor: pointer; +} + +.UG_IMG +{ + width: 320px; + height: 200px; +} + +.UG_IMG img +{ + width: 320px; + height: 200px; +} + +.UG_TITLE +{ + font-size: 16px; + line-height: 20px; + width: 320px; + margin-top: 6px; +} + +.UG_DESC +{ + width: 320px; + line-height: 18px; + color: #C4C4C4; + font-size: 14px; +} + + diff --git a/resources/web/homepage/img/delete.png b/resources/web/homepage/img/delete.png new file mode 100644 index 0000000000..3f857a1a28 Binary files /dev/null and b/resources/web/homepage/img/delete.png differ diff --git a/resources/web/homepage/img/folder.png b/resources/web/homepage/img/folder.png new file mode 100644 index 0000000000..cc5b345320 Binary files /dev/null and b/resources/web/homepage/img/folder.png differ diff --git a/resources/web/homepage/img/wiki.png b/resources/web/homepage/img/wiki.png new file mode 100644 index 0000000000..c6a19f4698 Binary files /dev/null and b/resources/web/homepage/img/wiki.png differ diff --git a/resources/web/homepage/img/wiki2.png b/resources/web/homepage/img/wiki2.png new file mode 100644 index 0000000000..7a867d41a2 Binary files /dev/null and b/resources/web/homepage/img/wiki2.png differ diff --git a/resources/web/homepage/img/wiki3.png b/resources/web/homepage/img/wiki3.png new file mode 100644 index 0000000000..f5a52c2e36 Binary files /dev/null and b/resources/web/homepage/img/wiki3.png differ diff --git a/resources/web/homepage/index.html b/resources/web/homepage/index.html index d05753b885..9f562225b8 100644 --- a/resources/web/homepage/index.html +++ b/resources/web/homepage/index.html @@ -10,7 +10,7 @@ - +
@@ -39,8 +39,11 @@
recent
+
+
+
UserGuide
+
-
@@ -63,16 +66,21 @@
+
+
-
recent open
+
+
recent open
+
Clear all
+
- +
-->
+ +
+
+
+
clear
+
+
+
+
open in explorer
+
+
+ + + + +
+
+
+
+
Quick Start
+
This article instroduces the most basic usage of Bambu Studio. It guides users to configure software, create projects, and complete the first printing task step by step.
+
+
+
+
Project Based Workflow
+
Bambu Studio has put forward a leading workflow to truly achieve an “all in one” project. Based on the mainstream 3MF project format, it provides a series of revolutionary new features, such as Multi-Plate Support, a Project Resource Manager, and Assembly/Part View. It greatly improves the efficiency of both creators and regular users.
+
+
+
+
High Speed Print at Quality
+
It is challenging to print at high speed while maintaining high quality. Bambu Studio makes this happen. + "Arch Move" makes the toolhead move smoothly and reduces the machine's vibration. The smart cooling is based on fine-tunned cooling parameters for each filament type. + Auto slow down for overhang walls works to prevent deformation at high speeds.
+
+
+
+
Multi-Color Printing
+
Bambu Studio provides versatile colorizing tools to make a colorful model. You can freely add/remove filaments in a project and colorize your model with different brushes. Before printing, each filament will be auto-mapped to an AMS slot, not needing to manually change the spool placement in the AMS.
+
+
+
+
Setting Guide of Slicing Parameters
+
The parameter management features in Bambu Studio provide very flexible and powerful control over the slicing process. This article introduces the organization of parameters and provides some skills on taking full advantage of these capabilities.
+
+
+
+
Remote Control & Monitoring
+
We support sending G-code to your printer over WAN/LAN network, controlling & monitoring every aspect of your 3D printer and printing jobs, and updating firmware over the air. If you have more than one printer, you can easily switch between them in the device list.
+
+
+
+
STEP Format
+
Compared with STL, STEP brings more effective information. Thanks to the high accuracy of STEP, a lot of extrusion paths can be generated as arcs. STEP also includes the assembly relationship of each parts of a model, which can be used to identify the exterior surface and restore the assembly view after a model is split.
+
+
+
+
3D Text
+
With 3D Text tool, users can easily create any 3D text shape in a project. Users can freely create 3D text content to make modles more personalized. Bambu Studio provides dozens of fonts and supports bold and italic styles to give text greater flexibility.
+
+
diff --git a/resources/web/homepage/js/home.js b/resources/web/homepage/js/home.js index e1bcdd8e8b..a37539bef0 100644 --- a/resources/web/homepage/js/home.js +++ b/resources/web/homepage/js/home.js @@ -14,6 +14,68 @@ function OnInit() SendMsg_GetRecentFile(); } +//------最佳打开文件的右键菜单功能---------- +var RightBtnFilePath=''; + +var MousePosX=0; +var MousePosY=0; + +function Set_RecentFile_MouseRightBtn_Event() +{ + $(".FileItem").mousedown( + function(e) + { + //FilePath + RightBtnFilePath=$(this).attr('fpath'); + + if(e.which == 3){ + //鼠标点击了右键+$(this).attr('ff') ); + ShowRecnetFileContextMenu(); + }else if(e.which == 2){ + //鼠标点击了中键 + }else if(e.which == 1){ + //鼠标点击了左键 + OnOpenRecentFile( encodeURI(RightBtnFilePath) ); + } + }); + + $(document).bind("contextmenu",function(e){ + //在这里书写代码,构建个性右键化菜单 + return false; + }); + + $(document).mousemove( function(e){ + MousePosX=e.pageX; + MousePosY=e.pageY; + + let ContextMenuWidth=$('#recnet_context_menu').width(); + let ContextMenuHeight=$('#recnet_context_menu').height(); + + let DocumentWidth=$(document).width(); + let DocumentHeight=$(document).height(); + + //$("#DebugText").text( ContextMenuWidth+' - '+ContextMenuHeight+'
'+ + // DocumentWidth+' - '+DocumentHeight+'
'+ + // MousePosX+' - '+MousePosY +'
' ); + } ); + + + $(document).click( function(){ + var e = e || window.event; +        var elem = e.target || e.srcElement; +        while (elem) { + if (elem.id && elem.id == 'recnet_context_menu') { +                    return; + } + elem = elem.parentNode; + } + + $("#recnet_context_menu").hide(); + } ); + + +} + function HandleStudio( pVal ) { @@ -123,7 +185,7 @@ function ShowRecentFileList( pList ) //let index=sPath.lastIndexOf('\\')>0?sPath.lastIndexOf('\\'):sPath.lastIndexOf('\/'); //let sShortName=sPath.substring(index+1,sPath.length); - let TmpHtml='
'+ + let TmpHtml='
'+ ''+ '
No Image
'+ ''+sName+''+ @@ -134,10 +196,33 @@ function ShowRecentFileList( pList ) } $("#FileList").html(strHtml); + + Set_RecentFile_MouseRightBtn_Event(); + UpdateRecentClearBtnDisplay(); } +function ShowRecnetFileContextMenu() +{ + $('#recnet_context_menu').show(); + + let ContextMenuWidth=$('#recnet_context_menu').width(); + let ContextMenuHeight=$('#recnet_context_menu').height(); + + let DocumentWidth=$(document).width(); + let DocumentHeight=$(document).height(); -/*-------MX Message------*/ + let RealX=MousePosX; + let RealY=MousePosY; + + if( MousePosX + ContextMenuWidth >DocumentWidth ) + RealX=MousePosX-ContextMenuWidth; + if( MousePosY+ContextMenuHeight>DocumentHeight ) + RealY=MousePosY-ContextMenuHeight; + + $("#recnet_context_menu").offset({top: RealY, left:RealX}); +} + +/*-------RecentFile MX Message------*/ function SendMsg_GetLoginInfo() { var tSend={}; @@ -197,6 +282,69 @@ function OnOpenRecentFile( strPath ) SendWXMessage( JSON.stringify(tSend) ); } +function OnDeleteRecentFile( ) +{ + var tSend={}; + tSend['sequence_id']=Math.round(new Date() / 1000); + tSend['command']="homepage_delete_recentfile"; + tSend['data']={}; + tSend['data']['path']=decodeURI(RightBtnFilePath); + + SendWXMessage( JSON.stringify(tSend) ); + + $("#recnet_context_menu").hide(); + + let AllFile=$(".FileItem"); + let nFile=AllFile.length; + for(let p=0;p0 ) + $("#RecentClearAllBtn").show(); + else + $("#RecentClearAllBtn").hide(); +} + + + + +function OnExploreRecentFile( ) +{ + var tSend={}; + tSend['sequence_id']=Math.round(new Date() / 1000); + tSend['command']="homepage_explore_recentfile"; + tSend['data']={}; + tSend['data']['path']=decodeURI(RightBtnFilePath); + + SendWXMessage( JSON.stringify(tSend) ); + + $("#recnet_context_menu").hide(); +} + function OnLogOut() { var tSend={}; @@ -227,4 +375,20 @@ function OutputKey(keyCode, isCtrlDown, isShiftDown, isCmdDown) { SendWXMessage(JSON.stringify(tSend)); } + +//-------------User Manual------------ + +function OpenWikiUrl( strUrl ) +{ + var tSend={}; + tSend['sequence_id']=Math.round(new Date() / 1000); + tSend['command']="userguide_wiki_open"; + tSend['data']={}; + tSend['data']['url']=strUrl; + + SendWXMessage( JSON.stringify(tSend) ); +} + + +//---------------Global----------------- window.postMessage = HandleStudio; diff --git a/src/BambuStudio_app_msvc.cpp b/src/BambuStudio_app_msvc.cpp index 9c9014a8e6..5dfc4c4635 100644 --- a/src/BambuStudio_app_msvc.cpp +++ b/src/BambuStudio_app_msvc.cpp @@ -14,8 +14,8 @@ extern "C" { // Let the NVIDIA and AMD know we want to use their graphics card // on a dual graphics card system. - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000000; + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0; } #endif /* SLIC3R_GUI */ diff --git a/src/admesh/stl.h b/src/admesh/stl.h index 28d5ee1553..65527e6f6b 100644 --- a/src/admesh/stl.h +++ b/src/admesh/stl.h @@ -45,6 +45,8 @@ typedef Eigen::Matrix stl_triangle_vertex_indices static_assert(sizeof(stl_vertex) == 12, "size of stl_vertex incorrect"); static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect"); +typedef std::function ImportstlProgressFn; + typedef enum { eNormal, // normal face eSmallOverhang, // small overhang @@ -244,7 +246,7 @@ struct indexed_triangle_set } }; -extern bool stl_open(stl_file *stl, const char *file); +extern bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn = nullptr); extern void stl_stats_out(stl_file *stl, FILE *file, char *input_file); extern bool stl_print_neighbors(stl_file *stl, char *file); extern bool stl_write_ascii(stl_file *stl, const char *file, const char *label); @@ -398,7 +400,7 @@ extern void stl_calculate_volume(stl_file *stl); extern void stl_repair(stl_file *stl, bool fixall_flag, bool exact_flag, bool tolerance_flag, float tolerance, bool increment_flag, float increment, bool nearby_flag, int iterations, bool remove_unconnected_flag, bool fill_holes_flag, bool normal_directions_flag, bool normal_values_flag, bool reverse_all_flag, bool verbose_flag); extern void stl_allocate(stl_file *stl); -extern void stl_read(stl_file *stl, int first_facet, bool first); +extern void stl_read(stl_file *stl, int first_facet, bool first, ImportstlProgressFn stlFn = nullptr); extern void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first); extern void stl_reallocate(stl_file *stl); extern void stl_add_facet(stl_file *stl, const stl_facet *new_facet); diff --git a/src/admesh/stlinit.cpp b/src/admesh/stlinit.cpp index 29131b1c75..f1be4ac77c 100644 --- a/src/admesh/stlinit.cpp +++ b/src/admesh/stlinit.cpp @@ -31,6 +31,7 @@ #include #include "stl.h" +#include "libslic3r/Format/STL.hpp" #include "libslic3r/LocalesUtils.hpp" @@ -42,6 +43,8 @@ extern void stl_internal_reverse_quads(char *buf, size_t cnt); #endif /* BOOST_ENDIAN_BIG_BYTE */ +const int LOAD_STL_UNIT_NUM = 5; + static FILE* stl_open_count_facets(stl_file *stl, const char *file) { // Open the file in binary mode first. @@ -145,7 +148,7 @@ static FILE* stl_open_count_facets(stl_file *stl, const char *file) /* Reads the contents of the file pointed to by fp into the stl structure, starting at facet first_facet. The second argument says if it's our first time running this for the stl and therefore we should reset our max and min stats. */ -static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) +static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first, ImportstlProgressFn stlFn) { if (stl->stats.type == binary) fseek(fp, HEADER_SIZE, SEEK_SET); @@ -153,7 +156,19 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) rewind(fp); char normal_buf[3][32]; - for (uint32_t i = first_facet; i < stl->stats.number_of_facets; ++ i) { + + uint32_t facets_num = stl->stats.number_of_facets; + uint32_t unit = facets_num / LOAD_STL_UNIT_NUM + 1; + for (uint32_t i = first_facet; i < facets_num; ++ i) { + if ((i % unit) == 0) { + bool cb_cancel = false; + if (stlFn) { + stlFn(i, facets_num, cb_cancel); + if (cb_cancel) + return false; + } + } + stl_facet facet; if (stl->stats.type == binary) { @@ -232,7 +247,7 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) return true; } -bool stl_open(stl_file *stl, const char *file) +bool stl_open(stl_file *stl, const char *file, ImportstlProgressFn stlFn) { Slic3r::CNumericLocalesSetter locales_setter; stl->clear(); @@ -240,7 +255,7 @@ bool stl_open(stl_file *stl, const char *file) if (fp == nullptr) return false; stl_allocate(stl); - bool result = stl_read(stl, fp, 0, true); + bool result = stl_read(stl, fp, 0, true, stlFn); fclose(fp); return result; } diff --git a/src/imgui/imgui.h b/src/imgui/imgui.h index 4b3c13ac60..4aa9dac3e9 100644 --- a/src/imgui/imgui.h +++ b/src/imgui/imgui.h @@ -491,6 +491,7 @@ namespace ImGui IMGUI_API bool ImageButton2(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec2& margin = ImVec2(0, 0)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool ImageTextButton(const ImVec2& button_size, const char* text, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec2& margin = ImVec2(0, 0)); IMGUI_API bool ImageButton3(ImTextureID user_texture_id,ImTextureID user_texture_id_hover, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec2& margin = ImVec2(0, 0)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API bool BBLImageButton(ImTextureID user_texture_id,ImTextureID user_texture_id_hover,ImTextureID user_texture_id_press, const ImVec2& size, bool &value, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec2& margin = ImVec2(0, 0)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool Checkbox(const char* label, bool* v); IMGUI_API bool BBLCheckbox(const char* label, bool* v); IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value); diff --git a/src/imgui/imgui_internal.h b/src/imgui/imgui_internal.h index c49ec09635..018654d8a0 100644 --- a/src/imgui/imgui_internal.h +++ b/src/imgui/imgui_internal.h @@ -2554,6 +2554,7 @@ namespace ImGui IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col); IMGUI_API bool ImageButtonEx2(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, const ImVec2& margin); IMGUI_API bool ImageButtonEx3(ImGuiID id, ImTextureID texture_id,ImTextureID texture_id_hover, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, const ImVec2& margin); + IMGUI_API bool BBLImageButtonEx(ImGuiID id, ImTextureID texture_id,ImTextureID texture_id_hover,ImTextureID texture_id_press, const ImVec2& size, bool &value, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col, const ImVec2& margin); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners diff --git a/src/imgui/imgui_widgets.cpp b/src/imgui/imgui_widgets.cpp index a9b59d241b..fc09d6063f 100644 --- a/src/imgui/imgui_widgets.cpp +++ b/src/imgui/imgui_widgets.cpp @@ -1205,6 +1205,40 @@ bool ImGui::ImageButtonEx3(ImGuiID id,ImTextureID texture_id,ImTextureID tex return pressed; } +bool ImGui::BBLImageButtonEx(ImGuiID id,ImTextureID texture_id,ImTextureID texture_id_hover, ImTextureID texture_id_press, const ImVec2 &size, bool &value,const ImVec2 &uv0,const ImVec2 &uv1,const ImVec2 &padding,const ImVec4 &bg_col,const ImVec4 &tint_col,const ImVec2 &margin) +{ + ImGuiContext &g = *GImGui; + ImGuiWindow * window = GetCurrentWindow(); + if (window->SkipItems) return false; + + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2 + margin * 2); + ItemSize(bb); + if (!ItemAdd(bb, id)) return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + if (pressed) value = !value; + + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) { + window->DrawList->AddRect(bb.Min + ImVec2(1, 1), bb.Max + ImVec2(1, 1), col, g.Style.FrameRounding, 0, border_size); + window->DrawList->AddRect(bb.Min, bb.Max, col, g.Style.FrameRounding, 0, border_size); + } + + if (bg_col.w > 0.0f) window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col)); + + window->DrawList->AddImage(texture_id, bb.Min + padding + margin, bb.Max - padding - margin, uv0, uv1, GetColorU32(tint_col)); + + if (hovered)window->DrawList->AddImage(texture_id_hover, bb.Min + padding + margin, bb.Max - padding - margin, uv0, uv1, GetColorU32(tint_col)); + + if (value)window->DrawList->AddImage(texture_id_press, bb.Min + padding + margin, bb.Max - padding - margin, uv0, uv1, GetColorU32(tint_col)); + + return pressed; +} bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) { @@ -1256,6 +1290,20 @@ bool ImGui::ImageButton3(ImTextureID user_texture_id,ImTextureID user_texture_id return ImageButtonEx3(id, user_texture_id, user_texture_id_hover, size, uv0, uv1, padding, bg_col, tint_col, margin); } +bool ImGui::BBLImageButton(ImTextureID user_texture_id,ImTextureID user_texture_id_hover, ImTextureID user_texture_id_press, const ImVec2 &size, bool &value, const ImVec2 &uv0, const ImVec2 &uv1, int frame_padding, const ImVec4 &bg_col, const ImVec4 &tint_col, const ImVec2 &margin) +{ + ImGuiContext &g = *GImGui; + ImGuiWindow * window = g.CurrentWindow; + if (window->SkipItems) return false; + + // Default to using texture ID as ID. User can still push string/integer prefixes. + PushID((void *) (intptr_t) user_texture_id); + const ImGuiID id = window->GetID("#image"); + PopID(); + + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float) frame_padding, (float) frame_padding) : g.Style.FramePadding; + return BBLImageButtonEx(id, user_texture_id, user_texture_id_hover, user_texture_id_press, size,value, uv0, uv1, padding, bg_col, tint_col, margin); +} bool ImGui::ImageTextButton(const ImVec2& button_size, const char* text, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col, const ImVec2& margin) { @@ -3767,16 +3815,18 @@ bool ImGui::BBLSliderScalar(const char *label, ImGuiDataType data_type, void *p_ // Render grab if (grab_bb.Max.x > grab_bb.Min.x) { - float offset = 1.0f; - ImVec2 p1 = ImVec2((grab_bb.Min.x + grab_bb.Max.x) / 2, (grab_bb.Min.y + grab_bb.Max.y) / 2 - offset); - ImVec2 p2 = ImVec2(grab_bb.Min.x, grab_bb.Max.y); - ImVec2 p3 = ImVec2(grab_bb.Max.x, grab_bb.Max.y); + float line_high = 2.0f; + const float offset = 2.0f; + + ImVec2 p1 = ImVec2((grab_bb.Min.x + grab_bb.Max.x) / 2, (grab_bb.Min.y + grab_bb.Max.y) / 2 + offset); + ImVec2 p2 = ImVec2(grab_bb.Min.x, grab_bb.Max.y + offset); + ImVec2 p3 = ImVec2(grab_bb.Max.x, grab_bb.Max.y + offset); window->DrawList->AddTriangleFilled(p1, p2, p3, GetColorU32(ImGuiCol_SliderGrabActive)); ImVec2 start_pos = ImVec2(frame_bb.Min.x, frame_bb.GetCenter().y - offset); - ImVec2 curr_pos = ImVec2(grab_bb.GetCenter().x, frame_bb.GetCenter().y + offset); - ImVec2 end_pos = ImVec2(frame_bb.Max.x, frame_bb.GetCenter().y + offset); - window->DrawList->AddRectFilled(start_pos, curr_pos, GetColorU32(ImGuiCol_SliderGrabActive), style.GrabRounding); + ImVec2 curr_pos = ImVec2(grab_bb.GetCenter().x, frame_bb.GetCenter().y + line_high - offset); + ImVec2 end_pos = ImVec2(frame_bb.Max.x, frame_bb.GetCenter().y + line_high - offset); window->DrawList->AddRectFilled(start_pos, end_pos, GetColorU32(ImGuiCol_SliderGrab), style.GrabRounding); + window->DrawList->AddRectFilled(start_pos, curr_pos, GetColorU32(ImGuiCol_SliderGrabActive), style.GrabRounding); } if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -6244,9 +6294,9 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl RenderFrameBorder(bb.Min, bb.Max, rounding); else #ifdef __APPLE__ - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding,NULL,2.0f); // Color button are often in need of some sort of border + window->DrawList->AddRect(bb.Min - ImVec2(3, 3), bb.Max + ImVec2(3, 3), GetColorU32(ImGuiCol_FrameBg), rounding * 2,NULL,4.0f);; // Color button are often in need of some sort of border #else - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + window->DrawList->AddRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2), GetColorU32(ImGuiCol_FrameBg), rounding * 2,NULL,3.0f); // Color button are often in need of some sort of border #endif } diff --git a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp index 2cf356401f..29de288b9a 100644 --- a/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp +++ b/src/libnest2d/include/libnest2d/placers/nfpplacer.hpp @@ -67,7 +67,7 @@ struct NfpPConfig { * the already packed items. * */ - std::function&)> object_function; + std::function&, const ItemGroup&)> object_function; /** * @brief The quality of search for an optimal placement. @@ -666,7 +666,7 @@ private: // This is the kernel part of the object function that is // customizable by the library client std::function _objfunc; - if(config_.object_function) _objfunc = config_.object_function; + if (config_.object_function) _objfunc = [this](const Item& item) {return config_.object_function(item, this->items_); }; else { // Inside check has to be strict if no alignment was enabled diff --git a/src/libslic3r/AABBTreeIndirect.hpp b/src/libslic3r/AABBTreeIndirect.hpp index 217166f8c7..9b9c886ecc 100644 --- a/src/libslic3r/AABBTreeIndirect.hpp +++ b/src/libslic3r/AABBTreeIndirect.hpp @@ -446,6 +446,57 @@ namespace detail { } } + // Real-time collision detection, Ericson, Chapter 5 + template + static inline Vector closest_point_to_triangle(const Vector &p, const Vector &a, const Vector &b, const Vector &c) + { + using Scalar = typename Vector::Scalar; + // Check if P in vertex region outside A + Vector ab = b - a; + Vector ac = c - a; + Vector ap = p - a; + Scalar d1 = ab.dot(ap); + Scalar d2 = ac.dot(ap); + if (d1 <= 0 && d2 <= 0) + return a; + // Check if P in vertex region outside B + Vector bp = p - b; + Scalar d3 = ab.dot(bp); + Scalar d4 = ac.dot(bp); + if (d3 >= 0 && d4 <= d3) + return b; + // Check if P in edge region of AB, if so return projection of P onto AB + Scalar vc = d1*d4 - d3*d2; + if (a != b && vc <= 0 && d1 >= 0 && d3 <= 0) { + Scalar v = d1 / (d1 - d3); + return a + v * ab; + } + // Check if P in vertex region outside C + Vector cp = p - c; + Scalar d5 = ab.dot(cp); + Scalar d6 = ac.dot(cp); + if (d6 >= 0 && d5 <= d6) + return c; + // Check if P in edge region of AC, if so return projection of P onto AC + Scalar vb = d5*d2 - d1*d6; + if (vb <= 0 && d2 >= 0 && d6 <= 0) { + Scalar w = d2 / (d2 - d6); + return a + w * ac; + } + // Check if P in edge region of BC, if so return projection of P onto BC + Scalar va = d3*d6 - d5*d4; + if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0) { + Scalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + return b + w * (c - b); + } + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + Scalar denom = Scalar(1.0) / (va + vb + vc); + Scalar v = vb * denom; + Scalar w = vc * denom; + return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = 1.0-v-w + }; + + // Nothing to do with COVID-19 social distancing. template struct IndexedTriangleSetDistancer { @@ -453,74 +504,36 @@ namespace detail { using IndexedFaceType = AIndexedFaceType; using TreeType = ATreeType; using VectorType = AVectorType; + using ScalarType = typename VectorType::Scalar; const std::vector &vertices; const std::vector &faces; const TreeType &tree; const VectorType origin; + + inline VectorType closest_point_to_origin(size_t primitive_index, + ScalarType& squared_distance){ + const auto &triangle = this->faces[primitive_index]; + VectorType closest_point = closest_point_to_triangle(origin, + this->vertices[triangle(0)].template cast(), + this->vertices[triangle(1)].template cast(), + this->vertices[triangle(2)].template cast()); + squared_distance = (origin - closest_point).squaredNorm(); + return closest_point; + } }; - // Real-time collision detection, Ericson, Chapter 5 - template - static inline Vector closest_point_to_triangle(const Vector &p, const Vector &a, const Vector &b, const Vector &c) - { - using Scalar = typename Vector::Scalar; - // Check if P in vertex region outside A - Vector ab = b - a; - Vector ac = c - a; - Vector ap = p - a; - Scalar d1 = ab.dot(ap); - Scalar d2 = ac.dot(ap); - if (d1 <= 0 && d2 <= 0) - return a; - // Check if P in vertex region outside B - Vector bp = p - b; - Scalar d3 = ab.dot(bp); - Scalar d4 = ac.dot(bp); - if (d3 >= 0 && d4 <= d3) - return b; - // Check if P in edge region of AB, if so return projection of P onto AB - Scalar vc = d1*d4 - d3*d2; - if (a != b && vc <= 0 && d1 >= 0 && d3 <= 0) { - Scalar v = d1 / (d1 - d3); - return a + v * ab; - } - // Check if P in vertex region outside C - Vector cp = p - c; - Scalar d5 = ab.dot(cp); - Scalar d6 = ac.dot(cp); - if (d6 >= 0 && d5 <= d6) - return c; - // Check if P in edge region of AC, if so return projection of P onto AC - Scalar vb = d5*d2 - d1*d6; - if (vb <= 0 && d2 >= 0 && d6 <= 0) { - Scalar w = d2 / (d2 - d6); - return a + w * ac; - } - // Check if P in edge region of BC, if so return projection of P onto BC - Scalar va = d3*d6 - d5*d4; - if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0) { - Scalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - return b + w * (c - b); - } - // P inside face region. Compute Q through its barycentric coordinates (u,v,w) - Scalar denom = Scalar(1.0) / (va + vb + vc); - Scalar v = vb * denom; - Scalar w = vc * denom; - return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = 1.0-v-w - }; - - template - static inline Scalar squared_distance_to_indexed_triangle_set_recursive( - IndexedTriangleSetDistancerType &distancer, + template + static inline Scalar squared_distance_to_indexed_primitives_recursive( + IndexedPrimitivesDistancerType &distancer, size_t node_idx, Scalar low_sqr_d, Scalar up_sqr_d, size_t &i, - Eigen::PlainObjectBase &c) + Eigen::PlainObjectBase &c) { - using Vector = typename IndexedTriangleSetDistancerType::VectorType; + using Vector = typename IndexedPrimitivesDistancerType::VectorType; if (low_sqr_d > up_sqr_d) return low_sqr_d; @@ -538,13 +551,9 @@ namespace detail { assert(node.is_valid()); if (node.is_leaf()) { - const auto &triangle = distancer.faces[node.idx]; - Vector c_candidate = closest_point_to_triangle( - distancer.origin, - distancer.vertices[triangle(0)].template cast(), - distancer.vertices[triangle(1)].template cast(), - distancer.vertices[triangle(2)].template cast()); - set_min((c_candidate - distancer.origin).squaredNorm(), node.idx, c_candidate); + Scalar sqr_dist; + Vector c_candidate = distancer.closest_point_to_origin(node.idx, sqr_dist); + set_min(sqr_dist, node.idx, c_candidate); } else { @@ -561,7 +570,7 @@ namespace detail { { size_t i_left; Vector c_left = c; - Scalar sqr_d_left = squared_distance_to_indexed_triangle_set_recursive(distancer, left_node_idx, low_sqr_d, up_sqr_d, i_left, c_left); + Scalar sqr_d_left = squared_distance_to_indexed_primitives_recursive(distancer, left_node_idx, low_sqr_d, up_sqr_d, i_left, c_left); set_min(sqr_d_left, i_left, c_left); looked_left = true; }; @@ -569,13 +578,13 @@ namespace detail { { size_t i_right; Vector c_right = c; - Scalar sqr_d_right = squared_distance_to_indexed_triangle_set_recursive(distancer, right_node_idx, low_sqr_d, up_sqr_d, i_right, c_right); + Scalar sqr_d_right = squared_distance_to_indexed_primitives_recursive(distancer, right_node_idx, low_sqr_d, up_sqr_d, i_right, c_right); set_min(sqr_d_right, i_right, c_right); looked_right = true; }; // must look left or right if in box - using BBoxScalar = typename IndexedTriangleSetDistancerType::TreeType::BoundingBox::Scalar; + using BBoxScalar = typename IndexedPrimitivesDistancerType::TreeType::BoundingBox::Scalar; if (node_left.bbox.contains(distancer.origin.template cast())) look_left(); if (node_right.bbox.contains(distancer.origin.template cast())) @@ -709,10 +718,15 @@ inline bool intersect_ray_all_hits( origin, dir, VectorType(dir.cwiseInverse()), eps } }; - if (! tree.empty()) { + if (tree.empty()) { + hits.clear(); + } else { + // Reusing the output memory if there is some memory already pre-allocated. + ray_intersector.hits = std::move(hits); + ray_intersector.hits.clear(); ray_intersector.hits.reserve(8); detail::intersect_ray_recursive_all_hits(ray_intersector, 0); - std::swap(hits, ray_intersector.hits); + hits = std::move(ray_intersector.hits); std::sort(hits.begin(), hits.end(), [](const auto &l, const auto &r) { return l.t < r.t; }); } return ! hits.empty(); @@ -742,7 +756,7 @@ inline typename VectorType::Scalar squared_distance_to_indexed_triangle_set( auto distancer = detail::IndexedTriangleSetDistancer { vertices, faces, tree, point }; return tree.empty() ? Scalar(-1) : - detail::squared_distance_to_indexed_triangle_set_recursive(distancer, size_t(0), Scalar(0), std::numeric_limits::infinity(), hit_idx_out, hit_point_out); + detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), std::numeric_limits::infinity(), hit_idx_out, hit_point_out); } // Decides if exists some triangle in defined radius on a 3D indexed triangle set using a pre-built AABBTreeIndirect::Tree. @@ -759,22 +773,22 @@ inline bool is_any_triangle_in_radius( const TreeType &tree, // Point to which the closest point on the indexed triangle set is searched for. const VectorType &point, - // Maximum distance in which triangle is search for - typename VectorType::Scalar &max_distance) + //Square of maximum distance in which triangle is searched for + typename VectorType::Scalar &max_distance_squared) { using Scalar = typename VectorType::Scalar; auto distancer = detail::IndexedTriangleSetDistancer { vertices, faces, tree, point }; - size_t hit_idx; - VectorType hit_point = VectorType::Ones() * (std::nan("")); + size_t hit_idx; + VectorType hit_point = VectorType::Ones() * (NaN); if(tree.empty()) { return false; } - detail::squared_distance_to_indexed_triangle_set_recursive(distancer, size_t(0), Scalar(0), max_distance, hit_idx, hit_point); + detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), max_distance_squared, hit_idx, hit_point); return hit_point.allFinite(); } diff --git a/src/libslic3r/AABBTreeLines.hpp b/src/libslic3r/AABBTreeLines.hpp new file mode 100644 index 0000000000..7b9595419a --- /dev/null +++ b/src/libslic3r/AABBTreeLines.hpp @@ -0,0 +1,112 @@ +#ifndef SRC_LIBSLIC3R_AABBTREELINES_HPP_ +#define SRC_LIBSLIC3R_AABBTREELINES_HPP_ + +#include "libslic3r/Point.hpp" +#include "libslic3r/EdgeGrid.hpp" +#include "libslic3r/AABBTreeIndirect.hpp" +#include "libslic3r/Line.hpp" + +namespace Slic3r { + +namespace AABBTreeLines { + +namespace detail { + +template +struct IndexedLinesDistancer { + using LineType = ALineType; + using TreeType = ATreeType; + using VectorType = AVectorType; + using ScalarType = typename VectorType::Scalar; + + const std::vector &lines; + const TreeType &tree; + + const VectorType origin; + + inline VectorType closest_point_to_origin(size_t primitive_index, + ScalarType &squared_distance) { + VectorType nearest_point; + const LineType &line = lines[primitive_index]; + squared_distance = line_alg::distance_to_squared(line, origin, &nearest_point); + return nearest_point; + } +}; + +} + +// Build a balanced AABB Tree over a vector of float lines, balancing the tree +// on centroids of the lines. +// Epsilon is applied to the bounding boxes of the AABB Tree to cope with numeric inaccuracies +// during tree traversal. +template +inline AABBTreeIndirect::Tree<2, typename LineType::Scalar> build_aabb_tree_over_indexed_lines( + const std::vector &lines, + //FIXME do we want to apply an epsilon? + const float eps = 0) + { + using TreeType = AABBTreeIndirect::Tree<2, typename LineType::Scalar>; +// using CoordType = typename TreeType::CoordType; + using VectorType = typename TreeType::VectorType; + using BoundingBox = typename TreeType::BoundingBox; + + struct InputType { + size_t idx() const { + return m_idx; + } + const BoundingBox& bbox() const { + return m_bbox; + } + const VectorType& centroid() const { + return m_centroid; + } + + size_t m_idx; + BoundingBox m_bbox; + VectorType m_centroid; + }; + + std::vector input; + input.reserve(lines.size()); + const VectorType veps(eps, eps); + for (size_t i = 0; i < lines.size(); ++i) { + const LineType &line = lines[i]; + InputType n; + n.m_idx = i; + n.m_centroid = (line.a + line.b) * 0.5; + n.m_bbox = BoundingBox(line.a, line.a); + n.m_bbox.extend(line.b); + n.m_bbox.min() -= veps; + n.m_bbox.max() += veps; + input.emplace_back(n); + } + + TreeType out; + out.build(std::move(input)); + return out; +} + +// Finding a closest line, its closest point and squared distance to the closest point +// Returns squared distance to the closest point or -1 if the input is empty. +template +inline typename VectorType::Scalar squared_distance_to_indexed_lines( + const std::vector &lines, + const TreeType &tree, + const VectorType &point, + size_t &hit_idx_out, + Eigen::PlainObjectBase &hit_point_out) + { + using Scalar = typename VectorType::Scalar; + auto distancer = detail::IndexedLinesDistancer + { lines, tree, point }; + return tree.empty() ? + Scalar(-1) : + AABBTreeIndirect::detail::squared_distance_to_indexed_primitives_recursive(distancer, size_t(0), Scalar(0), + std::numeric_limits::infinity(), hit_idx_out, hit_point_out); +} + +} + +} + +#endif /* SRC_LIBSLIC3R_AABBTREELINES_HPP_ */ diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 3636f3b436..c8a5b274fe 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -184,10 +184,10 @@ void AppConfig::set_defaults() #ifdef _WIN32 -#ifdef SUPPORT_3D_CONNEXION +//#ifdef SUPPORT_3D_CONNEXION if (get("use_legacy_3DConnexion").empty()) - set_bool("use_legacy_3DConnexion", false); -#endif + set_bool("use_legacy_3DConnexion", true); +//#endif #ifdef SUPPORT_DARK_MODE if (get("dark_color_mode").empty()) diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index e08a3c2086..cc2f1721a3 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -447,7 +447,7 @@ protected: return std::make_tuple(score, fullbb); } - std::function get_objfn(); + std::function get_objfn(); public: AutoArranger(const TBin & bin, @@ -508,7 +508,8 @@ public: bin_poly.contour.points.emplace_back(c0.x(), c1.y()); return bin_poly; }; - + + // preload fixed items (and excluded regions) on plate m_pconf.on_preload = [this](const ItemGroup &items, PConfig &cfg) { if (items.empty()) return; @@ -527,8 +528,12 @@ public: } } - cfg.object_function = [this, bb, starting_point](const Item& item) { - return fixed_overfit_topright_sliding(objfunc(item, starting_point), bb); + cfg.object_function = [this, bb, starting_point](const Item& item, const ItemGroup& packed_items) { + bool packed_are_excluded_region = std::all_of(packed_items.begin(), packed_items.end(), [](Item& itm) { return itm.is_virt_object && !itm.is_wipe_tower; }); + if(packed_are_excluded_region) + return fixed_overfit_topright_sliding(objfunc(item, starting_point), bb); + else + return fixed_overfit(objfunc(item, starting_point), bb); }; }; @@ -597,11 +602,11 @@ public: } }; -template<> std::function AutoArranger::get_objfn() +template<> std::function AutoArranger::get_objfn() { auto origin_pack = m_pconf.starting_point == PConfig::Alignment::CENTER ? m_bin.center() : m_bin.minCorner(); - return [this, origin_pack](const Item &itm) { + return [this, origin_pack](const Item &itm, const ItemGroup&) { auto result = objfunc(itm, origin_pack); double score = std::get<0>(result); @@ -623,11 +628,11 @@ template<> std::function AutoArranger::get_objfn() }; } -template<> std::function AutoArranger::get_objfn() +template<> std::function AutoArranger::get_objfn() { auto bb = sl::boundingBox(m_bin); auto origin_pack = m_pconf.starting_point == PConfig::Alignment::CENTER ? bb.center() : bb.minCorner(); - return [this, origin_pack](const Item &item) { + return [this, origin_pack](const Item &item, const ItemGroup&) { auto result = objfunc(item, origin_pack); @@ -653,11 +658,11 @@ template<> std::function AutoArranger::get_objfn() // Specialization for a generalized polygon. // Warning: this is much slower than with Box bed. Need further speedup. template<> -std::function AutoArranger::get_objfn() +std::function AutoArranger::get_objfn() { auto bb = sl::boundingBox(m_bin); auto origin_pack = m_pconf.starting_point == PConfig::Alignment::CENTER ? bb.center() : bb.minCorner(); - return [this, origin_pack](const Item &itm) { + return [this, origin_pack](const Item &itm, const ItemGroup&) { auto result = objfunc(itm, origin_pack); double score = std::get<0>(result); diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index a7835f3e9b..cd22476f3a 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -270,7 +270,7 @@ static ExPolygons top_level_outer_brim_area(const Print &print return diff_ex(brim_area, no_brim_area); } -// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders +// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders static ExPolygons top_level_outer_brim_area(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim, const float no_brim_offset, double& brim_width_max, std::map& brim_width_map, std::map& brimAreaMap, @@ -453,7 +453,7 @@ static ExPolygons inner_brim_area(const Print &print, return diff_ex(intersection_ex(to_polygons(std::move(brim_area)), holes), no_brim_area); } -// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders +// BBS: the brims of different objs will not overlapped with each other, and are stored by objs and by extruders static ExPolygons inner_brim_area(const Print& print, const ConstPrintObjectPtrs& top_level_objects_with_brim, const float no_brim_offset, std::map& brimAreaMap, std::map& supportBrimAreaMap, @@ -875,7 +875,7 @@ static ExPolygons outer_inner_brim_area(const Print& print, for (const auto& objectWithExtruder : objPrintVec) brimToWrite.insert({ objectWithExtruder.first, {true,true} }); - std::map objectIslandMap; + ExPolygons objectIslands; for (unsigned int extruderNo : printExtruders) { ++extruderNo; @@ -906,7 +906,11 @@ static ExPolygons outer_inner_brim_area(const Print& print, std::vector groupVolumePtrs; for (auto& volumeID : volumeGroup.volume_ids) { ModelVolume* currentModelVolumePtr = nullptr; - for (auto volumePtr : object->model_object()->volumes) { + //BBS: support shared object logic + const PrintObject* shared_object = object->get_shared_object(); + if (!shared_object) + shared_object = object; + for (auto volumePtr : shared_object->model_object()->volumes) { if (volumePtr->id() == volumeID) { currentModelVolumePtr = volumePtr; break; @@ -968,7 +972,7 @@ static ExPolygons outer_inner_brim_area(const Print& print, append_and_translate(brim_area, brim_area_object, instance, print, brimAreaMap); append_and_translate(no_brim_area, no_brim_area_object, instance); append_and_translate(holes, holes_object, instance); - append_and_translate(objectIslandMap[instance.print_object->id()], objectIsland, instance); + append_and_translate(objectIslands, objectIsland, instance); } if (brimAreaMap.find(object->id()) != brimAreaMap.end()) @@ -1032,27 +1036,44 @@ static ExPolygons outer_inner_brim_area(const Print& print, } } } - for (const PrintObject* object : print.objects()) { + for (const PrintObject* object : print.objects()) if (brimAreaMap.find(object->id()) != brimAreaMap.end()) { brimAreaMap[object->id()] = diff_ex(brimAreaMap[object->id()], no_brim_area); - // BBS: brim should be contacted to at least one object island - if (objectIslandMap.find(object->id()) != objectIslandMap.end() && !objectIslandMap[object->id()].empty()) { - auto tempArea = brimAreaMap[object->id()]; - brimAreaMap[object->id()].clear(); - // the error bound is set to 2x flow width - for (auto& ta : tempArea) { - auto offsetedTa = offset_ex(ta, print.brim_flow().scaled_spacing() * 2, jtRound, SCALED_RESOLUTION); - if (!intersection_ex(offsetedTa, objectIslandMap[object->id()]).empty()) - brimAreaMap[object->id()].push_back(ta); - } - } - } - if (supportBrimAreaMap.find(object->id()) != supportBrimAreaMap.end()) supportBrimAreaMap[object->id()] = diff_ex(supportBrimAreaMap[object->id()], no_brim_area); } - //brim_area = diff_ex(brim_area, no_brim_area); + + brim_area.clear(); + for (const PrintObject* object : print.objects()) { + // BBS: brim should be contacted to at least one object's island or brim area + if (brimAreaMap.find(object->id()) != brimAreaMap.end()) { + // find other objects' brim area + ExPolygons otherExPolys; + for (const PrintObject* otherObject : print.objects()) { + if ((otherObject->id() != object->id()) && (brimAreaMap.find(otherObject->id()) != brimAreaMap.end())) { + expolygons_append(otherExPolys, brimAreaMap[otherObject->id()]); + } + } + + auto tempArea = brimAreaMap[object->id()]; + brimAreaMap[object->id()].clear(); + + for (int ia = 0; ia != tempArea.size(); ++ia) { + // find this object's other brim area + ExPolygons otherExPoly; + for (int iao = 0; iao != tempArea.size(); ++iao) + if (iao != ia) otherExPoly.push_back(tempArea[iao]); + + auto offsetedTa = offset_ex(tempArea[ia], print.brim_flow().scaled_spacing() * 2, jtRound, SCALED_RESOLUTION); + if (!intersection_ex(offsetedTa, objectIslands).empty() || + !intersection_ex(offsetedTa, otherExPoly).empty() || + !intersection_ex(offsetedTa, otherExPolys).empty()) + brimAreaMap[object->id()].push_back(tempArea[ia]); + } + expolygons_append(brim_area, brimAreaMap[object->id()]); + } + } return brim_area; } // Flip orientation of open polylines to minimize travel distance. @@ -1066,7 +1087,7 @@ static void optimize_polylines_by_reversing(Polylines *polylines) double dist_to_start = (next.first_point() - prev.last_point()).cast().norm(); double dist_to_end = (next.last_point() - prev.last_point()).cast().norm(); - if (dist_to_end < dist_to_start) + if (dist_to_end < dist_to_start) next.reverse(); } } diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index da327ec978..c6f01a65db 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -142,10 +142,12 @@ set(lisbslic3r_sources GCodeWriter.hpp Geometry.cpp Geometry.hpp + Geometry/Bicubic.hpp Geometry/Circle.cpp Geometry/Circle.hpp Geometry/ConvexHull.cpp Geometry/ConvexHull.hpp + Geometry/Curves.hpp Geometry/MedialAxis.cpp Geometry/MedialAxis.hpp Geometry/Voronoi.hpp @@ -176,6 +178,8 @@ set(lisbslic3r_sources CustomGCode.hpp Arrange.hpp Arrange.cpp + NormalUtils.cpp + NormalUtils.hpp Orient.hpp Orient.cpp MultiPoint.cpp @@ -222,6 +226,8 @@ set(lisbslic3r_sources QuadricEdgeCollapse.cpp QuadricEdgeCollapse.hpp Semver.cpp + ShortEdgeCollapse.cpp + ShortEdgeCollapse.hpp ShortestPath.cpp ShortestPath.hpp SLAPrint.cpp @@ -264,6 +270,8 @@ set(lisbslic3r_sources Thread.hpp TriangleSelector.cpp TriangleSelector.hpp + TriangleSetSampling.cpp + TriangleSetSampling.hpp MTUtils.hpp VariableWidth.cpp VariableWidth.hpp @@ -315,7 +323,6 @@ set(lisbslic3r_sources SLA/Clustering.hpp SLA/Clustering.cpp SLA/ReprojectPointsOnMesh.hpp - Arachne/BeadingStrategy/BeadingStrategy.hpp Arachne/BeadingStrategy/BeadingStrategy.cpp Arachne/BeadingStrategy/BeadingStrategyFactory.hpp @@ -356,6 +363,8 @@ set(lisbslic3r_sources Arachne/SkeletalTrapezoidationJoint.hpp Arachne/WallToolPaths.hpp Arachne/WallToolPaths.cpp + Shape/TextShape.hpp + Shape/TextShape.cpp ) if (APPLE) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 2189f649fd..537adfdcc8 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -158,11 +158,10 @@ double ExtrusionLoop::length() const return len; } -bool ExtrusionLoop::split_at_vertex(const Point &point) +bool ExtrusionLoop::split_at_vertex(const Point &point, const double scaled_epsilon) { for (ExtrusionPaths::iterator path = this->paths.begin(); path != this->paths.end(); ++path) { - int idx = path->polyline.find_point(point); - if (idx != -1) { + if (int idx = path->polyline.find_point(point, scaled_epsilon); idx != -1) { if (this->paths.size() == 1) { // just change the order of points Polyline p1, p2; @@ -207,46 +206,57 @@ bool ExtrusionLoop::split_at_vertex(const Point &point) return false; } -std::pair ExtrusionLoop::get_closest_path_and_point(const Point& point, bool prefer_non_overhang) const +ExtrusionLoop::ClosestPathPoint ExtrusionLoop::get_closest_path_and_point(const Point &point, bool prefer_non_overhang) const { // Find the closest path and closest point belonging to that path. Avoid overhangs, if asked for. - size_t path_idx = 0; - Point p; - { - double min = std::numeric_limits::max(); - Point p_non_overhang; - size_t path_idx_non_overhang = 0; - double min_non_overhang = std::numeric_limits::max(); - for (const ExtrusionPath& path : this->paths) { - Point p_tmp = point.projection_onto(path.polyline); - double dist = (p_tmp - point).cast().norm(); - if (dist < min) { - p = p_tmp; - min = dist; - path_idx = &path - &this->paths.front(); - } - if (prefer_non_overhang && !is_bridge(path.role()) && dist < min_non_overhang) { - p_non_overhang = p_tmp; - min_non_overhang = dist; - path_idx_non_overhang = &path - &this->paths.front(); - } + ClosestPathPoint out{0, 0}; + double min2 = std::numeric_limits::max(); + ClosestPathPoint best_non_overhang{0, 0}; + double min2_non_overhang = std::numeric_limits::max(); + for (const ExtrusionPath &path : this->paths) { + std::pair foot_pt_ = foot_pt(path.polyline.points, point); + double d2 = (foot_pt_.second - point).cast().squaredNorm(); + if (d2 < min2) { + out.foot_pt = foot_pt_.second; + out.path_idx = &path - &this->paths.front(); + out.segment_idx = foot_pt_.first; + min2 = d2; } - if (prefer_non_overhang && min_non_overhang != std::numeric_limits::max()) { - // Only apply the non-overhang point if there is one. - path_idx = path_idx_non_overhang; - p = p_non_overhang; + if (prefer_non_overhang && !is_bridge(path.role()) && d2 < min2_non_overhang) { + best_non_overhang.foot_pt = foot_pt_.second; + best_non_overhang.path_idx = &path - &this->paths.front(); + best_non_overhang.segment_idx = foot_pt_.first; + min2_non_overhang = d2; } } - return std::make_pair(path_idx, p); + if (prefer_non_overhang && min2_non_overhang != std::numeric_limits::max()) + // Only apply the non-overhang point if there is one. + out = best_non_overhang; + return out; } // Splitting an extrusion loop, possibly made of multiple segments, some of the segments may be bridging. -void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang) +void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang, const double scaled_epsilon) { if (this->paths.empty()) return; - auto [path_idx, p] = get_closest_path_and_point(point, prefer_non_overhang); + auto [path_idx, segment_idx, p] = get_closest_path_and_point(point, prefer_non_overhang); + + // Snap p to start or end of segment_idx if closer than scaled_epsilon. + { + const Point *p1 = this->paths[path_idx].polyline.points.data() + segment_idx; + const Point *p2 = p1; + ++p2; + double d2_1 = (point - *p1).cast().squaredNorm(); + double d2_2 = (point - *p2).cast().squaredNorm(); + const double thr2 = scaled_epsilon * scaled_epsilon; + if (d2_1 < d2_2) { + if (d2_1 < thr2) p = *p1; + } else { + if (d2_2 < thr2) p = *p2; + } + } // now split path_idx in two parts const ExtrusionPath &path = this->paths[path_idx]; diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 2fc6608000..6863a0df3b 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -314,9 +314,15 @@ public: const Point& last_point() const override { assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); } Polygon polygon() const; double length() const override; - bool split_at_vertex(const Point &point); - void split_at(const Point &point, bool prefer_non_overhang); - std::pair get_closest_path_and_point(const Point& point, bool prefer_non_overhang) const; + bool split_at_vertex(const Point &point, const double scaled_epsilon = scaled(0.001)); + void split_at(const Point &point, bool prefer_non_overhang, const double scaled_epsilon = scaled(0.001)); + struct ClosestPathPoint + { + size_t path_idx; + size_t segment_idx; + Point foot_pt; + }; + ClosestPathPoint get_closest_path_and_point(const Point &point, bool prefer_non_overhang) const; void clip_end(double distance, ExtrusionPaths* paths) const; // Test, whether the point is extruded by a bridging flow. // This used to be used to avoid placing seams on overhangs, but now the EdgeGrid is used instead. diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index 2684581fd1..2b388199be 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -31,9 +31,6 @@ const double STEP_TRANS_CHORD_ERROR = 0.005; const double STEP_TRANS_ANGLE_RES = 1; -const int LOAD_STEP_STAGE_READ_FILE = 0; -const int LOAD_STEP_STAGE_GET_SOLID = 1; -const int LOAD_STEP_STAGE_GET_MESH = 2; namespace Slic3r { @@ -213,11 +210,11 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p } } -bool load_step(const char *path, Model *model, ImportStepProgressFn proFn, StepIsUtf8Fn isUtf8Fn) +bool load_step(const char *path, Model *model, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn) { bool cb_cancel = false; - if (proFn) { - proFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel); + if (stepFn) { + stepFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel); if (cb_cancel) return false; } @@ -245,9 +242,13 @@ bool load_step(const char *path, Model *model, ImportStepProgressFn proFn, StepI unsigned int id{1}; Standard_Integer topShapeLength = topLevelShapes.Length() + 1; + auto stage_unit2 = topShapeLength / LOAD_STEP_STAGE_UNIT_NUM + 1; + for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { - if (proFn) { - proFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel); + if (stepFn) { + if ((iLabel % stage_unit2) == 0) { + stepFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel); + } if (cb_cancel) { shapeTool.reset(nullptr); application->Close(document); @@ -257,14 +258,94 @@ bool load_step(const char *path, Model *model, ImportStepProgressFn proFn, StepI getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids); } - ModelObject* new_object = model->add_object(); - const char *last_slash = strrchr(path, DIR_SEPARATOR); + std::vector stl; + stl.resize(namedSolids.size()); + tbb::parallel_for(tbb::blocked_range(0, namedSolids.size()), [&](const tbb::blocked_range &range) { + for (size_t i = range.begin(); i < range.end(); i++) { + BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); + // BBS: calculate total number of the nodes and triangles + int aNbNodes = 0; + int aNbTriangles = 0; + for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); + if (!aTriangulation.IsNull()) { + aNbNodes += aTriangulation->NbNodes(); + aNbTriangles += aTriangulation->NbTriangles(); + } + } + + if (aNbTriangles == 0) + // BBS: No triangulation on the shape. + continue; + + stl[i].stats.type = inmemory; + stl[i].stats.number_of_facets = (uint32_t) aNbTriangles; + stl[i].stats.original_num_facets = stl[i].stats.number_of_facets; + stl_allocate(&stl[i]); + + std::vector points; + points.reserve(aNbNodes); + // BBS: count faces missing triangulation + Standard_Integer aNbFacesNoTri = 0; + // BBS: fill temporary triangulation + Standard_Integer aNodeOffset = 0; + Standard_Integer aTriangleOffet = 0; + for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + const TopoDS_Shape &aFace = anExpSF.Current(); + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); + if (aTriangulation.IsNull()) { + ++aNbFacesNoTri; + continue; + } + // BBS: copy nodes + gp_Trsf aTrsf = aLoc.Transformation(); + for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { + gp_Pnt aPnt = aTriangulation->Node(aNodeIter); + aPnt.Transform(aTrsf); + points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + } + // BBS: copy triangles + const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); + Standard_Integer anId[3]; + for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { + Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); + + aTri.Get(anId[0], anId[1], anId[2]); + if (anOrientation == TopAbs_REVERSED) + std::swap(anId[1], anId[2]); + // BBS: save triangles facets + stl_facet facet; + facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast(); + facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast(); + facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast(); + facet.extra[0] = 0; + facet.extra[1] = 0; + stl_normal normal; + stl_calculate_normal(normal, &facet); + stl_normalize_vector(normal); + facet.normal = normal; + stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet; + } + + aNodeOffset += aTriangulation->NbNodes(); + aTriangleOffet += aTriangulation->NbTriangles(); + } + } + }); + + ModelObject *new_object = model->add_object(); + const char * last_slash = strrchr(path, DIR_SEPARATOR); new_object->name.assign((last_slash == nullptr) ? path : last_slash + 1); new_object->input_file = path; - for (size_t i = 0; i < namedSolids.size(); ++i) { - if (proFn) { - proFn(LOAD_STEP_STAGE_GET_MESH, i, namedSolids.size(), cb_cancel); + auto stage_unit3 = stl.size() / LOAD_STEP_STAGE_UNIT_NUM + 1; + for (size_t i = 0; i < stl.size(); i++) { + if (stepFn) { + if ((i % stage_unit3) == 0) { + stepFn(LOAD_STEP_STAGE_GET_MESH, i, stl.size(), cb_cancel); + } if (cb_cancel) { model->delete_object(new_object); shapeTool.reset(nullptr); @@ -273,94 +354,13 @@ bool load_step(const char *path, Model *model, ImportStepProgressFn proFn, StepI } } - BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); - //BBS: calculate total number of the nodes and triangles - int aNbNodes = 0; - int aNbTriangles = 0; - for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { - TopLoc_Location aLoc; - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); - if (!aTriangulation.IsNull()) { - aNbNodes += aTriangulation->NbNodes(); - aNbTriangles += aTriangulation->NbTriangles(); - } - } - - if (aNbTriangles == 0) { - //BBS: No triangulation on the shape. - continue; - } - - stl_file stl; - stl.stats.type = inmemory; - stl.stats.number_of_facets = (uint32_t)aNbTriangles; - stl.stats.original_num_facets = stl.stats.number_of_facets; - stl_allocate(&stl); - - std::vector points; - points.reserve(aNbNodes); - //BBS: count faces missing triangulation - Standard_Integer aNbFacesNoTri = 0; - //BBS: fill temporary triangulation - Standard_Integer aNodeOffset = 0; - Standard_Integer aTriangleOffet = 0; - for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { - const TopoDS_Shape& aFace = anExpSF.Current(); - TopLoc_Location aLoc; - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); - if (aTriangulation.IsNull()) { - ++aNbFacesNoTri; - continue; - } - //BBS: copy nodes - gp_Trsf aTrsf = aLoc.Transformation(); - for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { - gp_Pnt aPnt = aTriangulation->Node(aNodeIter); - aPnt.Transform(aTrsf); - points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); - } - //BBS: copy triangles - const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); - for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { - Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); - - Standard_Integer anId[3]; - aTri.Get(anId[0], anId[1], anId[2]); - if (anOrientation == TopAbs_REVERSED) { - //BBS: swap 1, 2. - Standard_Integer aTmpIdx = anId[1]; - anId[1] = anId[2]; - anId[2] = aTmpIdx; - } - //BBS: Update nodes according to the offset. - anId[0] += aNodeOffset; - anId[1] += aNodeOffset; - anId[2] += aNodeOffset; - //BBS: save triangles facets - stl_facet facet; - facet.vertex[0] = points[anId[0] - 1].cast(); - facet.vertex[1] = points[anId[1] - 1].cast(); - facet.vertex[2] = points[anId[2] - 1].cast(); - facet.extra[0] = 0; - facet.extra[1] = 0; - stl_normal normal; - stl_calculate_normal(normal, &facet); - stl_normalize_vector(normal); - facet.normal = normal; - stl.facet_start[aTriangleOffet + aTriIter - 1] = facet; - } - - aNodeOffset += aTriangulation->NbNodes(); - aTriangleOffet += aTriangulation->NbTriangles(); - } - TriangleMesh triangle_mesh; - triangle_mesh.from_stl(stl); - ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh)); - new_volume->name = namedSolids[i].name; + triangle_mesh.from_stl(stl[i]); + ModelVolume *new_volume = new_object->add_volume(std::move(triangle_mesh)); + new_volume->name = namedSolids[i].name; new_volume->source.input_file = path; - new_volume->source.object_idx = (int)model->objects.size() - 1; - new_volume->source.volume_idx = (int)new_object->volumes.size() - 1; + new_volume->source.object_idx = (int) model->objects.size() - 1; + new_volume->source.volume_idx = (int) new_object->volumes.size() - 1; } shapeTool.reset(nullptr); diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp index 14d1db21fc..13965d4112 100644 --- a/src/libslic3r/Format/STEP.hpp +++ b/src/libslic3r/Format/STEP.hpp @@ -6,6 +6,13 @@ namespace Slic3r { class TriangleMesh; class ModelObject; +// load step stage +const int LOAD_STEP_STAGE_READ_FILE = 0; +const int LOAD_STEP_STAGE_GET_SOLID = 1; +const int LOAD_STEP_STAGE_GET_MESH = 2; +const int LOAD_STEP_STAGE_NUM = 3; +const int LOAD_STEP_STAGE_UNIT_NUM = 5; + typedef std::function ImportStepProgressFn; typedef std::function StepIsUtf8Fn; diff --git a/src/libslic3r/Format/STL.cpp b/src/libslic3r/Format/STL.cpp index 2f2c9ec7fb..3ba514dc9b 100644 --- a/src/libslic3r/Format/STL.cpp +++ b/src/libslic3r/Format/STL.cpp @@ -14,10 +14,10 @@ namespace Slic3r { -bool load_stl(const char *path, Model *model, const char *object_name_in) +bool load_stl(const char *path, Model *model, const char *object_name_in, ImportstlProgressFn stlFn) { TriangleMesh mesh; - if (! mesh.ReadSTLFile(path)) { + if (! mesh.ReadSTLFile(path, true, stlFn)) { // die "Failed to open $file\n" if !-e $path; return false; } diff --git a/src/libslic3r/Format/STL.hpp b/src/libslic3r/Format/STL.hpp index cff7dc0869..5f2f838bfe 100644 --- a/src/libslic3r/Format/STL.hpp +++ b/src/libslic3r/Format/STL.hpp @@ -1,13 +1,16 @@ #ifndef slic3r_Format_STL_hpp_ #define slic3r_Format_STL_hpp_ +#include + namespace Slic3r { +class Model; class TriangleMesh; class ModelObject; // Load an STL file into a provided model. -extern bool load_stl(const char *path, Model *model, const char *object_name = nullptr); +extern bool load_stl(const char *path, Model *model, const char *object_name = nullptr, ImportstlProgressFn stlFn = nullptr); extern bool store_stl(const char *path, TriangleMesh *mesh, bool binary); extern bool store_stl(const char *path, ModelObject *model_object, bool binary); diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index be32d06155..697a07730f 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -258,6 +258,8 @@ static constexpr const char* SOURCE_OFFSET_Z_KEY = "source_offset_z"; static constexpr const char* SOURCE_IN_INCHES = "source_in_inches"; static constexpr const char* SOURCE_IN_METERS = "source_in_meters"; +static constexpr const char* MESH_SHARED_KEY = "mesh_shared"; + static constexpr const char* MESH_STAT_EDGES_FIXED = "edges_fixed"; static constexpr const char* MESH_STAT_DEGENERATED_FACETS = "degenerate_facets"; static constexpr const char* MESH_STAT_FACETS_REMOVED = "facets_removed"; @@ -702,6 +704,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) std::string m_thumbnail_path; std::vector m_sub_model_paths; + std::map m_shared_meshes; + //BBS: plater related structures bool m_is_bbl_3mf { false }; bool m_parsing_slice_info { false }; @@ -847,8 +851,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) bool _handle_start_relationship(const char** attributes, unsigned int num_attributes); - void _generate_current_object_list(std::vector &sub_objects, Id object_id, IdToCurrentObjectMap current_objects); - bool _generate_volumes_new(ModelObject& object, const std::vector &sub_objects, const ObjectMetadata::VolumeMetadataList& volumes, ConfigSubstitutionContext& config_substitutions); + void _generate_current_object_list(std::vector &sub_objects, Id object_id, IdToCurrentObjectMap current_objects); + bool _generate_volumes_new(ModelObject& object, const std::vector &sub_objects, const ObjectMetadata::VolumeMetadataList& volumes, ConfigSubstitutionContext& config_substitutions); bool _generate_volumes(ModelObject& object, const Geometry& geometry, const ObjectMetadata::VolumeMetadataList& volumes, ConfigSubstitutionContext& config_substitutions); // callbacks to parse the .model file @@ -1281,7 +1285,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) add_error("3rd 3mf, can not find object, id " + std::to_string(object.first.second)); return false; } - std::vector object_id_list; + std::vector object_id_list; _generate_current_object_list(object_id_list, object.first, m_current_objects); ObjectMetadata::VolumeMetadataList volumes; @@ -1289,7 +1293,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) for (int k = 0; k < object_id_list.size(); k++) { - Id object_id = object_id_list[k]; + Id object_id = object_id_list[k].object_id; volumes.emplace_back(object_id.second); } @@ -1344,7 +1348,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) model_object->sla_drain_holes = std::move(obj_drain_holes->second); }*/ - std::vector object_id_list; + std::vector object_id_list; _generate_current_object_list(object_id_list, object.first, m_current_objects); ObjectMetadata::VolumeMetadataList volumes; @@ -1375,7 +1379,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //volumes.emplace_back(0, (int)obj_geometry->second.triangles.size() - 1); for (int k = 0; k < object_id_list.size(); k++) { - Id object_id = object_id_list[k]; + Id object_id = object_id_list[k].object_id; volumes.emplace_back(object_id.second); } @@ -2757,31 +2761,31 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) check_painting_version(m_mm_painting_version, MM_PAINTING_VERSION, _(L("The selected 3MF contains multi-material painted object using a newer version of BambuStudio and is not compatible.")));*/ } else if (m_curr_metadata_name == BBL_MODEL_ID_TAG) { - m_model_id = m_curr_characters; + m_model_id = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_MODEL_NAME_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found model name = " << m_curr_characters; - model_info.model_name = m_curr_characters; + model_info.model_name = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_DESIGNER_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer = " << m_curr_characters; - m_designer = m_curr_characters; + m_designer = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_DESIGNER_USER_ID_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer_user_id = " << m_curr_characters; - m_designer_user_id = m_curr_characters; + m_designer_user_id = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_DESIGNER_COVER_FILE_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found designer_cover = " << m_curr_characters; - model_info.cover_file = m_curr_characters; + model_info.cover_file = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_DESCRIPTION_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found description = " << m_curr_characters; - model_info.description = m_curr_characters; + model_info.description = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_LICENSE_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found license = " << m_curr_characters; - model_info.license = m_curr_characters; + model_info.license = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_COPYRIGHT_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found copyright = " << m_curr_characters; - model_info.copyright = m_curr_characters; + model_info.copyright = xml_unescape(m_curr_characters); } else if (m_curr_metadata_name == BBL_REGION_TAG) { BOOST_LOG_TRIVIAL(trace) << "design_info, load_3mf found region = " << m_curr_characters; - m_contry_code = m_curr_characters; + m_contry_code = xml_unescape(m_curr_characters); } return true; @@ -3279,34 +3283,34 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return true; } - void _BBS_3MF_Importer::_generate_current_object_list(std::vector &sub_objects, Id object_id, IdToCurrentObjectMap current_objects) + void _BBS_3MF_Importer::_generate_current_object_list(std::vector &sub_objects, Id object_id, IdToCurrentObjectMap current_objects) { - std::list id_list; - id_list.push_back(object_id); + std::list id_list; + id_list.push_back({ object_id, Transform3d::Identity() }); while (!id_list.empty()) { - Id current_id = id_list.front(); + Component current_id = id_list.front(); id_list.pop_front(); - IdToCurrentObjectMap::iterator current_object = current_objects.find(current_id); + IdToCurrentObjectMap::iterator current_object = current_objects.find(current_id.object_id); if (current_object != current_objects.end()) { //found one if (!current_object->second.components.empty()) { for (const Component& comp: current_object->second.components) { - id_list.push_back(comp.object_id); + id_list.push_back(comp); } } else if (!(current_object->second.geometry.empty())) { //CurrentObject* ptr = &(current_objects[current_id]); //CurrentObject* ptr2 = &(current_object->second); - sub_objects.push_back(current_object->first); + sub_objects.push_back({ current_object->first, current_id.transform }); } } } } - bool _BBS_3MF_Importer::_generate_volumes_new(ModelObject& object, const std::vector &sub_objects, const ObjectMetadata::VolumeMetadataList& volumes, ConfigSubstitutionContext& config_substitutions) + bool _BBS_3MF_Importer::_generate_volumes_new(ModelObject& object, const std::vector &sub_objects, const ObjectMetadata::VolumeMetadataList& volumes, ConfigSubstitutionContext& config_substitutions) { if (!object.volumes.empty()) { add_error("object already built with parts"); @@ -3319,7 +3323,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) for (unsigned int index = 0; index < sub_objects.size(); index++) { //find the volume metadata firstly - Id object_id = sub_objects[index]; + Component sub_comp = sub_objects[index]; + Id object_id = sub_comp.object_id; IdToCurrentObjectMap::iterator current_object = m_current_objects.find(object_id); if (current_object == m_current_objects.end()) { add_error("sub_objects can not be found, id=" + std::to_string(object_id.second)); @@ -3338,70 +3343,114 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) Transform3d volume_matrix_to_object = Transform3d::Identity(); bool has_transform = false; + int shared_mesh_id = -1; if (volume_data) { + int found_count = 0; // extract the volume transformation from the volume's metadata, if present for (const Metadata& metadata : volume_data->metadata) { if (metadata.key == MATRIX_KEY) { volume_matrix_to_object = Slic3r::Geometry::transform3d_from_string(metadata.value); has_transform = ! volume_matrix_to_object.isApprox(Transform3d::Identity(), 1e-10); - break; + found_count++; } + else if (metadata.key == MESH_SHARED_KEY){ + //add the shared mesh logic + shared_mesh_id = ::atoi(metadata.value.c_str()); + found_count++; + } + + if (found_count >= 2) + break; } } else { //create a volume_data volume_data = &default_volume_data; } - // splits volume out of imported geometry - indexed_triangle_set its; - its.indices.assign(sub_object->geometry.triangles.begin(), sub_object->geometry.triangles.end()); - const size_t triangles_count = its.indices.size(); + + ModelVolume* volume = nullptr; + ModelVolume *shared_volume = nullptr; + if (shared_mesh_id != -1) { + std::map::iterator iter = m_shared_meshes.find(shared_mesh_id); + if (iter != m_shared_meshes.end()) { + shared_volume = iter->second; + } + } + + const size_t triangles_count = sub_object->geometry.triangles.size(); if (triangles_count == 0) { add_error("found no trianges in the object " + std::to_string(sub_object->id)); return false; } - for (const Vec3i& face : its.indices) { - for (const int tri_id : face) { - if (tri_id < 0 || tri_id >= int(sub_object->geometry.vertices.size())) { - add_error("invalid vertex id in object " + std::to_string(sub_object->id)); - return false; + if (!shared_volume){ + // splits volume out of imported geometry + indexed_triangle_set its; + its.indices.assign(sub_object->geometry.triangles.begin(), sub_object->geometry.triangles.end()); + //const size_t triangles_count = its.indices.size(); + //if (triangles_count == 0) { + // add_error("found no trianges in the object " + std::to_string(sub_object->id)); + // return false; + //} + for (const Vec3i& face : its.indices) { + for (const int tri_id : face) { + if (tri_id < 0 || tri_id >= int(sub_object->geometry.vertices.size())) { + add_error("invalid vertex id in object " + std::to_string(sub_object->id)); + return false; + } } } - } - its.vertices.assign(sub_object->geometry.vertices.begin(), sub_object->geometry.vertices.end()); + its.vertices.assign(sub_object->geometry.vertices.begin(), sub_object->geometry.vertices.end()); - // BBS - for (const std::string prop_str : sub_object->geometry.face_properties) { - FaceProperty face_prop; - face_prop.from_string(prop_str); - its.properties.push_back(face_prop); - } - - TriangleMesh triangle_mesh(std::move(its), volume_data->mesh_stats); - - if (m_version == 0) { - // if the 3mf was not produced by BambuStudio and there is only one instance, - // bake the transformation into the geometry to allow the reload from disk command - // to work properly - if (object.instances.size() == 1) { - triangle_mesh.transform(object.instances.front()->get_transformation().get_matrix(), false); - object.instances.front()->set_transformation(Slic3r::Geometry::Transformation()); - //FIXME do the mesh fixing? + // BBS + for (const std::string prop_str : sub_object->geometry.face_properties) { + FaceProperty face_prop; + face_prop.from_string(prop_str); + its.properties.push_back(face_prop); } - } - if (triangle_mesh.volume() < 0) - triangle_mesh.flip_triangles(); - ModelVolume* volume = object.add_volume(std::move(triangle_mesh)); + TriangleMesh triangle_mesh(std::move(its), volume_data->mesh_stats); + + if (m_version == 0) { + // if the 3mf was not produced by BambuStudio and there is only one instance, + // bake the transformation into the geometry to allow the reload from disk command + // to work properly + if (object.instances.size() == 1) { + triangle_mesh.transform(object.instances.front()->get_transformation().get_matrix(), false); + object.instances.front()->set_transformation(Slic3r::Geometry::Transformation()); + //FIXME do the mesh fixing? + } + } + if (triangle_mesh.volume() < 0) + triangle_mesh.flip_triangles(); + + volume = object.add_volume(std::move(triangle_mesh)); + + m_shared_meshes[sub_object->id] = volume; + } + else { + //create volume to use shared mesh + volume = object.add_volume_with_shared_mesh(*shared_volume); + } // stores the volume matrix taken from the metadata, if present if (has_transform) volume->source.transform = Slic3r::Geometry::Transformation(volume_matrix_to_object); + volume->calculate_convex_hull(); + //set transform from 3mf + Slic3r::Geometry::Transformation comp_transformatino(sub_comp.transform); + volume->set_transformation(volume->get_transformation() * comp_transformatino); + if (shared_volume) { + const TriangleMesh& trangle_mesh = volume->mesh(); + Vec3d shift = trangle_mesh.get_init_shift(); + if (!shift.isApprox(Vec3d::Zero())) + volume->translate(shift); + } + // recreate custom supports, seam and mmu segmentation from previously loaded attribute - if (m_load_config) { + { volume->supported_facets.reserve(triangles_count); volume->seam_facets.reserve(triangles_count); volume->mmu_segmentation_facets.reserve(triangles_count); @@ -3448,7 +3497,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) volume->source.is_converted_from_inches = metadata.value == "1"; else if (metadata.key == SOURCE_IN_METERS) volume->source.is_converted_from_meters = metadata.value == "1"; - else if (metadata.key == MATRIX_KEY) + else if ((metadata.key == MATRIX_KEY) || (metadata.key == MESH_SHARED_KEY)) continue; else volume->config.set_deserialize(metadata.key, metadata.value, config_substitutions); @@ -3814,18 +3863,38 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) auto filename = boost::format("3D/Objects/%s_%d.model") % object.name % obj_id; std::string filepath = temp_path + "/" + filename.str(); - if (!open_zip_writer(&archive, filepath)) { + std::string filepath_tmp = filepath + ".tmp"; + boost::system::error_code ec; + boost::filesystem::remove(filepath_tmp, ec); + if (!open_zip_writer(&archive, filepath_tmp)) { add_error("Unable to open the file"); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":" << __LINE__ << boost::format(", Unable to open the file\n"); return false; } + struct close_lock + { + mz_zip_archive & archive; + std::string const * filename; + void close() { + close_zip_writer(&archive); + filename = nullptr; + } + ~close_lock() { + if (filename) { + close_zip_writer(&archive); + boost::filesystem::remove(*filename); + } + } + } lock{archive, &filepath_tmp}; + IdToObjectDataMap objects_data; objects_data.insert({obj_id, {&object, obj_id}}); _add_model_file_to_archive(filename.str(), archive, model, objects_data); mz_zip_writer_finalize_archive(&archive); - close_zip_writer(&archive); + lock.close(); + boost::filesystem::rename(filepath_tmp, filepath, ec); return true; } @@ -4363,6 +4432,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return false; } + { std::stringstream stream; reset_stream(stream); @@ -4413,27 +4483,29 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) model_id = project->project_model_id; region_code = project->project_country_code; } + if (!sub_model) { + stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_NAME_TAG << "\">" << xml_escape(name) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_TAG << "\">" << xml_escape(user_name) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_USER_ID_TAG << "\">" << user_id << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_COVER_FILE_TAG << "\">" << xml_escape(design_cover) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_DESCRIPTION_TAG << "\">" << xml_escape(description) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_COPYRIGHT_TAG << "\">" << xml_escape(copyright) << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_LICENSE_TAG << "\">" << xml_escape(license) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_NAME_TAG << "\">" << xml_escape(name) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_TAG << "\">" << xml_escape(user_name) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_USER_ID_TAG << "\">" << user_id << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESIGNER_COVER_FILE_TAG << "\">" << xml_escape(design_cover) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_DESCRIPTION_TAG << "\">" << xml_escape(description) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_COPYRIGHT_TAG << "\">" << xml_escape(copyright) << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_LICENSE_TAG << "\">" << xml_escape(license) << "\n"; + /* save model info */ + if (!model_id.empty()) { + stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_ID_TAG << "\">" << model_id << "\n"; + stream << " <" << METADATA_TAG << " name=\"" << BBL_REGION_TAG << "\">" << region_code << "\n"; + } - /* save model info */ - if (!model_id.empty()) { - stream << " <" << METADATA_TAG << " name=\"" << BBL_MODEL_ID_TAG << "\">" << model_id << "\n"; - stream << " <" << METADATA_TAG << " name=\"" << BBL_REGION_TAG << "\">" << region_code << "\n"; + std::string date = Slic3r::Utils::utc_timestamp(Slic3r::Utils::get_current_time_utc()); + // keep only the date part of the string + date = date.substr(0, 10); + stream << " <" << METADATA_TAG << " name=\"CreationDate\">" << date << "\n"; + stream << " <" << METADATA_TAG << " name=\"ModificationDate\">" << date << "\n"; + stream << " <" << METADATA_TAG << " name=\"Application\">" << SLIC3R_APP_KEY << "-" << SLIC3R_VERSION << "\n"; } - std::string date = Slic3r::Utils::utc_timestamp(Slic3r::Utils::get_current_time_utc()); - // keep only the date part of the string - date = date.substr(0, 10); - stream << " <" << METADATA_TAG << " name=\"CreationDate\">" << date << "\n"; - stream << " <" << METADATA_TAG << " name=\"ModificationDate\">" << date << "\n"; - stream << " <" << METADATA_TAG << " name=\"Application\">" << SLIC3R_APP_KEY << "-" << SLIC3R_VERSION << "\n"; stream << " <" << RESOURCES_TAG << ">\n"; std::string buf = stream.str(); if (! buf.empty() && ! mz_zip_writer_add_staged_data(&context, buf.data(), buf.size())) { @@ -4645,12 +4717,37 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (m_from_backup_save) { for (unsigned int index = 1; index <= object.volumes.size(); index ++) { unsigned int ref_id = object_id | (index << 16); - stream << " <" << COMPONENT_TAG << " objectid=\"" << ref_id << "\"/>\n"; + stream << " <" << COMPONENT_TAG << " objectid=\"" << ref_id; // << "\"/>\n"; + //add the transform of the volume + ModelVolume* volume = object.volumes[index - 1]; + const Transform3d& transf = volume->get_matrix(); + stream << "\" " << TRANSFORM_ATTR << "=\""; + for (unsigned c = 0; c < 4; ++c) { + for (unsigned r = 0; r < 3; ++r) { + stream << transf(r, c); + if (r != 2 || c != 3) + stream << " "; + } + } + stream << "\"/>\n"; } } else { - for (unsigned int index = object_id; index < volume_start_id; index ++) - stream << " <" << COMPONENT_TAG << " objectid=\"" << index << "\"/>\n"; + for (unsigned int index = object_id; index < volume_start_id; index ++) { + stream << " <" << COMPONENT_TAG << " objectid=\"" << index; // << "\"/>\n"; + //add the transform of the volume + ModelVolume* volume = object.volumes[index - object_id]; + const Transform3d& transf = volume->get_matrix(); + stream << "\" " << TRANSFORM_ATTR << "=\""; + for (unsigned c = 0; c < 4; ++c) { + for (unsigned r = 0; r < 3; ++r) { + stream << transf(r, c); + if (r != 2 || c != 3) + stream << " "; + } + } + stream << "\"/>\n"; + } } } else { @@ -4800,7 +4897,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) const Transform3d& matrix = volume->get_matrix(); for (size_t i = 0; i < its.vertices.size(); ++i) { - Vec3f v = (matrix * its.vertices[i].cast()).cast(); + //don't save the volume's matrix into vertex data + //add the shared mesh logic + //Vec3f v = (matrix * its.vertices[i].cast()).cast(); + Vec3f v = its.vertices[i]; char* ptr = buf; boost::spirit::karma::generate(ptr, boost::spirit::lit(" <") << VERTEX_TAG << " x=\""); ptr = format_coordinate(v.x(), ptr); @@ -5202,6 +5302,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) bool _BBS_3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const IdToObjectDataMap &objects_data, int export_plate_idx, bool save_gcode) { std::stringstream stream; + std::map shared_meshes; // Store mesh transformation in full precision, as the volumes are stored transformed and they need to be transformed back // when loaded as accurately as possible. stream << std::setprecision(std::numeric_limits::max_digits10); @@ -5294,6 +5395,17 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << METADATA_TAG << " "<< KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; } + //add the shared mesh logic + const TriangleMesh* current_mesh = volume->mesh_ptr(); + std::map::iterator mesh_iter; + mesh_iter = shared_meshes.find(current_mesh); + if (mesh_iter != shared_meshes.end()) { + stream << " <" << METADATA_TAG << " "<< KEY_ATTR << "=\"" << MESH_SHARED_KEY << "\" " << VALUE_ATTR << "=\"" << mesh_iter->second << "\"/>\n"; + } + else { + shared_meshes[current_mesh] = it->second; + } + // stores mesh's statistics const RepairedMeshErrors& stats = volume->mesh().stats().repaired_errors; stream << " <" << MESH_STAT_TAG << " "; diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index ff47b05aee..d7a90fba7f 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -166,6 +166,7 @@ const int IMPORT_STAGE_CHECK_MODE_GCODE = 9; const int UPDATE_GCODE_RESULT = 10; const int IMPORT_LOAD_CONFIG = 11; const int IMPORT_LOAD_MODEL_OBJECTS = 12; +const int IMPORT_STAGE_MAX = 13; //BBS export 3mf progress typedef std::function Export3mfProgressFn; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 503ed28e44..8b745752e0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -554,6 +554,9 @@ bool GCode::gcode_label_objects = false; { std::string gcode; + assert(m_layer_idx >= 0); + if (m_layer_idx >= (int) m_tool_changes.size()) return gcode; + // Calculate where the wipe tower layer will be printed. -1 means that print z will not change, // resulting in a wipe tower with sparse layers. double wipe_tower_z = -1; @@ -571,16 +574,12 @@ bool GCode::gcode_label_objects = false; m_is_first_print = false; } - assert(m_layer_idx >= 0); if (gcodegen.writer().need_toolchange(extruder_id) || finish_layer) { - if (m_layer_idx < (int)m_tool_changes.size()) { - if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size())) - throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer."); + if (!(size_t(m_tool_change_idx) < m_tool_changes[m_layer_idx].size())) throw Slic3r::RuntimeError("Wipe tower generation failed, possibly due to empty first layer."); - if (!ignore_sparse) { - gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); - m_last_wipe_tower_print_z = wipe_tower_z; - } + if (!ignore_sparse) { + gcode += append_tcr(gcodegen, m_tool_changes[m_layer_idx][m_tool_change_idx++], extruder_id, wipe_tower_z); + m_last_wipe_tower_print_z = wipe_tower_z; } } @@ -667,6 +666,7 @@ std::vector GCode::collect_layers_to_print(const PrintObjec --idx_tree_support_layer; } + layer_to_print.original_object = &object; layers_to_print.push_back(layer_to_print); bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) @@ -1261,6 +1261,7 @@ enum BambuBedType { bbtCoolPlate = 1, bbtEngineeringPlate = 2, bbtHighTemperaturePlate = 3, + bbtTexturedPEIPlate = 4, }; static BambuBedType to_bambu_bed_type(BedType type) @@ -1272,6 +1273,8 @@ static BambuBedType to_bambu_bed_type(BedType type) bambu_bed_type = bbtEngineeringPlate; else if (type == btPEI) bambu_bed_type = bbtHighTemperaturePlate; + else if (type == btPTE) + bambu_bed_type = bbtTexturedPEIPlate; return bambu_bed_type; } @@ -1570,7 +1573,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato print.throw_if_canceled(); // Collect custom seam data from all objects. - m_seam_placer.init(print); + std::function throw_if_canceled_func = [&print]() { print.throw_if_canceled(); }; + m_seam_placer.init(print, throw_if_canceled_func); // BBS: priming logic is removed, always set first extruer here. //if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) @@ -2153,7 +2157,9 @@ std::vector GCode::sort_print_object_instances( // Sequential print, single object is being printed. for (ObjectByExtruder &object_by_extruder : objects_by_extruder) { const size_t layer_id = &object_by_extruder - objects_by_extruder.data(); - const PrintObject *print_object = layers[layer_id].object(); + //BBS:add the support of shared print object + const PrintObject *print_object = layers[layer_id].original_object; + //const PrintObject *print_object = layers[layer_id].object(); if (print_object) out.emplace_back(object_by_extruder, layer_id, *print_object, single_object_instance_idx); } @@ -2163,7 +2169,9 @@ std::vector GCode::sort_print_object_instances( sorted.reserve(objects_by_extruder.size()); for (ObjectByExtruder &object_by_extruder : objects_by_extruder) { const size_t layer_id = &object_by_extruder - objects_by_extruder.data(); - const PrintObject *print_object = layers[layer_id].object(); + //BBS:add the support of shared print object + const PrintObject *print_object = layers[layer_id].original_object; + //const PrintObject *print_object = layers[layer_id].object(); if (print_object) sorted.emplace_back(print_object, &object_by_extruder); } @@ -2173,6 +2181,10 @@ std::vector GCode::sort_print_object_instances( out.reserve(sorted.size()); for (const PrintInstance *instance : *ordering) { const PrintObject &print_object = *instance->print_object; + //BBS:add the support of shared print object + //const PrintObject* print_obj_ptr = &print_object; + //if (print_object.get_shared_object()) + // print_obj_ptr = print_object.get_shared_object(); std::pair key(&print_object, nullptr); auto it = std::lower_bound(sorted.begin(), sorted.end(), key); if (it != sorted.end() && it->first == &print_object) @@ -2795,7 +2807,6 @@ GCode::LayerResult GCode::process_layer( m_wipe_tower->set_is_first_print(true); // Extrude the skirt, brim, support, perimeters, infill ordered by the extruders. - std::vector> lower_layer_edge_grids(layers.size()); for (unsigned int extruder_id : layer_tools.extruders) { gcode += (layer_tools.has_wipe_tower && m_wipe_tower) ? @@ -2910,12 +2921,7 @@ GCode::LayerResult GCode::process_layer( m_layer = layers[instance_to_print.layer_id].tree_support_layer; } m_object_layer_over_raft = false; - // BBS. Keep paths order -#if 0 - gcode += this->extrude_support( - // support_extrusion_role is erSupportMaterial, erSupportTransition, erSupportMaterialInterface or erMixed for all extrusion paths. - instance_to_print.object_by_extruder.support->chained_path_from(m_last_pos, instance_to_print.object_by_extruder.support_extrusion_role)); -#else + //BBS: print supports' brims first if (this->m_objSupportsWithBrim.find(instance_to_print.print_object.id()) != this->m_objSupportsWithBrim.end() && !print_wipe_extrusions) { this->set_origin(0., 0.); @@ -2945,12 +2951,10 @@ GCode::LayerResult GCode::process_layer( ExtrusionRole support_extrusion_role = instance_to_print.object_by_extruder.support_extrusion_role; bool is_overridden = support_extrusion_role == erSupportMaterialInterface ? support_intf_overridden : support_overridden; if (is_overridden == (print_wipe_extrusions != 0)) - support_eec.entities = filter_by_extrusion_role(instance_to_print.object_by_extruder.support->entities, instance_to_print.object_by_extruder.support_extrusion_role); + gcode += this->extrude_support( + // support_extrusion_role is erSupportMaterial, erSupportTransition, erSupportMaterialInterface or erMixed for all extrusion paths. + instance_to_print.object_by_extruder.support->chained_path_from(m_last_pos, support_extrusion_role)); - for (auto& ptr : support_eec.entities) - ptr = ptr->clone(); - gcode += this->extrude_support(support_eec); -#endif m_layer = layer_to_print.layer(); m_object_layer_over_raft = object_layer_over_raft; } @@ -2984,9 +2988,9 @@ GCode::LayerResult GCode::process_layer( //This behaviour is same with cura if (is_infill_first && !first_layer) { gcode += this->extrude_infill(print, by_region_specific, false); - gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]); + gcode += this->extrude_perimeters(print, by_region_specific); } else { - gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]); + gcode += this->extrude_perimeters(print, by_region_specific); gcode += this->extrude_infill(print,by_region_specific, false); } // ironing @@ -3164,14 +3168,11 @@ static std::unique_ptr calculate_layer_edge_grid(const Layer& la } -std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed, std::unique_ptr *lower_layer_edge_grid) +std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, double speed) { // get a copy; don't modify the orientation of the original loop object otherwise // next copies (if any) would not detect the correct orientation - if (m_layer->lower_layer && lower_layer_edge_grid != nullptr && ! *lower_layer_edge_grid) - *lower_layer_edge_grid = calculate_layer_edge_grid(*m_layer->lower_layer); - //BBS: extrude contour of wall ccw, hole of wall cw, except spiral mode bool was_clockwise = loop.is_clockwise(); if (m_config.spiral_mode || !is_perimeter(loop.role())) @@ -3181,17 +3182,13 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // find the point of the loop that is closest to the current extruder position // or randomize if requested Point last_pos = this->last_pos(); - if (m_config.spiral_mode) { + if (!m_config.spiral_mode && description == "perimeter") { + assert(m_layer != nullptr); + bool is_outer_wall_first = m_config.wall_infill_order == WallInfillOrder::OuterInnerInfill + || m_config.wall_infill_order == WallInfillOrder::InfillOuterInner; + m_seam_placer.place_seam(m_layer, loop, is_outer_wall_first, this->last_pos()); + } else loop.split_at(last_pos, false); - } - else { - //BBS - bool is_outer_wall_first = - m_config.wall_infill_order == WallInfillOrder::OuterInnerInfill || - m_config.wall_infill_order == WallInfillOrder::InfillOuterInner; - m_seam_placer.place_seam(loop, this->last_pos(), is_outer_wall_first, - EXTRUDER_CONFIG(nozzle_diameter), lower_layer_edge_grid ? lower_layer_edge_grid->get() : nullptr); - } // clip the path to avoid the extruder to get exactly on the first point of the loop; // if polyline was shorter than the clipping distance we'd get a null polyline, so @@ -3301,14 +3298,14 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string return gcode; } -std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string description, double speed, std::unique_ptr *lower_layer_edge_grid) +std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string description, double speed) { if (const ExtrusionPath* path = dynamic_cast(&entity)) return this->extrude_path(*path, description, speed); else if (const ExtrusionMultiPath* multipath = dynamic_cast(&entity)) return this->extrude_multi_path(*multipath, description, speed); else if (const ExtrusionLoop* loop = dynamic_cast(&entity)) - return this->extrude_loop(*loop, description, speed, lower_layer_edge_grid); + return this->extrude_loop(*loop, description, speed); else throw Slic3r::InvalidArgument("Invalid argument supplied to extrude()"); return ""; @@ -3330,24 +3327,15 @@ std::string GCode::extrude_path(ExtrusionPath path, std::string description, dou } // Extrude perimeters: Decide where to put seams (hide or align seams). -std::string GCode::extrude_perimeters(const Print &print, const std::vector &by_region, std::unique_ptr &lower_layer_edge_grid) +std::string GCode::extrude_perimeters(const Print &print, const std::vector &by_region) { std::string gcode; for (const ObjectByExtruder::Island::Region ®ion : by_region) if (! region.perimeters.empty()) { m_config.apply(print.get_print_region(®ion - &by_region.front()).config()); - // plan_perimeters tries to place seams, it needs to have the lower_layer_edge_grid calculated already. - if (m_layer->lower_layer && ! lower_layer_edge_grid) - lower_layer_edge_grid = calculate_layer_edge_grid(*m_layer->lower_layer); - - m_seam_placer.plan_perimeters(std::vector(region.perimeters.begin(), region.perimeters.end()), - *m_layer, m_config.seam_position, this->last_pos(), EXTRUDER_CONFIG(nozzle_diameter), - (m_layer == NULL ? nullptr : m_layer->object()), - (lower_layer_edge_grid ? lower_layer_edge_grid.get() : nullptr)); - for (const ExtrusionEntity* ee : region.perimeters) - gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid); + gcode += this->extrude_entity(*ee, "perimeter", -1.); } return gcode; } @@ -3817,6 +3805,11 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) return false; } + //BBS: force to retract when leave from external perimeter for a long travel + //Better way is judging whether the travel move direction is same with last extrusion move. + if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) + return true; + if (role == erSupportMaterial || role == erSupportTransition) { const SupportLayer* support_layer = dynamic_cast(m_layer); //FIXME support_layer->support_islands.contains should use some search structure! diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 702f47fe73..dc80fa0339 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -41,11 +41,11 @@ class OozePrevention { public: bool enable; Points standby_points; - + OozePrevention() : enable(false) {} std::string pre_toolchange(GCode &gcodegen); std::string post_toolchange(GCode &gcodegen); - + private: int _get_temp(GCode &gcodegen); }; @@ -54,7 +54,7 @@ class Wipe { public: bool enable; Polyline path; - + Wipe() : enable(false) {} bool has_path() const { return !this->path.points.empty(); } void reset_path() { this->path = Polyline(); } @@ -136,15 +136,15 @@ public: }; class GCode { -public: +public: GCode() : m_origin(Vec2d::Zero()), - m_enable_loop_clipping(true), - m_enable_cooling_markers(false), + m_enable_loop_clipping(true), + m_enable_cooling_markers(false), m_enable_extrusion_role_markers(false), m_last_processor_extrusion_role(erNone), m_layer_count(0), - m_layer_index(-1), + m_layer_index(-1), m_layer(nullptr), m_object_layer_over_raft(false), //m_volumetric_speed(0), @@ -201,10 +201,11 @@ public: // public, so that it could be accessed by free helper functions from GCode.cpp struct LayerToPrint { - LayerToPrint() : object_layer(nullptr), support_layer(nullptr), tree_support_layer(nullptr) {} + LayerToPrint() : object_layer(nullptr), support_layer(nullptr), tree_support_layer(nullptr), original_object(nullptr) {} const Layer* object_layer; const SupportLayer* support_layer; const TreeSupportLayer* tree_support_layer; + const PrintObject* original_object; //BBS: used for shared object logic const Layer* layer() const { if (object_layer != nullptr) @@ -218,7 +219,11 @@ public: return nullptr; } - const PrintObject* object() const { return (this->layer() != nullptr) ? this->layer()->object() : nullptr; } + + const PrintObject* object() const + { + return (this->layer() != nullptr) ? this->layer()->object() : nullptr; + } coordf_t print_z() const { coordf_t sum_z = 0.; @@ -249,7 +254,7 @@ private: bool is_open() const { return f; } bool is_error() const; - + void flush(); void close(); @@ -257,12 +262,12 @@ private: void write(const std::string& what) { this->write(what.c_str()); } void write(const char* what); - // Write a string into a file. + // Write a string into a file. // Add a newline, if the string does not end with a newline already. // Used to export a custom G-code section processed by the PlaceholderParser. void writeln(const std::string& what); - // Formats and write into a file the given data. + // Formats and write into a file the given data. void write_format(const char* format, ...); private: @@ -325,8 +330,8 @@ private: std::string preamble(); // BBS std::string change_layer(coordf_t print_z, bool lazy_raise = false); - std::string extrude_entity(const ExtrusionEntity &entity, std::string description = "", double speed = -1., std::unique_ptr *lower_layer_edge_grid = nullptr); - std::string extrude_loop(ExtrusionLoop loop, std::string description, double speed = -1., std::unique_ptr *lower_layer_edge_grid = nullptr); + std::string extrude_entity(const ExtrusionEntity &entity, std::string description = "", double speed = -1.); + std::string extrude_loop(ExtrusionLoop loop, std::string description, double speed = -1.); std::string extrude_multi_path(ExtrusionMultiPath multipath, std::string description = "", double speed = -1.); std::string extrude_path(ExtrusionPath path, std::string description = "", double speed = -1.); @@ -375,7 +380,7 @@ private: InstanceToPrint(ObjectByExtruder &object_by_extruder, size_t layer_id, const PrintObject &print_object, size_t instance_id) : object_by_extruder(object_by_extruder), layer_id(layer_id), print_object(print_object), instance_id(instance_id) {} - // Repository + // Repository ObjectByExtruder &object_by_extruder; // Index into std::vector, which contains Object and Support layers for the current print_z, collected for a single object, or for possibly multiple objects with multiple instances. const size_t layer_id; @@ -393,7 +398,7 @@ private: // For sequential print, the instance of the object to be printing has to be defined. const size_t single_object_instance_idx); - std::string extrude_perimeters(const Print &print, const std::vector &by_region, std::unique_ptr &lower_layer_edge_grid); + std::string extrude_perimeters(const Print &print, const std::vector &by_region); std::string extrude_infill(const Print &print, const std::vector &by_region, bool ironing); std::string extrude_support(const ExtrusionEntityCollection &support_fills); @@ -500,14 +505,14 @@ private: bool object_layer_over_raft() const { return m_object_layer_over_raft; } friend ObjectByExtruder& object_by_extruder( - std::map> &by_extruder, - unsigned int extruder_id, - size_t object_idx, + std::map> &by_extruder, + unsigned int extruder_id, + size_t object_idx, size_t num_objects); friend std::vector& object_islands_by_extruder( - std::map> &by_extruder, - unsigned int extruder_id, - size_t object_idx, + std::map> &by_extruder, + unsigned int extruder_id, + size_t object_idx, size_t num_objects, size_t num_islands); diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 97a64a64ef..1c9ecda834 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -1,987 +1,1382 @@ #include "SeamPlacer.hpp" +#include "tbb/parallel_for.h" +#include "tbb/blocked_range.h" +#include "tbb/parallel_reduce.h" +#include +#include +#include +#include + +#include "libslic3r/AABBTreeLines.hpp" +#include "libslic3r/KDTreeIndirect.hpp" #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/Print.hpp" #include "libslic3r/BoundingBox.hpp" -#include "libslic3r/EdgeGrid.hpp" #include "libslic3r/ClipperUtils.hpp" -#include "libslic3r/SVG.hpp" #include "libslic3r/Layer.hpp" +#include "libslic3r/Geometry/Curves.hpp" +#include "libslic3r/ShortEdgeCollapse.hpp" +#include "libslic3r/TriangleSetSampling.hpp" + +#include "libslic3r/Utils.hpp" + +//#define DEBUG_FILES + +#ifdef DEBUG_FILES +#include +#include +#endif + namespace Slic3r { -// This penalty is added to all points inside custom blockers (subtracted from pts inside enforcers). -static constexpr float ENFORCER_BLOCKER_PENALTY = 100; +namespace SeamPlacerImpl { -// In case there are custom enforcers/blockers, the loop polygon shall always have -// sides smaller than this (so it isn't limited to original resolution). -static constexpr float MINIMAL_POLYGON_SIDE = scaled(0.2f); - -// When spAligned is active and there is a support enforcer, -// add this penalty to its center. -static constexpr float ENFORCER_CENTER_PENALTY = -10.f; - - - - -static float extrudate_overlap_penalty(float nozzle_r, float weight_zero, float overlap_distance) +// ************ FOR BACKPORT COMPATIBILITY ONLY *************** +// Color mapping of a value into RGB false colors. +inline Vec3f value_to_rgbf(float minimum, float maximum, float value) { - // The extrudate is not fully supported by the lower layer. Fit a polynomial penalty curve. - // Solved by sympy package: -/* -from sympy import * -(x,a,b,c,d,r,z)=symbols('x a b c d r z') -p = a + b*x + c*x*x + d*x*x*x -p2 = p.subs(solve([p.subs(x, -r), p.diff(x).subs(x, -r), p.diff(x,x).subs(x, -r), p.subs(x, 0)-z], [a, b, c, d])) -from sympy.plotting import plot -plot(p2.subs(r,0.2).subs(z,1.), (x, -1, 3), adaptive=False, nb_of_points=400) -*/ - if (overlap_distance < - nozzle_r) { - // The extrudate is fully supported by the lower layer. This is the ideal case, therefore zero penalty. - return 0.f; - } else { - float x = overlap_distance / nozzle_r; - float x2 = x * x; - float x3 = x2 * x; - return weight_zero * (1.f + 3.f * x + 3.f * x2 + x3); - } + float ratio = 2.0f * (value - minimum) / (maximum - minimum); + float b = std::max(0.0f, (1.0f - ratio)); + float r = std::max(0.0f, (ratio - 1.0f)); + float g = 1.0f - b - r; + return Vec3f{r, g, b}; } +// Color mapping of a value into RGB false colors. +inline Vec3i value_to_rgbi(float minimum, float maximum, float value) { return (value_to_rgbf(minimum, maximum, value) * 255).cast(); } +// *************************** +template int sgn(T val) { return int(T(0) < val) - int(val < T(0)); } -// Return a value in <0, 1> of a cubic B-spline kernel centered around zero. -// The B-spline is re-scaled so it has value 1 at zero. -static inline float bspline_kernel(float x) +// base function: ((e^(((1)/(x^(2)+1)))-1)/(e-1)) +// checkout e.g. here: https://www.geogebra.org/calculator +float gauss(float value, float mean_x_coord, float mean_value, float falloff_speed) { - x = std::abs(x); - if (x < 1.f) { - return 1.f - (3.f / 2.f) * x * x + (3.f / 4.f) * x * x * x; - } - else if (x < 2.f) { - x -= 1.f; - float x2 = x * x; - float x3 = x2 * x; - return (1.f / 4.f) - (3.f / 4.f) * x + (3.f / 4.f) * x2 - (1.f / 4.f) * x3; - } - else - return 0; + float shifted = value - mean_x_coord; + float denominator = falloff_speed * shifted * shifted + 1.0f; + float exponent = 1.0f / denominator; + return mean_value * (std::exp(exponent) - 1.0f) / (std::exp(1.0f) - 1.0f); } - - -static Points::const_iterator project_point_to_polygon_and_insert(Polygon &polygon, const Point &pt, double eps) +float compute_angle_penalty(float ccw_angle) { - assert(polygon.points.size() >= 2); - if (polygon.points.size() <= 1) - if (polygon.points.size() == 1) - return polygon.points.begin(); + // This function is used: + // ((ℯ^(((1)/(x^(2)*3+1)))-1)/(ℯ-1))*1+((1)/(2+ℯ^(-x))) + // looks scary, but it is gaussian combined with sigmoid, + // so that concave points have much smaller penalty over convex ones + // https://github.com/prusa3d/PrusaSlicer/tree/master/doc/seam_placement/corner_penalty_function.png + return gauss(ccw_angle, 0.0f, 1.0f, 3.0f) + 1.0f / (2 + std::exp(-ccw_angle)); +} - Point pt_min; - double d_min = std::numeric_limits::max(); - size_t i_min = size_t(-1); +/// Coordinate frame +class Frame +{ +public: + Frame() + { + mX = Vec3f(1, 0, 0); + mY = Vec3f(0, 1, 0); + mZ = Vec3f(0, 0, 1); + } - for (size_t i = 0; i < polygon.points.size(); ++ i) { - size_t j = i + 1; - if (j == polygon.points.size()) - j = 0; - const Point &p1 = polygon.points[i]; - const Point &p2 = polygon.points[j]; - const Slic3r::Point v_seg = p2 - p1; - const Slic3r::Point v_pt = pt - p1; - const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1)); - int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1)); - if (t_pt < 0) { - // Closest to p1. - double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1))); - if (dabs < d_min) { - d_min = dabs; - i_min = i; - pt_min = p1; - } - } - else if (t_pt > l2_seg) { - // Closest to p2. Then p2 is the starting point of another segment, which shall be discovered in the next step. - continue; - } else { - // Closest to the segment. - assert(t_pt >= 0 && t_pt <= l2_seg); - int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1)); - double d = double(d_seg) / sqrt(double(l2_seg)); - double dabs = std::abs(d); - if (dabs < d_min) { - d_min = dabs; - i_min = i; - // Evaluate the foot point. - pt_min = p1; - double linv = double(d_seg) / double(l2_seg); - pt_min(0) = pt(0) - coord_t(floor(double(v_seg(1)) * linv + 0.5)); - pt_min(1) = pt(1) + coord_t(floor(double(v_seg(0)) * linv + 0.5)); - assert(Line(p1, p2).distance_to(pt_min) < scale_(1e-5)); - } + Frame(const Vec3f &x, const Vec3f &y, const Vec3f &z) : mX(x), mY(y), mZ(z) {} + + void set_from_z(const Vec3f &z) + { + mZ = z.normalized(); + Vec3f tmpZ = mZ; + Vec3f tmpX = (std::abs(tmpZ.x()) > 0.99f) ? Vec3f(0, 1, 0) : Vec3f(1, 0, 0); + mY = (tmpZ.cross(tmpX)).normalized(); + mX = mY.cross(tmpZ); + } + + Vec3f to_world(const Vec3f &a) const { return a.x() * mX + a.y() * mY + a.z() * mZ; } + + Vec3f to_local(const Vec3f &a) const { return Vec3f(mX.dot(a), mY.dot(a), mZ.dot(a)); } + + const Vec3f &binormal() const { return mX; } + + const Vec3f &tangent() const { return mY; } + + const Vec3f &normal() const { return mZ; } + +private: + Vec3f mX, mY, mZ; +}; + +Vec3f sample_sphere_uniform(const Vec2f &samples) +{ + float term1 = 2.0f * float(PI) * samples.x(); + float term2 = 2.0f * sqrt(samples.y() - samples.y() * samples.y()); + return {cos(term1) * term2, sin(term1) * term2, 1.0f - 2.0f * samples.y()}; +} + +Vec3f sample_hemisphere_uniform(const Vec2f &samples) +{ + float term1 = 2.0f * float(PI) * samples.x(); + float term2 = 2.0f * sqrt(samples.y() - samples.y() * samples.y()); + return {cos(term1) * term2, sin(term1) * term2, abs(1.0f - 2.0f * samples.y())}; +} + +Vec3f sample_power_cosine_hemisphere(const Vec2f &samples, float power) +{ + float term1 = 2.f * float(PI) * samples.x(); + float term2 = pow(samples.y(), 1.f / (power + 1.f)); + float term3 = sqrt(1.f - term2 * term2); + + return Vec3f(cos(term1) * term3, sin(term1) * term3, term2); +} + +std::vector raycast_visibility(const AABBTreeIndirect::Tree<3, float> &raycasting_tree, + const indexed_triangle_set & triangles, + const TriangleSetSamples & samples, + size_t negative_volumes_start_index) +{ + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: raycast visibility of " << samples.positions.size() << " samples over " << triangles.indices.size() << " triangles: end"; + + // prepare uniform samples of a hemisphere + float step_size = 1.0f / SeamPlacer::sqr_rays_per_sample_point; + std::vector precomputed_sample_directions(SeamPlacer::sqr_rays_per_sample_point * SeamPlacer::sqr_rays_per_sample_point); + for (size_t x_idx = 0; x_idx < SeamPlacer::sqr_rays_per_sample_point; ++x_idx) { + float sample_x = x_idx * step_size + step_size / 2.0; + for (size_t y_idx = 0; y_idx < SeamPlacer::sqr_rays_per_sample_point; ++y_idx) { + size_t dir_index = x_idx * SeamPlacer::sqr_rays_per_sample_point + y_idx; + float sample_y = y_idx * step_size + step_size / 2.0; + precomputed_sample_directions[dir_index] = sample_hemisphere_uniform({sample_x, sample_y}); } } - assert(i_min != size_t(-1)); - if ((pt_min - polygon.points[i_min]).cast().norm() > eps) { - // Insert a new point on the segment i_min, i_min+1. - return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min); - } - return polygon.points.begin() + i_min; -} + bool model_contains_negative_parts = negative_volumes_start_index < triangles.indices.size(); + std::vector result(samples.positions.size()); + tbb::parallel_for(tbb::blocked_range(0, result.size()), [&triangles, &precomputed_sample_directions, model_contains_negative_parts, negative_volumes_start_index, + &raycasting_tree, &result, &samples](tbb::blocked_range r) { + // Maintaining hits memory outside of the loop, so it does not have to be reallocated for each query. + std::vector hits; + for (size_t s_idx = r.begin(); s_idx < r.end(); ++s_idx) { + result[s_idx] = 1.0f; + constexpr float decrease_step = 1.0f / (SeamPlacer::sqr_rays_per_sample_point * SeamPlacer::sqr_rays_per_sample_point); + const Vec3f ¢er = samples.positions[s_idx]; + const Vec3f &normal = samples.normals[s_idx]; + // apply the local direction via Frame struct - the local_dir is with respect to +Z being forward + Frame f; + f.set_from_z(normal); -static std::vector polygon_angles_at_vertices(const Polygon &polygon, const std::vector &lengths, float min_arm_length) -{ - assert(polygon.points.size() + 1 == lengths.size()); - if (min_arm_length > 0.25f * lengths.back()) - min_arm_length = 0.25f * lengths.back(); + for (const auto &dir : precomputed_sample_directions) { + Vec3f final_ray_dir = (f.to_world(dir)); + if (!model_contains_negative_parts) { + igl::Hit hitpoint; + // FIXME: This AABBTTreeIndirect query will not compile for float ray origin and + // direction. + Vec3d final_ray_dir_d = final_ray_dir.cast(); + Vec3d ray_origin_d = (center + normal * 0.01f).cast(); // start above surface. + bool hit = AABBTreeIndirect::intersect_ray_first_hit(triangles.vertices, triangles.indices, raycasting_tree, ray_origin_d, final_ray_dir_d, hitpoint); + if (hit && its_face_normal(triangles, hitpoint.id).dot(final_ray_dir) <= 0) { result[s_idx] -= decrease_step; } + } else { // TODO improve logic for order based boolean operations - consider order of volumes + bool casting_from_negative_volume = samples.triangle_indices[s_idx] >= negative_volumes_start_index; - // Find the initial prev / next point span. - size_t idx_prev = polygon.points.size(); - size_t idx_curr = 0; - size_t idx_next = 1; - while (idx_prev > idx_curr && lengths.back() - lengths[idx_prev] < min_arm_length) - -- idx_prev; - while (idx_next < idx_prev && lengths[idx_next] < min_arm_length) - ++ idx_next; - - std::vector angles(polygon.points.size(), 0.f); - for (; idx_curr < polygon.points.size(); ++ idx_curr) { - // Move idx_prev up until the distance between idx_prev and idx_curr is lower than min_arm_length. - if (idx_prev >= idx_curr) { - while (idx_prev < polygon.points.size() && lengths.back() - lengths[idx_prev] + lengths[idx_curr] > min_arm_length) - ++ idx_prev; - if (idx_prev == polygon.points.size()) - idx_prev = 0; - } - while (idx_prev < idx_curr && lengths[idx_curr] - lengths[idx_prev] > min_arm_length) - ++ idx_prev; - // Move idx_prev one step back. - if (idx_prev == 0) - idx_prev = polygon.points.size() - 1; - else - -- idx_prev; - // Move idx_next up until the distance between idx_curr and idx_next is greater than min_arm_length. - if (idx_curr <= idx_next) { - while (idx_next < polygon.points.size() && lengths[idx_next] - lengths[idx_curr] < min_arm_length) - ++ idx_next; - if (idx_next == polygon.points.size()) - idx_next = 0; - } - while (idx_next < idx_curr && lengths.back() - lengths[idx_curr] + lengths[idx_next] < min_arm_length) - ++ idx_next; - // Calculate angle between idx_prev, idx_curr, idx_next. - const Point &p0 = polygon.points[idx_prev]; - const Point &p1 = polygon.points[idx_curr]; - const Point &p2 = polygon.points[idx_next]; - const Point v1 = p1 - p0; - const Point v2 = p2 - p1; - int64_t dot = int64_t(v1(0))*int64_t(v2(0)) + int64_t(v1(1))*int64_t(v2(1)); - int64_t cross = int64_t(v1(0))*int64_t(v2(1)) - int64_t(v1(1))*int64_t(v2(0)); - float angle = float(atan2(double(cross), double(dot))); - angles[idx_curr] = angle; - } - - return angles; -} - - - -void SeamPlacer::init(const Print& print) -{ - m_enforcers.clear(); - m_blockers.clear(); - m_seam_history.clear(); - m_po_list.clear(); - - const std::vector& nozzle_dmrs = print.config().nozzle_diameter.values; - float max_nozzle_dmr = *std::max_element(nozzle_dmrs.begin(), nozzle_dmrs.end()); - - - std::vector temp_enf; - std::vector temp_blk; - std::vector temp_polygons; - - for (const PrintObject* po : print.objects()) { - - auto merge_and_offset = [po, &temp_polygons, max_nozzle_dmr](EnforcerBlockerType type, std::vector& out) { - // Offset the triangles out slightly. - auto offset_out = [](Polygon& input, float offset) -> ExPolygons { - ClipperLib::Paths out(1); - std::vector deltas(input.points.size(), offset); - input.make_counter_clockwise(); - out.front() = mittered_offset_path_scaled(input.points, deltas, 3.); - return ClipperPaths_to_Slic3rExPolygons(out, true); // perform union - }; - - - temp_polygons.clear(); - po->project_and_append_custom_facets(true, type, temp_polygons); - out.clear(); - out.reserve(temp_polygons.size()); - float offset = scale_(max_nozzle_dmr + po->config().elefant_foot_compensation); - for (Polygons &src : temp_polygons) { - out.emplace_back(ExPolygons()); - for (Polygon& plg : src) { - ExPolygons offset_explg = offset_out(plg, offset); - if (! offset_explg.empty()) - out.back().emplace_back(std::move(offset_explg.front())); - } - - offset = scale_(max_nozzle_dmr); - } - }; - merge_and_offset(EnforcerBlockerType::BLOCKER, temp_blk); - merge_and_offset(EnforcerBlockerType::ENFORCER, temp_enf); - - // Remember this PrintObject and initialize a store of enforcers and blockers for it. - m_po_list.push_back(po); - size_t po_idx = m_po_list.size() - 1; - m_enforcers.emplace_back(std::vector(temp_enf.size())); - m_blockers.emplace_back(std::vector(temp_blk.size())); - - // A helper class to store data to build the AABB tree from. - class CustomTriangleRef { - public: - CustomTriangleRef(size_t idx, - Point&& centroid, - BoundingBox&& bb) - : m_idx{idx}, m_centroid{centroid}, - m_bbox{AlignedBoxType(bb.min, bb.max)} - {} - size_t idx() const { return m_idx; } - const Point& centroid() const { return m_centroid; } - const TreeType::BoundingBox& bbox() const { return m_bbox; } - - private: - size_t m_idx; - Point m_centroid; - AlignedBoxType m_bbox; - }; - - // A lambda to extract the ExPolygons and save them into the member AABB tree. - // Will be called for enforcers and blockers separately. - auto add_custom = [](std::vector& src, std::vector& dest) { - // Go layer by layer, and append all the ExPolygons into the AABB tree. - size_t layer_idx = 0; - for (ExPolygons& expolys_on_layer : src) { - CustomTrianglesPerLayer& layer_data = dest[layer_idx]; - std::vector triangles_data; - layer_data.polys.reserve(expolys_on_layer.size()); - triangles_data.reserve(expolys_on_layer.size()); - - for (ExPolygon& expoly : expolys_on_layer) { - if (expoly.empty()) - continue; - layer_data.polys.emplace_back(std::move(expoly)); - triangles_data.emplace_back(layer_data.polys.size() - 1, - layer_data.polys.back().centroid(), - layer_data.polys.back().bounding_box()); - } - // All polygons are saved, build the AABB tree for them. - layer_data.tree.build(std::move(triangles_data)); - ++layer_idx; - } - }; - - add_custom(temp_enf, m_enforcers.at(po_idx)); - add_custom(temp_blk, m_blockers.at(po_idx)); - } -} - - - -void SeamPlacer::plan_perimeters(const std::vector perimeters, - const Layer& layer, SeamPosition seam_position, - Point last_pos, coordf_t nozzle_dmr, const PrintObject* po, - const EdgeGrid::Grid* lower_layer_edge_grid) -{ - // When printing the perimeters, we want the seams on external and internal perimeters to match. - // We have a list of perimeters in the order to be printed. Each internal perimeter must inherit - // the seam from the previous external perimeter. - - m_plan.clear(); - m_plan_idx = 0; - - if (perimeters.empty() || ! po) - return; - - m_plan.resize(perimeters.size()); - - for (int i = 0; i < int(perimeters.size()); ++i) { - if (perimeters[i]->role() == erExternalPerimeter && perimeters[i]->is_loop()) { - last_pos = this->calculate_seam( - layer, seam_position, *dynamic_cast(perimeters[i]), nozzle_dmr, - po, lower_layer_edge_grid, last_pos); - m_plan[i].external = true; - m_plan[i].seam_position = seam_position; - m_plan[i].layer = &layer; - m_plan[i].po = po; - } - m_plan[i].pt = last_pos; - } -} - - -void SeamPlacer::place_seam(ExtrusionLoop& loop, const Point& last_pos, bool external_first, double nozzle_diameter, - const EdgeGrid::Grid* lower_layer_edge_grid) -{ - const double seam_offset = nozzle_diameter; - - Point seam = last_pos; - if (! m_plan.empty() && m_plan_idx < m_plan.size()) { - if (m_plan[m_plan_idx].external) { - seam = m_plan[m_plan_idx].pt; - // One more heuristics: if the seam is too far from current nozzle position, - // try to place it again. This can happen in cases where the external perimeter - // does not belong to the preceding ones and they are ordered so they end up - // far from each other. - if ((seam.cast() - last_pos.cast()).squaredNorm() > std::pow(scale_(5.*nozzle_diameter), 2.)) - seam = this->calculate_seam(*m_plan[m_plan_idx].layer, m_plan[m_plan_idx].seam_position, loop, nozzle_diameter, - m_plan[m_plan_idx].po, lower_layer_edge_grid, last_pos); - } - else if (! external_first) { - // Internal perimeter printed before the external. - // First get list of external seams. - std::vector ext_seams; - for (size_t i = 0; i < m_plan.size(); ++i) { - if (m_plan[i].external) - ext_seams.emplace_back(i); - } - - if (! ext_seams.empty()) { - // First find the line segment closest to an external seam: - int path_idx = 0; - int line_idx = 0; - size_t ext_seam_idx = size_t(-1); - double min_dist_sqr = std::numeric_limits::max(); - std::vector lines_vect; - for (int i = 0; i < int(loop.paths.size()); ++i) { - lines_vect.emplace_back(loop.paths[i].polyline.lines()); - const Lines& lines = lines_vect.back(); - for (int j = 0; j < int(lines.size()); ++j) { - for (size_t k : ext_seams) { - double d_sqr = lines[j].distance_to_squared(m_plan[k].pt); - if (d_sqr < min_dist_sqr) { - path_idx = i; - line_idx = j; - ext_seam_idx = k; - min_dist_sqr = d_sqr; + Vec3d ray_origin_d = (center + normal * 0.01f).cast(); // start above surface. + if (casting_from_negative_volume) { // if casting from negative volume face, invert direction, change start pos + final_ray_dir = -1.0 * final_ray_dir; + ray_origin_d = (center - normal * 0.01f).cast(); + } + Vec3d final_ray_dir_d = final_ray_dir.cast(); + bool some_hit = AABBTreeIndirect::intersect_ray_all_hits(triangles.vertices, triangles.indices, raycasting_tree, ray_origin_d, final_ray_dir_d, hits); + if (some_hit) { + int counter = 0; + // NOTE: iterating in reverse, from the last hit for one simple reason: We know the state of the ray at that point; + // It cannot be inside model, and it cannot be inside negative volume + for (int hit_index = int(hits.size()) - 1; hit_index >= 0; --hit_index) { + Vec3f face_normal = its_face_normal(triangles, hits[hit_index].id); + if (hits[hit_index].id >= int(negative_volumes_start_index)) { // negative volume hit + counter -= sgn(face_normal.dot(final_ray_dir)); // if volume face aligns with ray dir, we are leaving negative space + // which in reverse hit analysis means, that we are entering negative space :) and vice versa + } else { + counter += sgn(face_normal.dot(final_ray_dir)); } } + if (counter == 0) { result[s_idx] -= decrease_step; } } } - - // Only accept seam that is reasonably close. - double limit_dist_sqr = std::pow(double(scale_((ext_seam_idx - m_plan_idx) * nozzle_diameter * 2.)), 2.); - if (ext_seam_idx != size_t(-1) && min_dist_sqr < limit_dist_sqr) { - // Now find a projection of the external seam - const Lines& lines = lines_vect[path_idx]; - Point closest = m_plan[ext_seam_idx].pt.projection_onto(lines[line_idx]); - double dist = (closest.cast() - lines[line_idx].b.cast()).norm(); - - // And walk along the perimeter until we make enough space for - // seams of all perimeters beforethe external one. - double offset = (ext_seam_idx - m_plan_idx) * scale_(seam_offset); - double last_offset = offset; - offset -= dist; - const Point* a = &closest; - const Point* b = &lines[line_idx].b; - while (++line_idx < int(lines.size()) && offset > 0.) { - last_offset = offset; - offset -= lines[line_idx].length(); - a = &lines[line_idx].a; - b = &lines[line_idx].b; - } - - // We have walked far enough, too far maybe. Interpolate on the - // last segment to find the end precisely. - offset = std::min(0., offset); // In case that offset is still positive (we may have "wrapped around") - double ratio = last_offset / (last_offset - offset); - seam = (a->cast() + ((b->cast() - a->cast()) * ratio)).cast(); - } } } - else { - // We should have a candidate ready from before. If not, use last_pos. - if (m_plan_idx > 0 && m_plan[m_plan_idx - 1].precalculated) - seam = m_plan[m_plan_idx - 1].pt; - } - } + }); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: raycast visibility of " << samples.positions.size() << " samples over " << triangles.indices.size() << " triangles: end"; - // Split the loop at the point with a minium penalty. - if (!loop.split_at_vertex(seam)) - // The point is not in the original loop. Insert it. - loop.split_at(seam, true); - - if (external_first && m_plan_idx+1 1) { - const ExtrusionPath& last = loop.paths.back(); - auto it = last.polyline.points.crbegin() + 1; - for (; it != last.polyline.points.crend(); ++it) { - running_sqr += (it->cast() - (it - 1)->cast()).squaredNorm(); - if (running_sqr > dist_sqr) - break; - running_sqr_last = running_sqr; - } - if (running_sqr <= dist_sqr) - it = last.polyline.points.crend() - 1; - // Now interpolate. - double ratio = (std::sqrt(dist_sqr) - std::sqrt(running_sqr_last)) / (std::sqrt(running_sqr) - std::sqrt(running_sqr_last)); - m_plan[m_plan_idx + 1].pt = ((it - 1)->cast() + (it->cast() - (it - 1)->cast()) * std::min(ratio, 1.)).cast(); - m_plan[m_plan_idx + 1].precalculated = true; - } - } - - ++m_plan_idx; + return result; } -constexpr float CLOSE_TO_LAST_SEAM_THRESHOLD = 5; - -// Returns a seam for an EXTERNAL perimeter. -Point SeamPlacer::calculate_seam(const Layer& layer, const SeamPosition seam_position, - const ExtrusionLoop& loop, coordf_t nozzle_dmr, const PrintObject* po, - const EdgeGrid::Grid* lower_layer_edge_grid, Point last_pos) +std::vector calculate_polygon_angles_at_vertices(const Polygon &polygon, const std::vector &lengths, float min_arm_length) { - assert(loop.role() == erExternalPerimeter); - Polygon polygon = loop.polygon(); - bool was_clockwise = polygon.make_counter_clockwise(); - BoundingBox polygon_bb = polygon.bounding_box(); - const coord_t nozzle_r = coord_t(scale_(0.5 * nozzle_dmr) + 0.5); + std::vector result(polygon.size()); - size_t po_idx = std::find(m_po_list.begin(), m_po_list.end(), po) - m_po_list.begin(); + if (polygon.size() == 1) { result[0] = 0.0f; } - // Find current layer in respective PrintObject. Cache the result so the - // lookup is only done once per layer, not for each loop. - const Layer* layer_po = nullptr; - if (po == m_last_po && layer.print_z == m_last_print_z) - layer_po = m_last_layer_po; - else { - layer_po = po->get_layer_at_printz(layer.print_z); - m_last_po = po; - m_last_print_z = layer.print_z; - m_last_layer_po = layer_po; - } - if (! layer_po) - return last_pos; + size_t idx_prev = 0; + size_t idx_curr = 0; + size_t idx_next = 0; - // Index of this layer in the respective PrintObject. - size_t layer_idx = layer_po->id() - po->layers().front()->id(); // raft layers + float distance_to_prev = 0; + float distance_to_next = 0; - assert(layer_idx < po->layer_count()); - - if (this->is_custom_seam_on_layer(layer_idx, po_idx)) { - // Seam enf/blockers can begin and end in between the original vertices. - // Let add extra points in between and update the leghths. - polygon.densify(MINIMAL_POLYGON_SIDE); + // push idx_prev far enough back as initialization + while (distance_to_prev < min_arm_length) { + idx_prev = Slic3r::prev_idx_modulo(idx_prev, polygon.size()); + distance_to_prev += lengths[idx_prev]; } - if (seam_position != spRandom) { - // Retrieve the last start position for this object. - float last_pos_weight = 1.f; - - if (seam_position == spAligned) { - // Seam is aligned to the seam at the preceding layer. - if (po != nullptr) { - std::optional pos = m_seam_history.get_last_seam(m_po_list[po_idx], layer_idx, polygon_bb); - if (pos.has_value()) { - last_pos = *pos; - last_pos_weight = is_custom_enforcer_on_layer(layer_idx, po_idx) ? 0.f : 1.f; - } - } - } - else if (seam_position == spRear) { - // Object is centered around (0,0) in its current coordinate system. - last_pos.x() = 0; - last_pos.y() = coord_t(3. * po->bounding_box().radius()); - last_pos_weight = 5.f; - } if (seam_position == spNearest) { - // last_pos already contains current nozzle position - - // BBS: if the project point of current nozzle position is close to the last seam of this object - // then we think the current nozzle position is almost same with last same. - // So that last seam can be treat as one factor even in cost based strategy to make seam more posible to be aligned - if (po != nullptr) { - std::optional pos = m_seam_history.get_last_seam(m_po_list[po_idx], layer_idx, polygon_bb); - if (pos.has_value()) { - Point project_point = polygon.point_projection(last_pos); - if ((pos->cast() - project_point.cast()).squaredNorm() < std::pow(scale_(CLOSE_TO_LAST_SEAM_THRESHOLD), 2.)) - last_pos = *pos; - } - } + for (size_t _i = 0; _i < polygon.size(); ++_i) { + // pull idx_prev to current as much as possible, while respecting the min_arm_length + while (distance_to_prev - lengths[idx_prev] > min_arm_length) { + distance_to_prev -= lengths[idx_prev]; + idx_prev = Slic3r::next_idx_modulo(idx_prev, polygon.size()); } - // Insert a projection of last_pos into the polygon. - size_t last_pos_proj_idx; - { - auto it = project_point_to_polygon_and_insert(polygon, last_pos, 0.1 * nozzle_r); - last_pos_proj_idx = it - polygon.points.begin(); + // push idx_next forward as far as needed + while (distance_to_next < min_arm_length) { + distance_to_next += lengths[idx_next]; + idx_next = Slic3r::next_idx_modulo(idx_next, polygon.size()); } - // Parametrize the polygon by its length. - std::vector lengths = polygon.parameter_by_length(); + // Calculate angle between idx_prev, idx_curr, idx_next. + const Point &p0 = polygon.points[idx_prev]; + const Point &p1 = polygon.points[idx_curr]; + const Point &p2 = polygon.points[idx_next]; + result[idx_curr] = float(angle(p1 - p0, p2 - p1)); - // For each polygon point, store a penalty. - // First calculate the angles, store them as penalties. The angles are caluculated over a minimum arm length of nozzle_r. - std::vector penalties = polygon_angles_at_vertices(polygon, lengths, float(nozzle_r)); - // No penalty for reflex points, slight penalty for convex points, high penalty for flat surfaces. - const float penaltyConvexVertex = 1.f; - const float penaltyFlatSurface = 5.f; - const float penaltyOverhangHalf = 10.f; - // Penalty for visible seams. - for (size_t i = 0; i < polygon.points.size(); ++ i) { - float ccwAngle = penalties[i]; - if (was_clockwise) - ccwAngle = - ccwAngle; - float penalty = 0; - if (ccwAngle <- float(0.6 * PI)) - // Sharp reflex vertex. We love that, it hides the seam perfectly. - penalty = 0.f; - else if (ccwAngle > float(0.6 * PI)) - // Seams on sharp convex vertices are more visible than on reflex vertices. - penalty = penaltyConvexVertex; - else if (ccwAngle < 0.f) { - // Interpolate penalty between maximum and zero. - penalty = penaltyFlatSurface * bspline_kernel(ccwAngle * float(PI * 2. / 3.)); - } else { - assert(ccwAngle >= 0.f); - // Interpolate penalty between maximum and the penalty for a convex vertex. - penalty = penaltyConvexVertex + (penaltyFlatSurface - penaltyConvexVertex) * bspline_kernel(ccwAngle * float(PI * 2. / 3.)); - } - // Give a negative penalty for points close to the last point or the prefered seam location. - float dist_to_last_pos_proj = (i < last_pos_proj_idx) ? - std::min(lengths[last_pos_proj_idx] - lengths[i], lengths.back() - lengths[last_pos_proj_idx] + lengths[i]) : - std::min(lengths[i] - lengths[last_pos_proj_idx], lengths.back() - lengths[i] + lengths[last_pos_proj_idx]); - float dist_max = 0.1f * lengths.back(); // 5.f * nozzle_dmr - penalty -= last_pos_weight * bspline_kernel(dist_to_last_pos_proj / dist_max); - penalties[i] = std::max(0.f, penalty); - } + // increase idx_curr by one + float curr_distance = lengths[idx_curr]; + idx_curr++; + distance_to_prev += curr_distance; + distance_to_next -= curr_distance; + } - // Penalty for overhangs. - if (lower_layer_edge_grid) { - // Use the edge grid distance field structure over the lower layer to calculate overhangs. - coord_t nozzle_r = coord_t(std::floor(scale_(0.5 * nozzle_dmr) + 0.5)); - coord_t search_r = coord_t(std::floor(scale_(0.8 * nozzle_dmr) + 0.5)); - for (size_t i = 0; i < polygon.points.size(); ++ i) { - const Point &p = polygon.points[i]; - coordf_t dist; - // Signed distance is positive outside the object, negative inside the object. - // The point is considered at an overhang, if it is more than nozzle radius - // outside of the lower layer contour. - [[maybe_unused]] bool found = lower_layer_edge_grid->signed_distance(p, search_r, dist); - // If the approximate Signed Distance Field was initialized over lower_layer_edge_grid, - // then the signed distnace shall always be known. - assert(found); - penalties[i] += extrudate_overlap_penalty(float(nozzle_r), penaltyOverhangHalf, float(dist)); - } - } - - // Custom seam. Huge (negative) constant penalty is applied inside - // blockers (enforcers) to rule out points that should not win. - this->apply_custom_seam(polygon, po_idx, penalties, lengths, layer_idx, seam_position); - - // Find a point with a minimum penalty. - size_t idx_min = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); - - if (seam_position != spAligned || ! is_custom_enforcer_on_layer(layer_idx, po_idx)) { - // Very likely the weight of idx_min is very close to the weight of last_pos_proj_idx. - // In that case use last_pos_proj_idx instead. - float penalty_aligned = penalties[last_pos_proj_idx]; - float penalty_min = penalties[idx_min]; - float penalty_diff_abs = std::abs(penalty_min - penalty_aligned); - float penalty_max = std::max(std::abs(penalty_min), std::abs(penalty_aligned)); - float penalty_diff_rel = (penalty_max == 0.f) ? 0.f : penalty_diff_abs / penalty_max; - // printf("Align seams, penalty aligned: %f, min: %f, diff abs: %f, diff rel: %f\n", penalty_aligned, penalty_min, penalty_diff_abs, penalty_diff_rel); - if (std::abs(penalty_diff_rel) < 0.05) { - // Penalty of the aligned point is very close to the minimum penalty. - // Align the seams as accurately as possible. - idx_min = last_pos_proj_idx; - } - } - - if (seam_position == spAligned || seam_position == spNearest) - m_seam_history.add_seam(po, polygon.points[idx_min], polygon_bb); - - - // Export the contour into a SVG file. - #if 0 - { - static int iRun = 0; - SVG svg(debug_out_path("GCode_extrude_loop-%d.svg", iRun ++)); - if (m_layer->lower_layer != NULL) - svg.draw(m_layer->lower_layer->slices); - for (size_t i = 0; i < loop.paths.size(); ++ i) - svg.draw(loop.paths[i].as_polyline(), "red"); - Polylines polylines; - for (size_t i = 0; i < loop.paths.size(); ++ i) - polylines.push_back(loop.paths[i].as_polyline()); - Slic3r::Polygons polygons; - coordf_t nozzle_dmr = EXTRUDER_CONFIG(nozzle_diameter); - coord_t delta = scale_(0.5*nozzle_dmr); - Slic3r::offset(polylines, &polygons, delta); -// for (size_t i = 0; i < polygons.size(); ++ i) svg.draw((Polyline)polygons[i], "blue"); - svg.draw(last_pos, "green", 3); - svg.draw(polygon.points[idx_min], "yellow", 3); - svg.Close(); - } - #endif - return polygon.points[idx_min]; - - } else - return this->get_random_seam(layer_idx, polygon, po_idx); + return result; } - -Point SeamPlacer::get_random_seam(size_t layer_idx, const Polygon& polygon, size_t po_idx, - bool* saw_custom) const +struct CoordinateFunctor { - // Parametrize the polygon by its length. - const std::vector lengths = polygon.parameter_by_length(); + const std::vector *coordinates; + CoordinateFunctor(const std::vector *coords) : coordinates(coords) {} + CoordinateFunctor() : coordinates(nullptr) {} - // Which of the points are inside enforcers/blockers? - std::vector enforcers_idxs; - std::vector blockers_idxs; - this->get_enforcers_and_blockers(layer_idx, polygon, po_idx, enforcers_idxs, blockers_idxs); + const float &operator()(size_t idx, size_t dim) const { return coordinates->operator[](idx)[dim]; } +}; - bool has_enforcers = ! enforcers_idxs.empty(); - bool has_blockers = ! blockers_idxs.empty(); - if (saw_custom) - *saw_custom = has_enforcers || has_blockers; +// structure to store global information about the model - occlusion hits, enforcers, blockers +struct GlobalModelInfo +{ + TriangleSetSamples mesh_samples; + std::vector mesh_samples_visibility; + CoordinateFunctor mesh_samples_coordinate_functor; + KDTreeIndirect<3, float, CoordinateFunctor> mesh_samples_tree{CoordinateFunctor{}}; + float mesh_samples_radius; - assert(std::is_sorted(enforcers_idxs.begin(), enforcers_idxs.end())); - assert(std::is_sorted(blockers_idxs.begin(), blockers_idxs.end())); - std::vector edges; + indexed_triangle_set enforcers; + indexed_triangle_set blockers; + AABBTreeIndirect::Tree<3, float> enforcers_tree; + AABBTreeIndirect::Tree<3, float> blockers_tree; - // Lambda to calculate lengths of all edges of interest. Last parameter - // decides whether to measure edges inside or outside idxs. - // Negative number = not an edge of interest. - auto get_valid_length = [&lengths](const std::vector& idxs, - std::vector& edges, - bool measure_inside_edges) -> float + bool is_enforced(const Vec3f &position, float radius) const { - // First mark edges we are interested in by assigning a positive number. - edges.assign(lengths.size()-1, measure_inside_edges ? -1.f : 1.f); - for (size_t i=0; i the edge between them is the enforcer/blocker. - bool inside_edge = ((i != idxs.size()-1 && idxs[i+1] == this_pt_idx + 1) - || (i == idxs.size()-1 && idxs.back() == lengths.size()-2 && idxs[0] == 0)); - if (inside_edge) - edges[this_pt_idx] = measure_inside_edges ? 1.f : -1.f; + if (enforcers.empty()) { return false; } + float radius_sqr = radius * radius; + return AABBTreeIndirect::is_any_triangle_in_radius(enforcers.vertices, enforcers.indices, enforcers_tree, position, radius_sqr); + } + + bool is_blocked(const Vec3f &position, float radius) const + { + if (blockers.empty()) { return false; } + float radius_sqr = radius * radius; + return AABBTreeIndirect::is_any_triangle_in_radius(blockers.vertices, blockers.indices, blockers_tree, position, radius_sqr); + } + + float calculate_point_visibility(const Vec3f &position) const + { + std::vector points = find_nearby_points(mesh_samples_tree, position, mesh_samples_radius); + if (points.empty()) { return 1.0f; } + + auto compute_dist_to_plane = [](const Vec3f &position, const Vec3f &plane_origin, const Vec3f &plane_normal) { + Vec3f orig_to_point = position - plane_origin; + return std::abs(orig_to_point.dot(plane_normal)); + }; + + float total_weight = 0; + float total_visibility = 0; + for (size_t i = 0; i < points.size(); ++i) { + size_t sample_idx = points[i]; + + Vec3f sample_point = this->mesh_samples.positions[sample_idx]; + Vec3f sample_normal = this->mesh_samples.normals[sample_idx]; + + float weight = mesh_samples_radius - compute_dist_to_plane(position, sample_point, sample_normal); + weight += (mesh_samples_radius - (position - sample_point).norm()); + total_visibility += weight * mesh_samples_visibility[sample_idx]; + total_weight += weight; } - // Now measure them. - float running_total = 0.f; - for (size_t i=0; i 0.f) { - edges[i] = lengths[i+1] - lengths[i]; - running_total += edges[i]; + + return total_visibility / total_weight; + } + +#ifdef DEBUG_FILES + void debug_export(const indexed_triangle_set &obj_mesh) const + { + indexed_triangle_set divided_mesh = obj_mesh; + Slic3r::CNumericLocalesSetter locales_setter; + + { + auto filename = debug_out_path("visiblity.obj"); + FILE *fp = boost::nowide::fopen(filename.c_str(), "w"); + if (fp == nullptr) { + BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << filename << " for writing"; + return; + } + + for (size_t i = 0; i < divided_mesh.vertices.size(); ++i) { + float visibility = calculate_point_visibility(divided_mesh.vertices[i]); + Vec3f color = value_to_rgbf(0.0f, 1.0f, visibility); + fprintf(fp, "v %f %f %f %f %f %f\n", divided_mesh.vertices[i](0), divided_mesh.vertices[i](1), divided_mesh.vertices[i](2), color(0), color(1), color(2)); + } + for (size_t i = 0; i < divided_mesh.indices.size(); ++i) + fprintf(fp, "f %d %d %d\n", divided_mesh.indices[i][0] + 1, divided_mesh.indices[i][1] + 1, divided_mesh.indices[i][2] + 1); + fclose(fp); + } + + { + auto filename = debug_out_path("visiblity_samples.obj"); + FILE *fp = boost::nowide::fopen(filename.c_str(), "w"); + if (fp == nullptr) { + BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << filename << " for writing"; + return; + } + + for (size_t i = 0; i < mesh_samples.positions.size(); ++i) { + float visibility = mesh_samples_visibility[i]; + Vec3f color = value_to_rgbf(0.0f, 1.0f, visibility); + fprintf(fp, "v %f %f %f %f %f %f\n", mesh_samples.positions[i](0), mesh_samples.positions[i](1), mesh_samples.positions[i](2), color(0), color(1), color(2)); + } + fclose(fp); + } + } +#endif +}; + +// Extract perimeter polygons of the given layer +Polygons extract_perimeter_polygons(const Layer *layer, const SeamPosition configured_seam_preference, std::vector &corresponding_regions_out) +{ + Polygons polygons; + for (const LayerRegion *layer_region : layer->regions()) { + for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities) { + if (ex_entity->is_collection()) { // collection of inner, outer, and overhang perimeters + for (const ExtrusionEntity *perimeter : static_cast(ex_entity)->entities) { + ExtrusionRole role = perimeter->role(); + if (perimeter->is_loop()) { + for (const ExtrusionPath &path : static_cast(perimeter)->paths) { + if (path.role() == ExtrusionRole::erExternalPerimeter) { role = ExtrusionRole::erExternalPerimeter; } + } + } + + if (role == ExtrusionRole::erExternalPerimeter || + (is_perimeter(role) && configured_seam_preference == spRandom)) { // for random seam alignment, extract all perimeters + Points p; + perimeter->collect_points(p); + polygons.emplace_back(std::move(p)); + corresponding_regions_out.push_back(layer_region); + } + } + if (polygons.empty()) { + Points p; + ex_entity->collect_points(p); + polygons.emplace_back(std::move(p)); + corresponding_regions_out.push_back(layer_region); + } + } else { + Points p; + ex_entity->collect_points(p); + polygons.emplace_back(std::move(p)); + corresponding_regions_out.push_back(layer_region); } } - return running_total; + } + + if (polygons.empty()) { // If there are no perimeter polygons for whatever reason (disabled perimeters .. ) insert dummy point + // it is easier than checking everywhere if the layer is not emtpy, no seam will be placed to this layer anyway + polygons.emplace_back(std::vector{Point{0, 0}}); + corresponding_regions_out.push_back(nullptr); + } + + return polygons; +} + +// Insert SeamCandidates created from perimeter polygons in to the result vector. +// Compute its type (Enfrocer,Blocker), angle, and position +// each SeamCandidate also contains pointer to shared Perimeter structure representing the polygon +// if Custom Seam modifiers are present, oversamples the polygon if necessary to better fit user intentions +void process_perimeter_polygon( + const Polygon &orig_polygon, float z_coord, const LayerRegion *region, const GlobalModelInfo &global_model_info, PrintObjectSeamData::LayerSeams &result) +{ + if (orig_polygon.size() == 0) { return; } + Polygon polygon = orig_polygon; + bool was_clockwise = polygon.make_counter_clockwise(); + float angle_arm_len = region != nullptr ? region->flow(FlowRole::frExternalPerimeter).nozzle_diameter() : 0.5f; + + std::vector lengths{}; + for (size_t point_idx = 0; point_idx < polygon.size() - 1; ++point_idx) { lengths.push_back((unscale(polygon[point_idx]) - unscale(polygon[point_idx + 1])).norm()); } + lengths.push_back(std::max((unscale(polygon[0]) - unscale(polygon[polygon.size() - 1])).norm(), 0.1)); + std::vector polygon_angles = calculate_polygon_angles_at_vertices(polygon, lengths, angle_arm_len); + + result.perimeters.push_back({}); + Perimeter &perimeter = result.perimeters.back(); + + std::queue orig_polygon_points{}; + for (size_t index = 0; index < polygon.size(); ++index) { + Vec2f unscaled_p = unscale(polygon[index]).cast(); + orig_polygon_points.emplace(unscaled_p.x(), unscaled_p.y(), z_coord); + } + Vec3f first = orig_polygon_points.front(); + std::queue oversampled_points{}; + size_t orig_angle_index = 0; + perimeter.start_index = result.points.size(); + perimeter.flow_width = region != nullptr ? region->flow(FlowRole::frExternalPerimeter).width() : 0.0f; + bool some_point_enforced = false; + while (!orig_polygon_points.empty() || !oversampled_points.empty()) { + EnforcedBlockedSeamPoint type = EnforcedBlockedSeamPoint::Neutral; + Vec3f position; + float local_ccw_angle = 0; + bool orig_point = false; + if (!oversampled_points.empty()) { + position = oversampled_points.front(); + oversampled_points.pop(); + } else { + position = orig_polygon_points.front(); + orig_polygon_points.pop(); + local_ccw_angle = was_clockwise ? -polygon_angles[orig_angle_index] : polygon_angles[orig_angle_index]; + orig_angle_index++; + orig_point = true; + } + + if (global_model_info.is_enforced(position, perimeter.flow_width)) { type = EnforcedBlockedSeamPoint::Enforced; } + + if (global_model_info.is_blocked(position, perimeter.flow_width)) { type = EnforcedBlockedSeamPoint::Blocked; } + some_point_enforced = some_point_enforced || type == EnforcedBlockedSeamPoint::Enforced; + + if (orig_point) { + Vec3f pos_of_next = orig_polygon_points.empty() ? first : orig_polygon_points.front(); + float distance_to_next = (position - pos_of_next).norm(); + if (global_model_info.is_enforced(position, distance_to_next)) { + Vec3f vec_to_next = (pos_of_next - position).normalized(); + float step_size = SeamPlacer::enforcer_oversampling_distance; + float step = step_size; + while (step < distance_to_next) { + oversampled_points.push(position + vec_to_next * step); + step += step_size; + } + } + } + + result.points.emplace_back(position, perimeter, local_ccw_angle, type); + } + + perimeter.end_index = result.points.size(); + + if (some_point_enforced) { + // We will patches of enforced points (patch: continuous section of enforced points), choose + // the longest patch, and select the middle point or sharp point (depending on the angle) + // this point will have high priority on this perimeter + size_t perimeter_size = perimeter.end_index - perimeter.start_index; + const auto next_index = [&](size_t idx) { return perimeter.start_index + Slic3r::next_idx_modulo(idx - perimeter.start_index, perimeter_size); }; + + std::vector patches_starts_ends; + for (size_t i = perimeter.start_index; i < perimeter.end_index; ++i) { + if (result.points[i].type != EnforcedBlockedSeamPoint::Enforced && result.points[next_index(i)].type == EnforcedBlockedSeamPoint::Enforced) { + patches_starts_ends.push_back(next_index(i)); + } + if (result.points[i].type == EnforcedBlockedSeamPoint::Enforced && result.points[next_index(i)].type != EnforcedBlockedSeamPoint::Enforced) { + patches_starts_ends.push_back(next_index(i)); + } + } + // if patches_starts_ends are empty, it means that the whole perimeter is enforced.. don't do anything in that case + if (!patches_starts_ends.empty()) { + // if the first point in the patches is not enforced, it marks a patch end. in that case, put it to the end and start on next + // to simplify the processing + assert(patches_starts_ends.size() % 2 == 0); + bool start_on_second = false; + if (result.points[patches_starts_ends[0]].type != EnforcedBlockedSeamPoint::Enforced) { + start_on_second = true; + patches_starts_ends.push_back(patches_starts_ends[0]); + } + // now pick the longest patch + std::pair longest_patch{0, 0}; + auto patch_len = [perimeter_size](const std::pair &start_end) { + if (start_end.second < start_end.first) { + return start_end.first + (perimeter_size - start_end.second); + } else { + return start_end.second - start_end.first; + } + }; + for (size_t patch_idx = start_on_second ? 1 : 0; patch_idx < patches_starts_ends.size(); patch_idx += 2) { + std::pair current_patch{patches_starts_ends[patch_idx], patches_starts_ends[patch_idx + 1]}; + if (patch_len(longest_patch) < patch_len(current_patch)) { longest_patch = current_patch; } + } + std::vector viable_points_indices; + std::vector large_angle_points_indices; + for (size_t point_idx = longest_patch.first; point_idx != longest_patch.second; point_idx = next_index(point_idx)) { + viable_points_indices.push_back(point_idx); + if (std::abs(result.points[point_idx].local_ccw_angle) > SeamPlacer::sharp_angle_snapping_threshold) { large_angle_points_indices.push_back(point_idx); } + } + assert(viable_points_indices.size() > 0); + if (large_angle_points_indices.empty()) { + size_t central_idx = viable_points_indices[viable_points_indices.size() / 2]; + result.points[central_idx].central_enforcer = true; + } else { + size_t central_idx = large_angle_points_indices.size() / 2; + result.points[large_angle_points_indices[central_idx]].central_enforcer = true; + } + } + } +} + +// Get index of previous and next perimeter point of the layer. Because SeamCandidates of all polygons of the given layer +// are sequentially stored in the vector, each perimeter contains info about start and end index. These vales are used to +// deduce index of previous and next neigbour in the corresponding perimeter. +std::pair find_previous_and_next_perimeter_point(const std::vector &perimeter_points, size_t point_index) +{ + const SeamCandidate ¤t = perimeter_points[point_index]; + int prev = point_index - 1; // for majority of points, it is true that neighbours lie behind and in front of them in the vector + int next = point_index + 1; + + if (point_index == current.perimeter.start_index) { + // if point_index is equal to start, it means that the previous neighbour is at the end + prev = current.perimeter.end_index; + } + + if (point_index == current.perimeter.end_index - 1) { + // if point_index is equal to end, than next neighbour is at the start + next = current.perimeter.start_index; + } + + assert(prev >= 0); + assert(next >= 0); + return {size_t(prev), size_t(next)}; +} + +// Computes all global model info - transforms object, performs raycasting +void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po, std::function throw_if_canceled) +{ + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather occlusion meshes: start"; + auto obj_transform = po->trafo_centered(); + indexed_triangle_set triangle_set; + indexed_triangle_set negative_volumes_set; + // add all parts + for (const ModelVolume *model_volume : po->model_object()->volumes) { + if (model_volume->type() == ModelVolumeType::MODEL_PART || model_volume->type() == ModelVolumeType::NEGATIVE_VOLUME) { + auto model_transformation = model_volume->get_matrix(); + indexed_triangle_set model_its = model_volume->mesh().its; + its_transform(model_its, model_transformation); + if (model_volume->type() == ModelVolumeType::MODEL_PART) { + its_merge(triangle_set, model_its); + } else { + its_merge(negative_volumes_set, model_its); + } + } + } + throw_if_canceled(); + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather occlusion meshes: end"; + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: decimate: start"; + its_short_edge_collpase(triangle_set, 25000); + its_short_edge_collpase(negative_volumes_set, 25000); + + size_t negative_volumes_start_index = triangle_set.indices.size(); + its_merge(triangle_set, negative_volumes_set); + its_transform(triangle_set, obj_transform); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: decimate: end"; + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: Compute visibility sample points: start"; + + result.mesh_samples = sample_its_uniform_parallel(SeamPlacer::raycasting_visibility_samples_count, triangle_set); + result.mesh_samples_coordinate_functor = CoordinateFunctor(&result.mesh_samples.positions); + result.mesh_samples_tree = KDTreeIndirect<3, float, CoordinateFunctor>(result.mesh_samples_coordinate_functor, result.mesh_samples.positions.size()); + + // The following code determines search area for random visibility samples on the mesh when calculating visibility of each perimeter point + // number of random samples in the given radius (area) is approximately poisson distribution + // to compute ideal search radius (area), we use exponential distribution (complementary distr to poisson) + // parameters of exponential distribution to compute area that will have with probability="probability" more than given number of samples="samples" + float probability = 0.9f; + float samples = 4; + float density = SeamPlacer::raycasting_visibility_samples_count / result.mesh_samples.total_area; + // exponential probability distrubtion function is : f(x) = P(X > x) = e^(l*x) where l is the rate parameter (computed as 1/u where u is mean value) + // probability that sampled area A with S samples contains more than samples count: + // P(S > samples in A) = e^-(samples/(density*A)); express A: + float search_area = samples / (-logf(probability) * density); + float search_radius = sqrt(search_area / PI); + result.mesh_samples_radius = search_radius; + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: Compute visiblity sample points: end"; + throw_if_canceled(); + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: Mesh sample raidus: " << result.mesh_samples_radius; + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: build AABB tree: start"; + auto raycasting_tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(triangle_set.vertices, triangle_set.indices); + + throw_if_canceled(); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: build AABB tree: end"; + result.mesh_samples_visibility = raycast_visibility(raycasting_tree, triangle_set, result.mesh_samples, negative_volumes_start_index); + throw_if_canceled(); +#ifdef DEBUG_FILES + result.debug_export(triangle_set); +#endif +} + +void gather_enforcers_blockers(GlobalModelInfo &result, const PrintObject *po) +{ + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: build AABB trees for raycasting enforcers/blockers: start"; + + auto obj_transform = po->trafo_centered(); + + for (const ModelVolume *mv : po->model_object()->volumes) { + if (mv->is_seam_painted()) { + auto model_transformation = obj_transform * mv->get_matrix(); + + indexed_triangle_set enforcers = mv->seam_facets.get_facets(*mv, EnforcerBlockerType::ENFORCER); + its_transform(enforcers, model_transformation); + its_merge(result.enforcers, enforcers); + + indexed_triangle_set blockers = mv->seam_facets.get_facets(*mv, EnforcerBlockerType::BLOCKER); + its_transform(blockers, model_transformation); + its_merge(result.blockers, blockers); + } + } + + result.enforcers_tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(result.enforcers.vertices, result.enforcers.indices); + result.blockers_tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(result.blockers.vertices, result.blockers.indices); + + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: build AABB trees for raycasting enforcers/blockers: end"; +} + +struct SeamComparator +{ + SeamPosition setup; + float angle_importance; + explicit SeamComparator(SeamPosition setup) : setup(setup) + { + angle_importance = setup == spNearest ? SeamPlacer::angle_importance_nearest : SeamPlacer::angle_importance_aligned; + } + + // Standard comparator, must respect the requirements of comparators (e.g. give same result on same inputs) for sorting usage + // should return if a is better seamCandidate than b + bool is_first_better(const SeamCandidate &a, const SeamCandidate &b, const Vec2f &preffered_location = Vec2f{0.0f, 0.0f}) const + { + if (setup == SeamPosition::spAligned && a.central_enforcer != b.central_enforcer) { return a.central_enforcer; } + + // Blockers/Enforcers discrimination, top priority + if (a.type != b.type) { return a.type > b.type; } + + // avoid overhangs + if (a.overhang > 0.0f || b.overhang > 0.0f) { return a.overhang < b.overhang; } + + // prefer hidden points (more than 0.5 mm inside) + if (a.embedded_distance < -0.5f && b.embedded_distance > -0.5f) { return true; } + if (b.embedded_distance < -0.5f && a.embedded_distance > -0.5f) { return false; } + + if (setup == SeamPosition::spRear && a.position.y() != b.position.y()) { return a.position.y() > b.position.y(); } + + float distance_penalty_a = 0.0f; + float distance_penalty_b = 0.0f; + if (setup == spNearest) { + distance_penalty_a = 1.0f - gauss((a.position.head<2>() - preffered_location).norm(), 0.0f, 1.0f, 0.005f); + distance_penalty_b = 1.0f - gauss((b.position.head<2>() - preffered_location).norm(), 0.0f, 1.0f, 0.005f); + } + + // the penalites are kept close to range [0-1.x] however, it should not be relied upon + float penalty_a = a.overhang + a.visibility + angle_importance * compute_angle_penalty(a.local_ccw_angle) + distance_penalty_a; + float penalty_b = b.overhang + b.visibility + angle_importance * compute_angle_penalty(b.local_ccw_angle) + distance_penalty_b; + + return penalty_a < penalty_b; + } + + // Comparator used during alignment. If there is close potential aligned point, it is compared to the current + // seam point of the perimeter, to find out if the aligned point is not much worse than the current seam + // Also used by the random seam generator. + bool is_first_not_much_worse(const SeamCandidate &a, const SeamCandidate &b) const + { + // Blockers/Enforcers discrimination, top priority + if (setup == SeamPosition::spAligned && a.central_enforcer != b.central_enforcer) { + // Prefer centers of enforcers. + return a.central_enforcer; + } + + if (a.type == EnforcedBlockedSeamPoint::Enforced) { return true; } + + if (a.type == EnforcedBlockedSeamPoint::Blocked) { return false; } + + if (a.type != b.type) { return a.type > b.type; } + + // avoid overhangs + if ((a.overhang > 0.0f || b.overhang > 0.0f) && abs(a.overhang - b.overhang) > (0.1f * a.perimeter.flow_width)) { return a.overhang < b.overhang; } + + // prefer hidden points (more than 0.5 mm inside) + if (a.embedded_distance < -0.5f && b.embedded_distance > -0.5f) { return true; } + if (b.embedded_distance < -0.5f && a.embedded_distance > -0.5f) { return false; } + + if (setup == SeamPosition::spRandom) { return true; } + + if (setup == SeamPosition::spRear) { return a.position.y() + SeamPlacer::seam_align_score_tolerance * 5.0f > b.position.y(); } + + float penalty_a = a.overhang + a.visibility + angle_importance * compute_angle_penalty(a.local_ccw_angle); + float penalty_b = b.overhang + b.visibility + angle_importance * compute_angle_penalty(b.local_ccw_angle); + + return penalty_a <= penalty_b || penalty_a - penalty_b < SeamPlacer::seam_align_score_tolerance; + } + + bool are_similar(const SeamCandidate &a, const SeamCandidate &b) const { return is_first_not_much_worse(a, b) && is_first_not_much_worse(b, a); } +}; + +#ifdef DEBUG_FILES +void debug_export_points(const std::vector &layers, const BoundingBox &bounding_box, const SeamComparator &comparator) +{ + for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) { + std::string angles_file_name = debug_out_path(("angles_" + std::to_string(layer_idx) + ".svg").c_str()); + SVG angles_svg{angles_file_name, bounding_box}; + float min_vis = 0; + float max_vis = min_vis; + + float min_weight = std::numeric_limits::min(); + float max_weight = min_weight; + + for (const SeamCandidate &point : layers[layer_idx].points) { + Vec3i color = value_to_rgbi(-PI, PI, point.local_ccw_angle); + std::string fill = "rgb(" + std::to_string(color.x()) + "," + std::to_string(color.y()) + "," + std::to_string(color.z()) + ")"; + angles_svg.draw(scaled(Vec2f(point.position.head<2>())), fill); + min_vis = std::min(min_vis, point.visibility); + max_vis = std::max(max_vis, point.visibility); + + min_weight = std::min(min_weight, -compute_angle_penalty(point.local_ccw_angle)); + max_weight = std::max(max_weight, -compute_angle_penalty(point.local_ccw_angle)); + } + + std::string visiblity_file_name = debug_out_path(("visibility_" + std::to_string(layer_idx) + ".svg").c_str()); + SVG visibility_svg{visiblity_file_name, bounding_box}; + std::string weights_file_name = debug_out_path(("weight_" + std::to_string(layer_idx) + ".svg").c_str()); + SVG weight_svg{weights_file_name, bounding_box}; + std::string overhangs_file_name = debug_out_path(("overhang_" + std::to_string(layer_idx) + ".svg").c_str()); + SVG overhangs_svg{overhangs_file_name, bounding_box}; + + for (const SeamCandidate &point : layers[layer_idx].points) { + Vec3i color = value_to_rgbi(min_vis, max_vis, point.visibility); + std::string visibility_fill = "rgb(" + std::to_string(color.x()) + "," + std::to_string(color.y()) + "," + std::to_string(color.z()) + ")"; + visibility_svg.draw(scaled(Vec2f(point.position.head<2>())), visibility_fill); + + Vec3i weight_color = value_to_rgbi(min_weight, max_weight, -compute_angle_penalty(point.local_ccw_angle)); + std::string weight_fill = "rgb(" + std::to_string(weight_color.x()) + "," + std::to_string(weight_color.y()) + "," + std::to_string(weight_color.z()) + ")"; + weight_svg.draw(scaled(Vec2f(point.position.head<2>())), weight_fill); + + Vec3i overhang_color = value_to_rgbi(-0.5, 0.5, std::clamp(point.overhang, -0.5f, 0.5f)); + std::string overhang_fill = "rgb(" + std::to_string(overhang_color.x()) + "," + std::to_string(overhang_color.y()) + "," + std::to_string(overhang_color.z()) + ")"; + overhangs_svg.draw(scaled(Vec2f(point.position.head<2>())), overhang_fill); + } + } +} +#endif + +// Pick best seam point based on the given comparator +void pick_seam_point(std::vector &perimeter_points, size_t start_index, const SeamComparator &comparator) +{ + size_t end_index = perimeter_points[start_index].perimeter.end_index; + + size_t seam_index = start_index; + for (size_t index = start_index; index < end_index; ++index) { + if (comparator.is_first_better(perimeter_points[index], perimeter_points[seam_index])) { seam_index = index; } + } + perimeter_points[start_index].perimeter.seam_index = seam_index; +} + +size_t pick_nearest_seam_point_index(const std::vector &perimeter_points, size_t start_index, const Vec2f &preffered_location) +{ + size_t end_index = perimeter_points[start_index].perimeter.end_index; + SeamComparator comparator{spNearest}; + + size_t seam_index = start_index; + for (size_t index = start_index; index < end_index; ++index) { + if (comparator.is_first_better(perimeter_points[index], perimeter_points[seam_index], preffered_location)) { seam_index = index; } + } + return seam_index; +} + +// picks random seam point uniformly, respecting enforcers blockers and overhang avoidance. +void pick_random_seam_point(const std::vector &perimeter_points, size_t start_index) +{ + SeamComparator comparator{spRandom}; + + // algorithm keeps a list of viable points and their lengths. If it finds a point + // that is much better than the viable_example_index (e.g. better type, no overhang; see is_first_not_much_worse) + // then it throws away stored lists and starts from start + // in the end, the list should contain points with same type (Enforced > Neutral > Blocked) and also only those which are not + // big overhang. + size_t viable_example_index = start_index; + size_t end_index = perimeter_points[start_index].perimeter.end_index; + struct Viable + { + // Candidate seam point index. + size_t index; + float edge_length; + Vec3f edge; + }; + std::vector viables; + + const Vec3f pseudornd_seed = perimeter_points[viable_example_index].position; + float rand = std::abs(sin(pseudornd_seed.dot(Vec3f(12.9898f, 78.233f, 133.3333f))) * 43758.5453f); + rand = rand - (int) rand; + + for (size_t index = start_index; index < end_index; ++index) { + if (comparator.are_similar(perimeter_points[index], perimeter_points[viable_example_index])) { + // index ok, push info into viables + Vec3f edge_to_next{perimeter_points[index == end_index - 1 ? start_index : index + 1].position - perimeter_points[index].position}; + float dist_to_next = edge_to_next.norm(); + viables.push_back({index, dist_to_next, edge_to_next}); + } else if (comparator.is_first_not_much_worse(perimeter_points[viable_example_index], perimeter_points[index])) { + // index is worse then viable_example_index, skip this point + } else { + // index is better than viable example index, update example, clear gathered info, start again + // clear up all gathered info, start from scratch, update example index + viable_example_index = index; + viables.clear(); + + Vec3f edge_to_next = (perimeter_points[index == end_index - 1 ? start_index : index + 1].position - perimeter_points[index].position); + float dist_to_next = edge_to_next.norm(); + viables.push_back({index, dist_to_next, edge_to_next}); + } + } + + // now pick random point from the stored options + float len_sum = std::accumulate(viables.begin(), viables.end(), 0.0f, [](const float acc, const Viable &v) { return acc + v.edge_length; }); + float picked_len = len_sum * rand; + + size_t point_idx = 0; + while (picked_len - viables[point_idx].edge_length > 0) { + picked_len = picked_len - viables[point_idx].edge_length; + point_idx++; + } + + Perimeter &perimeter = perimeter_points[start_index].perimeter; + perimeter.seam_index = viables[point_idx].index; + perimeter.final_seam_position = perimeter_points[perimeter.seam_index].position + viables[point_idx].edge.normalized() * picked_len; + perimeter.finalized = true; +} + +class PerimeterDistancer +{ + std::vector lines; + AABBTreeIndirect::Tree<2, double> tree; + +public: + PerimeterDistancer(const Layer *layer) + { + ExPolygons layer_outline = layer->lslices; + for (const ExPolygon &island : layer_outline) { + assert(island.contour.is_counter_clockwise()); + for (const auto &line : island.contour.lines()) { lines.emplace_back(unscale(line.a), unscale(line.b)); } + for (const Polygon &hole : island.holes) { + assert(hole.is_clockwise()); + for (const auto &line : hole.lines()) { lines.emplace_back(unscale(line.a), unscale(line.b)); } + } + } + tree = AABBTreeLines::build_aabb_tree_over_indexed_lines(lines); + } + + float distance_from_perimeter(const Vec2f &point) const + { + Vec2d p = point.cast(); + size_t hit_idx_out{}; + Vec2d hit_point_out = Vec2d::Zero(); + auto distance = AABBTreeLines::squared_distance_to_indexed_lines(lines, tree, p, hit_idx_out, hit_point_out); + if (distance < 0) { return std::numeric_limits::max(); } + + distance = sqrt(distance); + const Linef &line = lines[hit_idx_out]; + Vec2d v1 = line.b - line.a; + Vec2d v2 = p - line.a; + if ((v1.x() * v2.y()) - (v1.y() * v2.x()) > 0.0) { distance *= -1; } + return distance; + } +}; + +} // namespace SeamPlacerImpl + +// Parallel process and extract each perimeter polygon of the given print object. +// Gather SeamCandidates of each layer into vector and build KDtree over them +// Store results in the SeamPlacer variables m_seam_per_object +void SeamPlacer::gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info, const SeamPosition configured_seam_preference) +{ + using namespace SeamPlacerImpl; + PrintObjectSeamData &seam_data = m_seam_per_object.emplace(po, PrintObjectSeamData{}).first->second; + seam_data.layers.resize(po->layer_count()); + + tbb::parallel_for(tbb::blocked_range(0, po->layers().size()), [po, configured_seam_preference, &global_model_info, &seam_data](tbb::blocked_range r) { + for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { + PrintObjectSeamData::LayerSeams &layer_seams = seam_data.layers[layer_idx]; + const Layer * layer = po->get_layer(layer_idx); + auto unscaled_z = layer->slice_z; + std::vector regions; + // NOTE corresponding region ptr may be null, if the layer has zero perimeters + Polygons polygons = extract_perimeter_polygons(layer, configured_seam_preference, regions); + for (size_t poly_index = 0; poly_index < polygons.size(); ++poly_index) { + process_perimeter_polygon(polygons[poly_index], unscaled_z, regions[poly_index], global_model_info, layer_seams); + } + auto functor = SeamCandidateCoordinateFunctor{layer_seams.points}; + seam_data.layers[layer_idx].points_tree = std::make_unique(functor, layer_seams.points.size()); + } + }); +} + +void SeamPlacer::calculate_candidates_visibility(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info) +{ + using namespace SeamPlacerImpl; + + std::vector &layers = m_seam_per_object[po].layers; + tbb::parallel_for(tbb::blocked_range(0, layers.size()), [&layers, &global_model_info](tbb::blocked_range r) { + for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { + for (auto &perimeter_point : layers[layer_idx].points) { perimeter_point.visibility = global_model_info.calculate_point_visibility(perimeter_point.position); } + } + }); +} + +void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po) +{ + using namespace SeamPlacerImpl; + + std::vector &layers = m_seam_per_object[po].layers; + tbb::parallel_for(tbb::blocked_range(0, layers.size()), [po, &layers](tbb::blocked_range r) { + std::unique_ptr prev_layer_distancer; + if (r.begin() > 0) { // previous layer exists + prev_layer_distancer = std::make_unique(po->layers()[r.begin() - 1]); + } + + for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { + size_t regions_with_perimeter = 0; + for (const LayerRegion *region : po->layers()[layer_idx]->regions()) { + if (region->perimeters.entities.size() > 0) { regions_with_perimeter++; } + }; + bool should_compute_layer_embedding = regions_with_perimeter > 1; + std::unique_ptr current_layer_distancer = std::make_unique(po->layers()[layer_idx]); + + for (SeamCandidate &perimeter_point : layers[layer_idx].points) { + Vec2f point = Vec2f{perimeter_point.position.head<2>()}; + if (prev_layer_distancer.get() != nullptr) { + perimeter_point.overhang = prev_layer_distancer->distance_from_perimeter(point) + 0.6f * perimeter_point.perimeter.flow_width - + tan(SeamPlacer::overhang_angle_threshold) * po->layers()[layer_idx]->height; + perimeter_point.overhang = perimeter_point.overhang < 0.0f ? 0.0f : perimeter_point.overhang; + } + + if (should_compute_layer_embedding) { // search for embedded perimeter points (points hidden inside the print ,e.g. multimaterial join, best position for seam) + perimeter_point.embedded_distance = current_layer_distancer->distance_from_perimeter(point) + 0.6f * perimeter_point.perimeter.flow_width; + } + } + + prev_layer_distancer.swap(current_layer_distancer); + } + }); +} + +// Estimates, if there is good seam point in the layer_idx which is close to last_point_pos +// uses comparator.is_first_not_much_worse method to compare current seam with the closest point +// (if current seam is too far away ) +// If the current chosen stream is close enough, it is stored in seam_string. returns true and updates last_point_pos +// If the closest point is good enough to replace current chosen seam, it is stored in potential_string_seams, returns true and updates last_point_pos +// Otherwise does nothing, returns false +// Used by align_seam_points(). +std::optional> SeamPlacer::find_next_seam_in_layer(const std::vector &layers, + const Vec3f & projected_position, + const size_t layer_idx, + const float max_distance, + const SeamPlacerImpl::SeamComparator & comparator) const +{ + using namespace SeamPlacerImpl; + std::vector nearby_points_indices = find_nearby_points(*layers[layer_idx].points_tree, projected_position, max_distance); + + if (nearby_points_indices.empty()) { return {}; } + + size_t best_nearby_point_index = nearby_points_indices[0]; + size_t nearest_point_index = nearby_points_indices[0]; + + // Now find best nearby point, nearest point, and corresponding indices + for (const size_t &nearby_point_index : nearby_points_indices) { + const SeamCandidate &point = layers[layer_idx].points[nearby_point_index]; + if (point.perimeter.finalized) { + continue; // skip over finalized perimeters, try to find some that is not finalized + } + if (comparator.is_first_better(point, layers[layer_idx].points[best_nearby_point_index], projected_position.head<2>()) || + layers[layer_idx].points[best_nearby_point_index].perimeter.finalized) { + best_nearby_point_index = nearby_point_index; + } + if ((point.position - projected_position).squaredNorm() < (layers[layer_idx].points[nearest_point_index].position - projected_position).squaredNorm() || + layers[layer_idx].points[nearest_point_index].perimeter.finalized) { + nearest_point_index = nearby_point_index; + } + } + + const SeamCandidate &best_nearby_point = layers[layer_idx].points[best_nearby_point_index]; + const SeamCandidate &nearest_point = layers[layer_idx].points[nearest_point_index]; + + if (nearest_point.perimeter.finalized) { + // all points are from already finalized perimeter, skip + return {}; + } + + // from the nearest_point, deduce index of seam in the next layer + const SeamCandidate &next_layer_seam = layers[layer_idx].points[nearest_point.perimeter.seam_index]; + + // First try to pick central enforcer if any present + if (next_layer_seam.central_enforcer && (next_layer_seam.position - projected_position).squaredNorm() < sqr(3 * max_distance)) { + return {std::pair{layer_idx, nearest_point.perimeter.seam_index}}; + } + + // First try to align the nearest, then try the best nearby + if (comparator.is_first_not_much_worse(nearest_point, next_layer_seam)) { return {std::pair{layer_idx, nearest_point_index}}; } + // If nearest point is not good enough, try it with the best nearby point. + if (comparator.is_first_not_much_worse(best_nearby_point, next_layer_seam)) { return {std::pair{layer_idx, best_nearby_point_index}}; } + + return {}; +} + +std::vector> SeamPlacer::find_seam_string(const PrintObject * po, + std::pair start_seam, + const SeamPlacerImpl::SeamComparator &comparator) const +{ + const std::vector &layers = m_seam_per_object.find(po)->second.layers; + int layer_idx = start_seam.first; + + // initialize searching for seam string - cluster of nearby seams on previous and next layers + int next_layer = layer_idx + 1; + int step = 1; + std::pair prev_point_index = start_seam; + std::vector> seam_string{start_seam}; + + auto reverse_lookup_direction = [&]() { + step = -1; + prev_point_index = start_seam; + next_layer = layer_idx - 1; }; - // Find all seam candidate edges and their lengths. - float valid_length = 0.f; - if (has_enforcers) - valid_length = get_valid_length(enforcers_idxs, edges, true); + while (next_layer >= 0) { + if (next_layer >= int(layers.size())) { + reverse_lookup_direction(); + if (next_layer < 0) { break; } + } + float max_distance = SeamPlacer::seam_align_tolerable_dist_factor * layers[start_seam.first].points[start_seam.second].perimeter.flow_width; + Vec3f prev_position = layers[prev_point_index.first].points[prev_point_index.second].position; + Vec3f projected_position = prev_position; + projected_position.z() = float(po->get_layer(next_layer)->slice_z); - if (! has_enforcers || valid_length == 0.f) { - // Second condition covers case with isolated enf points. Given how the painted - // triangles are projected, this should not happen. Stay on the safe side though. - if (has_blockers) - valid_length = get_valid_length(blockers_idxs, edges, false); - if (valid_length == 0.f) // No blockers or everything blocked - use the whole polygon. - valid_length = lengths.back(); - } - assert(valid_length != 0.f); - // Now generate a random length and find the respective edge. - float rand_len = valid_length * (rand()/float(RAND_MAX)); - size_t pt_idx = 0; // Index of the edge where to put the seam. - if (valid_length == lengths.back()) { - // Whole polygon is used for placing the seam. - auto it = std::lower_bound(lengths.begin(), lengths.end(), rand_len); - pt_idx = it == lengths.begin() ? 0 : (it-lengths.begin()-1); // this takes care of a corner case where rand() returns 0 - } else { - float running = 0.f; - for (size_t i=0; i 0.f ? edges[i] : 0.f; - if (running >= rand_len) { - pt_idx = i; + std::optional> maybe_next_seam = find_next_seam_in_layer(layers, projected_position, next_layer, max_distance, comparator); + + if (maybe_next_seam.has_value()) { + // For old macOS (pre 10.14), std::optional does not have .value() method, so the code is using operator*() instead. + seam_string.push_back(maybe_next_seam.operator*()); + prev_point_index = seam_string.back(); + // String added, prev_point_index updated + } else { + if (step == 1) { + reverse_lookup_direction(); + if (next_layer < 0) { break; } + } else { break; } } + next_layer += step; } - - if (! has_enforcers && ! has_blockers) { - // The polygon may be too coarse, calculate the point exactly. - assert(valid_length == lengths.back()); - bool last_seg = pt_idx == polygon.points.size()-1; - size_t next_idx = last_seg ? 0 : pt_idx+1; - const Point& prev = polygon.points[pt_idx]; - const Point& next = polygon.points[next_idx]; - assert(next_idx == 0 || pt_idx+1 == next_idx); - coordf_t diff_x = next.x() - prev.x(); - coordf_t diff_y = next.y() - prev.y(); - coordf_t dist = lengths[last_seg ? pt_idx+1 : next_idx] - lengths[pt_idx]; - return Point(prev.x() + (rand_len - lengths[pt_idx]) * (diff_x/dist), - prev.y() + (rand_len - lengths[pt_idx]) * (diff_y/dist)); - - } else { - // The polygon should be dense enough. - return polygon.points[pt_idx]; - } + return seam_string; } - - - - - - - -void SeamPlacer::get_enforcers_and_blockers(size_t layer_id, - const Polygon& polygon, - size_t po_idx, - std::vector& enforcers_idxs, - std::vector& blockers_idxs) const +// clusters already chosen seam points into strings across multiple layers, and then +// aligns the strings via polynomial fit +// Does not change the positions of the SeamCandidates themselves, instead stores +// the new aligned position into the shared Perimeter structure of each perimeter +// Note that this position does not necesarilly lay on the perimeter. +void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::SeamComparator &comparator) { - enforcers_idxs.clear(); - blockers_idxs.clear(); + using namespace SeamPlacerImpl; - auto is_inside = [](const Point& pt, - const CustomTrianglesPerLayer& custom_data) -> bool { - assert(! custom_data.polys.empty()); - // Now ask the AABB tree which polygons we should check and check them. - std::vector candidates; - AABBTreeIndirect::get_candidate_idxs(custom_data.tree, pt, candidates); - if (! candidates.empty()) - for (size_t idx : candidates) - if (custom_data.polys[idx].contains(pt)) - return true; - return false; - }; - - if (! m_enforcers[po_idx].empty()) { - const CustomTrianglesPerLayer& enforcers = m_enforcers[po_idx][layer_id]; - if (! enforcers.polys.empty()) { - for (size_t i=0; i find_enforcer_centers(const Polygon& polygon, - const std::vector& lengths, - const std::vector& enforcers_idxs) -{ - std::vector out; - assert(polygon.points.size()+1 == lengths.size()); - assert(std::is_sorted(enforcers_idxs.begin(), enforcers_idxs.end())); - if (polygon.size() < 2 || enforcers_idxs.empty()) - return out; - - auto get_center_idx = [&lengths](size_t start_idx, size_t end_idx) -> size_t { - assert(end_idx >= start_idx); - if (start_idx == end_idx) - return start_idx; - float t_c = lengths[start_idx] + 0.5f * (lengths[end_idx] - lengths[start_idx]); - auto it = std::lower_bound(lengths.begin() + start_idx, lengths.begin() + end_idx, t_c); - int ret = it - lengths.begin(); - return ret; - }; - - int last_enforcer_start_idx = enforcers_idxs.front(); - bool first_pt_in_list = enforcers_idxs.front() != 0; - bool last_pt_in_list = enforcers_idxs.back() == polygon.points.size() - 1; - bool wrap_around = last_pt_in_list && first_pt_in_list; - - for (size_t i=0; i t_e) ? t_s + half_dist : t_e - half_dist; - - auto it = std::lower_bound(lengths.begin(), lengths.end(), t_c); - out[0] = it - lengths.begin(); - if (out[0] == lengths.size() - 1) - --out[0]; - assert(out[0] < lengths.size() - 1); - } - return out; -} - - - -void SeamPlacer::apply_custom_seam(const Polygon& polygon, size_t po_idx, - std::vector& penalties, - const std::vector& lengths, - int layer_id, SeamPosition seam_position) const -{ - if (! is_custom_seam_on_layer(layer_id, po_idx)) + // Prepares Debug files for writing. +#ifdef DEBUG_FILES + Slic3r::CNumericLocalesSetter locales_setter; + auto clusters_f = debug_out_path("seam_clusters.obj"); + FILE * clusters = boost::nowide::fopen(clusters_f.c_str(), "w"); + if (clusters == nullptr) { + BOOST_LOG_TRIVIAL(error) << "stl_write_obj: Couldn't open " << clusters_f << " for writing"; return; - - std::vector enforcers_idxs; - std::vector blockers_idxs; - this->get_enforcers_and_blockers(layer_id, polygon, po_idx, enforcers_idxs, blockers_idxs); - - for (size_t i : enforcers_idxs) { - assert(i < penalties.size()); - penalties[i] -= float(ENFORCER_BLOCKER_PENALTY); } - for (size_t i : blockers_idxs) { - assert(i < penalties.size()); - penalties[i] += float(ENFORCER_BLOCKER_PENALTY); - } - if (seam_position == spAligned) { - std::vector enf_centers = find_enforcer_centers(polygon, lengths, enforcers_idxs); - for (size_t idx : enf_centers) { - assert(idx < penalties.size()); - penalties[idx] += ENFORCER_CENTER_PENALTY; - } - } - -#if 0 - std::ostringstream os; - os << std::setw(3) << std::setfill('0') << layer_id; - int a = scale_(30.); - SVG svg("custom_seam" + os.str() + ".svg", BoundingBox(Point(-a, -a), Point(a, a))); - if (! m_enforcers[po_idx].empty()) - svg.draw(m_enforcers[po_idx][layer_id].polys, "blue"); - if (! m_blockers[po_idx].empty()) - svg.draw(m_blockers[po_idx][layer_id].polys, "red"); - - if (! blockers_idxs.empty()) { - ; - } - - - size_t min_idx = std::min_element(penalties.begin(), penalties.end()) - penalties.begin(); - - for (size_t i=0; i SeamHistory::get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb) -{ - assert(layer_id >= m_layer_id || layer_id == 0); - if (layer_id != m_layer_id) { - // Get seam was called for different layer than last time. - if (layer_id == 0) // seq printing - m_data_this_layer.clear(); - m_data_last_layer = m_data_this_layer; - m_data_this_layer.clear(); - m_layer_id = layer_id; + // gather vector of all seams on the print_object - pair of layer_index and seam__index within that layer + const std::vector &layers = m_seam_per_object[po].layers; + std::vector> seams; + for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) { + const std::vector &layer_perimeter_points = layers[layer_idx].points; + size_t current_point_index = 0; + while (current_point_index < layer_perimeter_points.size()) { + seams.emplace_back(layer_idx, layer_perimeter_points[current_point_index].perimeter.seam_index); + current_point_index = layer_perimeter_points[current_point_index].perimeter.end_index; + } } - std::optional out; + // sort them before alignment. Alignment is sensitive to initializaion, this gives it better chance to choose something nice + std::stable_sort(seams.begin(), seams.end(), [&comparator, &layers](const std::pair &left, const std::pair &right) { + return comparator.is_first_better(layers[left.first].points[left.second], layers[right.first].points[right.second]); + }); - auto seams_it = m_data_last_layer.find(po); - if (seams_it == m_data_last_layer.end()) - return out; + // align the seam points - start with the best, and check if they are aligned, if yes, skip, else start alignment + // Keeping the vectors outside, so with a bit of luck they will not get reallocated after couple of for loop iterations. + std::vector> seam_string; + std::vector> alternative_seam_string; + std::vector observations; + std::vector observation_points; + std::vector weights; - const std::vector& seam_data_po = seams_it->second; - - // Find a bounding-box on the last layer that is close to one we see now. - double min_score = std::numeric_limits::max(); - for (const SeamPoint& sp : seam_data_po) { - const BoundingBox& bb = sp.m_island_bb; - - if (! bb.overlap(island_bb)) { - // This bb does not even overlap. It is likely unrelated. + int global_index = 0; + while (global_index < int(seams.size())) { + size_t layer_idx = seams[global_index].first; + size_t seam_index = seams[global_index].second; + global_index++; + const std::vector &layer_perimeter_points = layers[layer_idx].points; + if (layer_perimeter_points[seam_index].perimeter.finalized) { + // This perimeter is already aligned, skip seam continue; - } + } else { + seam_string = this->find_seam_string(po, {layer_idx, seam_index}, comparator); + size_t step_size = 1 + seam_string.size() / 20; + for (size_t alternative_start = 0; alternative_start < seam_string.size(); alternative_start += step_size) { + size_t start_layer_idx = seam_string[alternative_start].first; + size_t seam_idx = layers[start_layer_idx].points[seam_string[alternative_start].second].perimeter.seam_index; + alternative_seam_string = this->find_seam_string(po, std::pair(start_layer_idx, seam_idx), comparator); + if (alternative_seam_string.size() > seam_string.size()) { seam_string = std::move(alternative_seam_string); } + } + if (seam_string.size() < seam_align_minimum_string_seams) { + // string NOT long enough to be worth aligning, skip + continue; + } - double score = std::pow(bb.min(0) - island_bb.min(0), 2.) - + std::pow(bb.min(1) - island_bb.min(1), 2.) - + std::pow(bb.max(0) - island_bb.max(0), 2.) - + std::pow(bb.max(1) - island_bb.max(1), 2.); + // String is long enough, all string seams and potential string seams gathered, now do the alignment + // sort by layer index + std::sort(seam_string.begin(), seam_string.end(), + [](const std::pair &left, const std::pair &right) { return left.first < right.first; }); - if (score < min_score) { - min_score = score; - out = sp.m_pos; + // repeat the alignment for the current seam, since it could be skipped due to alternative path being aligned. + global_index--; + + // gather all positions of seams and their weights + observations.resize(seam_string.size()); + observation_points.resize(seam_string.size()); + weights.resize(seam_string.size()); + + auto angle_3d = [](const Vec3f &a, const Vec3f &b) { return std::abs(acosf(a.normalized().dot(b.normalized()))); }; + + auto angle_weight = [](float angle) { return 1.0f / (0.1f + compute_angle_penalty(angle)); }; + + // gather points positions and weights + float total_length = 0.0f; + Vec3f last_point_pos = layers[seam_string[0].first].points[seam_string[0].second].position; + for (size_t index = 0; index < seam_string.size(); ++index) { + const SeamCandidate ¤t = layers[seam_string[index].first].points[seam_string[index].second]; + float layer_angle = 0.0f; + if (index > 0 && index < seam_string.size() - 1) { + layer_angle = angle_3d(current.position - layers[seam_string[index - 1].first].points[seam_string[index - 1].second].position, + layers[seam_string[index + 1].first].points[seam_string[index + 1].second].position - current.position); + } + observations[index] = current.position.head<2>(); + observation_points[index] = current.position.z(); + weights[index] = angle_weight(current.local_ccw_angle); + float sign = layer_angle > 2.0 * std::abs(current.local_ccw_angle) ? -0.8f : 1.0f; + if (current.type == EnforcedBlockedSeamPoint::Enforced) { + sign = 1.0f; + weights[index] += 3.0f; + } + total_length += sign * (last_point_pos - current.position).norm(); + last_point_pos = current.position; + } + + // Curve Fitting + size_t number_of_segments = std::max(size_t(1), size_t(std::max(0.0f, total_length) / SeamPlacer::seam_align_mm_per_segment)); + auto curve = Geometry::fit_cubic_bspline(observations, observation_points, weights, number_of_segments); + + // Do alignment - compute fitted point for each point in the string from its Z coord, and store the position into + // Perimeter structure of the point; also set flag aligned to true + for (size_t index = 0; index < seam_string.size(); ++index) { + const auto &pair = seam_string[index]; + float t = std::min(1.0f, std::pow(std::abs(layers[pair.first].points[pair.second].local_ccw_angle) / SeamPlacer::sharp_angle_snapping_threshold, 3.0f)); + if (layers[pair.first].points[pair.second].type == EnforcedBlockedSeamPoint::Enforced) { t = std::max(0.4f, t); } + + Vec3f current_pos = layers[pair.first].points[pair.second].position; + Vec2f fitted_pos = curve.get_fitted_value(current_pos.z()); + + // interpolate between current and fitted position, prefer current pos for large weights. + Vec3f final_position = t * current_pos + (1.0f - t) * to_3d(fitted_pos, current_pos.z()); + + Perimeter &perimeter = layers[pair.first].points[pair.second].perimeter; + perimeter.seam_index = pair.second; + perimeter.final_seam_position = final_position; + perimeter.finalized = true; + } + +#ifdef DEBUG_FILES + auto randf = []() { return float(rand()) / float(RAND_MAX); }; + Vec3f color{randf(), randf(), randf()}; + for (size_t i = 0; i < seam_string.size(); ++i) { + auto orig_seam = layers[seam_string[i].first].points[seam_string[i].second]; + fprintf(clusters, "v %f %f %f %f %f %f \n", orig_seam.position[0], orig_seam.position[1], orig_seam.position[2], color[0], color[1], color[2]); + } + + color = Vec3f{randf(), randf(), randf()}; + for (size_t i = 0; i < seam_string.size(); ++i) { + const Perimeter &perimeter = layers[seam_string[i].first].points[seam_string[i].second].perimeter; + fprintf(aligns, "v %f %f %f %f %f %f \n", perimeter.final_seam_position[0], perimeter.final_seam_position[1], perimeter.final_seam_position[2], color[0], + color[1], color[2]); + } +#endif } } - return out; +#ifdef DEBUG_FILES + fclose(clusters); + fclose(aligns); +#endif } - - -void SeamHistory::add_seam(const PrintObject* po, const Point& pos, const BoundingBox& island_bb) +void SeamPlacer::init(const Print &print, std::function throw_if_canceled_func) { - m_data_this_layer[po].push_back({pos, island_bb});; + using namespace SeamPlacerImpl; + m_seam_per_object.clear(); + + for (const PrintObject *po : print.objects()) { + throw_if_canceled_func(); + SeamPosition configured_seam_preference = po->config().seam_position.value; + SeamComparator comparator{configured_seam_preference}; + + { + GlobalModelInfo global_model_info{}; + gather_enforcers_blockers(global_model_info, po); + throw_if_canceled_func(); + if (configured_seam_preference == spAligned || configured_seam_preference == spNearest) { compute_global_occlusion(global_model_info, po, throw_if_canceled_func); } + throw_if_canceled_func(); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather_seam_candidates: start"; + gather_seam_candidates(po, global_model_info, configured_seam_preference); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: gather_seam_candidates: end"; + throw_if_canceled_func(); + if (configured_seam_preference == spAligned || configured_seam_preference == spNearest) { + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: calculate_candidates_visibility : start"; + calculate_candidates_visibility(po, global_model_info); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: calculate_candidates_visibility : end"; + } + } // destruction of global_model_info (large structure, no longer needed) + throw_if_canceled_func(); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: calculate_overhangs and layer embdedding : start"; + calculate_overhangs_and_layer_embedding(po); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: calculate_overhangs and layer embdedding: end"; + throw_if_canceled_func(); + if (configured_seam_preference != spNearest) { // For spNearest, the seam is picked in the place_seam method with actual nozzle position information + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: pick_seam_point : start"; + // pick seam point + std::vector &layers = m_seam_per_object[po].layers; + tbb::parallel_for(tbb::blocked_range(0, layers.size()), [&layers, configured_seam_preference, comparator](tbb::blocked_range r) { + for (size_t layer_idx = r.begin(); layer_idx < r.end(); ++layer_idx) { + std::vector &layer_perimeter_points = layers[layer_idx].points; + for (size_t current = 0; current < layer_perimeter_points.size(); current = layer_perimeter_points[current].perimeter.end_index) + if (configured_seam_preference == spRandom) + pick_random_seam_point(layer_perimeter_points, current); + else + pick_seam_point(layer_perimeter_points, current, comparator); + } + }); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: pick_seam_point : end"; + } + throw_if_canceled_func(); + if (configured_seam_preference == spAligned || configured_seam_preference == spRear) { + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: align_seam_points : start"; + align_seam_points(po, comparator); + BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: align_seam_points : end"; + } + +#ifdef DEBUG_FILES + debug_export_points(m_seam_per_object[po].layers, po->bounding_box(), comparator); +#endif + } } - - -void SeamHistory::clear() +void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos) const { - m_layer_id = 0; - m_data_last_layer.clear(); - m_data_this_layer.clear(); + using namespace SeamPlacerImpl; + const PrintObject *po = layer->object(); + // Must not be called with supprot layer. + assert(dynamic_cast(layer) == nullptr); + // Object layer IDs are incremented by the number of raft layers. + assert(layer->id() >= po->slicing_parameters().raft_layers()); + const size_t layer_index = layer->id() - po->slicing_parameters().raft_layers(); + const double unscaled_z = layer->slice_z; + + const PrintObjectSeamData::LayerSeams &layer_perimeters = m_seam_per_object.find(layer->object())->second.layers[layer_index]; + + // Find the closest perimeter in the SeamPlacer to the first point of this loop. + size_t closest_perimeter_point_index; + { + const Point &fp = loop.first_point(); + Vec2f unscaled_p = unscaled(fp); + closest_perimeter_point_index = find_closest_point(*layer_perimeters.points_tree.get(), to_3d(unscaled_p, float(unscaled_z))); + } + + Vec3f seam_position; + size_t seam_index; + if (const Perimeter &perimeter = layer_perimeters.points[closest_perimeter_point_index].perimeter; perimeter.finalized) { + seam_position = perimeter.final_seam_position; + seam_index = perimeter.seam_index; + } else { + seam_index = po->config().seam_position == spNearest ? pick_nearest_seam_point_index(layer_perimeters.points, perimeter.start_index, unscaled(last_pos)) : + perimeter.seam_index; + seam_position = layer_perimeters.points[seam_index].position; + } + + Point seam_point = Point::new_scale(seam_position.x(), seam_position.y()); + + if (const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index]; + (po->config().seam_position == spNearest || po->config().seam_position == spAligned) && loop.role() == ExtrusionRole::erPerimeter && // Hopefully internal perimeter + (seam_position - perimeter_point.position).squaredNorm() < 4.0f && // seam is on perimeter point + perimeter_point.local_ccw_angle < -EPSILON // In concave angles + ) { // In this case, we are at internal perimeter, where the external perimeter has seam in concave angle. We want to align + // the internal seam into the concave corner, and not on the perpendicular projection on the closest edge (which is what the split_at function does) + size_t index_of_prev = seam_index == perimeter_point.perimeter.start_index ? perimeter_point.perimeter.end_index - 1 : seam_index - 1; + size_t index_of_next = seam_index == perimeter_point.perimeter.end_index - 1 ? perimeter_point.perimeter.start_index : seam_index + 1; + + Vec2f dir_to_middle = ((perimeter_point.position - layer_perimeters.points[index_of_prev].position).head<2>().normalized() + + (perimeter_point.position - layer_perimeters.points[index_of_next].position).head<2>().normalized()) * + 0.5; + + ExtrusionLoop::ClosestPathPoint projected_point = loop.get_closest_path_and_point(seam_point, true); + // get closest projected point, determine depth of the seam point. + float depth = (float) unscale(Point(seam_point - projected_point.foot_pt)).norm(); + float angle_factor = cos(-perimeter_point.local_ccw_angle / 2.0f); // There are some nice geometric identities in determination of the correct depth of new seam point. + // overshoot the target depth, in concave angles it will correctly snap to the corner; TODO: find out why such big overshoot is needed. + Vec2f final_pos = perimeter_point.position.head<2>() + (1.4142 * depth / angle_factor) * dir_to_middle; + seam_point = Point::new_scale(final_pos.x(), final_pos.y()); + } + + // Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns, + // thus empty path segments will not be produced by G-code export. + if (!loop.split_at_vertex(seam_point, scaled(0.0015))) { + // The point is not in the original loop. + // Insert it. + loop.split_at(seam_point, true); + } } - -} +} // namespace Slic3r diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp index 57c3532c3b..43727f1731 100644 --- a/src/libslic3r/GCode/SeamPlacer.hpp +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -3,12 +3,16 @@ #include #include +#include +#include +#include "libslic3r/libslic3r.h" #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/BoundingBox.hpp" #include "libslic3r/AABBTreeIndirect.hpp" +#include "libslic3r/KDTreeIndirect.hpp" namespace Slic3r { @@ -16,119 +20,147 @@ class PrintObject; class ExtrusionLoop; class Print; class Layer; -namespace EdgeGrid { class Grid; } - - -class SeamHistory { -public: - SeamHistory() { clear(); } - std::optional get_last_seam(const PrintObject* po, size_t layer_id, const BoundingBox& island_bb); - void add_seam(const PrintObject* po, const Point& pos, const BoundingBox& island_bb); - void clear(); - -private: - struct SeamPoint { - Point m_pos; - BoundingBox m_island_bb; - }; - - std::map> m_data_last_layer; - std::map> m_data_this_layer; - size_t m_layer_id; -}; - - - -class SeamPlacer { -public: - void init(const Print& print); - - // When perimeters are printed, first call this function with the respective - // external perimeter. SeamPlacer will find a location for its seam and remember it. - // Subsequent calls to get_seam will return this position. - - - void plan_perimeters(const std::vector perimeters, - const Layer& layer, SeamPosition seam_position, - Point last_pos, coordf_t nozzle_dmr, const PrintObject* po, - const EdgeGrid::Grid* lower_layer_edge_grid); - - void place_seam(ExtrusionLoop& loop, const Point& last_pos, bool external_first, double nozzle_diameter, - const EdgeGrid::Grid* lower_layer_edge_grid); - - - using TreeType = AABBTreeIndirect::Tree<2, coord_t>; - using AlignedBoxType = Eigen::AlignedBox; - -private: - - // When given an external perimeter (!), returns the seam. - Point calculate_seam(const Layer& layer, const SeamPosition seam_position, - const ExtrusionLoop& loop, coordf_t nozzle_dmr, const PrintObject* po, - const EdgeGrid::Grid* lower_layer_edge_grid, Point last_pos); - - struct CustomTrianglesPerLayer { - Polygons polys; - TreeType tree; - }; - - // Just a cache to save some lookups. - const Layer* m_last_layer_po = nullptr; - coordf_t m_last_print_z = -1.; - const PrintObject* m_last_po = nullptr; - - struct SeamPoint { - Point pt; - bool precalculated = false; - bool external = false; - const Layer* layer = nullptr; - SeamPosition seam_position; - const PrintObject* po = nullptr; - }; - std::vector m_plan; - size_t m_plan_idx; - - std::vector> m_enforcers; - std::vector> m_blockers; - std::vector m_po_list; - - //std::map m_last_seam_position; - SeamHistory m_seam_history; - - // Get indices of points inside enforcers and blockers. - void get_enforcers_and_blockers(size_t layer_id, - const Polygon& polygon, - size_t po_id, - std::vector& enforcers_idxs, - std::vector& blockers_idxs) const; - - // Apply penalties to points inside enforcers/blockers. - void apply_custom_seam(const Polygon& polygon, size_t po_id, - std::vector& penalties, - const std::vector& lengths, - int layer_id, SeamPosition seam_position) const; - - // Return random point of a polygon. The distribution will be uniform - // along the contour and account for enforcers and blockers. - Point get_random_seam(size_t layer_idx, const Polygon& polygon, size_t po_id, - bool* saw_custom = nullptr) const; - - // Is there any enforcer/blocker on this layer? - bool is_custom_seam_on_layer(size_t layer_id, size_t po_idx) const { - return is_custom_enforcer_on_layer(layer_id, po_idx) - || is_custom_blocker_on_layer(layer_id, po_idx); - } - - bool is_custom_enforcer_on_layer(size_t layer_id, size_t po_idx) const { - return (! m_enforcers.at(po_idx).empty() && ! m_enforcers.at(po_idx)[layer_id].polys.empty()); - } - - bool is_custom_blocker_on_layer(size_t layer_id, size_t po_idx) const { - return (! m_blockers.at(po_idx).empty() && ! m_blockers.at(po_idx)[layer_id].polys.empty()); - } -}; - +namespace EdgeGrid { +class Grid; } +namespace SeamPlacerImpl { + +// ************ FOR BACKPORT COMPATIBILITY ONLY *************** +// Angle from v1 to v2, returning double atan2(y, x) normalized to <-PI, PI>. +template inline double angle(const Eigen::MatrixBase &v1, const Eigen::MatrixBase &v2) +{ + static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "angle(): first parameter is not a 2D vector"); + static_assert(Derived2::IsVectorAtCompileTime && int(Derived2::SizeAtCompileTime) == 2, "angle(): second parameter is not a 2D vector"); + auto v1d = v1.template cast(); + auto v2d = v2.template cast(); + return atan2(cross2(v1d, v2d), v1d.dot(v2d)); +} +// *************************** + +struct GlobalModelInfo; +struct SeamComparator; + +enum class EnforcedBlockedSeamPoint { + Blocked = 0, + Neutral = 1, + Enforced = 2, +}; + +// struct representing single perimeter loop +struct Perimeter +{ + size_t start_index{}; + size_t end_index{}; // inclusive! + size_t seam_index{}; + float flow_width{}; + + // During alignment, a final position may be stored here. In that case, finalized is set to true. + // Note that final seam position is not limited to points of the perimeter loop. In theory it can be any position + // Random position also uses this flexibility to set final seam point position + bool finalized = false; + Vec3f final_seam_position = Vec3f::Zero(); +}; + +// Struct over which all processing of perimeters is done. For each perimeter point, its respective candidate is created, +// then all the needed attributes are computed and finally, for each perimeter one point is chosen as seam. +// This seam position can be then further aligned +struct SeamCandidate +{ + SeamCandidate(const Vec3f &pos, Perimeter &perimeter, float local_ccw_angle, EnforcedBlockedSeamPoint type) + : position(pos), perimeter(perimeter), visibility(0.0f), overhang(0.0f), embedded_distance(0.0f), local_ccw_angle(local_ccw_angle), type(type), central_enforcer(false) + {} + const Vec3f position; + // pointer to Perimeter loop of this point. It is shared across all points of the loop + Perimeter &perimeter; + float visibility; + float overhang; + // distance inside the merged layer regions, for detecting perimeter points which are hidden indside the print (e.g. multimaterial join) + // Negative sign means inside the print, comes from EdgeGrid structure + float embedded_distance; + float local_ccw_angle; + EnforcedBlockedSeamPoint type; + bool central_enforcer; // marks this candidate as central point of enforced segment on the perimeter - important for alignment +}; + +struct SeamCandidateCoordinateFunctor +{ + SeamCandidateCoordinateFunctor(const std::vector &seam_candidates) : seam_candidates(seam_candidates) {} + const std::vector &seam_candidates; + float operator()(size_t index, size_t dim) const { return seam_candidates[index].position[dim]; } +}; +} // namespace SeamPlacerImpl + +struct PrintObjectSeamData +{ + using SeamCandidatesTree = KDTreeIndirect<3, float, SeamPlacerImpl::SeamCandidateCoordinateFunctor>; + + struct LayerSeams + { + Slic3r::deque perimeters; + std::vector points; + std::unique_ptr points_tree; + }; + // Map of PrintObjects (PO) -> vector of layers of PO -> vector of perimeter + std::vector layers; + // Map of PrintObjects (PO) -> vector of layers of PO -> unique_ptr to KD + // tree of all points of the given layer + + void clear() { layers.clear(); } +}; + +class SeamPlacer +{ +public: + // Number of samples generated on the mesh. There are sqr_rays_per_sample_point*sqr_rays_per_sample_point rays casted from each samples + static constexpr size_t raycasting_visibility_samples_count = 30000; + // square of number of rays per sample point + static constexpr size_t sqr_rays_per_sample_point = 5; + + // snapping angle - angles larger than this value will be snapped to during seam painting + static constexpr float sharp_angle_snapping_threshold = 55.0f * float(PI) / 180.0f; + // overhang angle for seam placement that still yields good results, in degrees, measured from vertical direction + //BBS + static constexpr float overhang_angle_threshold = 45.0f * float(PI) / 180.0f; + + // determines angle importance compared to visibility ( neutral value is 1.0f. ) + static constexpr float angle_importance_aligned = 0.6f; + static constexpr float angle_importance_nearest = 1.0f; // use much higher angle importance for nearest mode, to combat the visibility info noise + + // For long polygon sides, if they are close to the custom seam drawings, they are oversampled with this step size + static constexpr float enforcer_oversampling_distance = 0.2f; + + // When searching for seam clusters for alignment: + // following value describes, how much worse score can point have and still be picked into seam cluster instead of original seam point on the same layer + static constexpr float seam_align_score_tolerance = 0.3f; + // seam_align_tolerable_dist_factor - how far to search for seam from current position, final dist is seam_align_tolerable_dist_factor * flow_width + static constexpr float seam_align_tolerable_dist_factor = 4.0f; + // minimum number of seams needed in cluster to make alignment happen + static constexpr size_t seam_align_minimum_string_seams = 6; + // millimeters covered by spline; determines number of splines for the given string + static constexpr size_t seam_align_mm_per_segment = 4.0f; + + // The following data structures hold all perimeter points for all PrintObject. + std::unordered_map m_seam_per_object; + + void init(const Print &print, std::function throw_if_canceled_func); + + void place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos) const; + +private: + void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info, const SeamPosition configured_seam_preference); + void calculate_candidates_visibility(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info); + void calculate_overhangs_and_layer_embedding(const PrintObject *po); + void align_seam_points(const PrintObject *po, const SeamPlacerImpl::SeamComparator &comparator); + std::vector> find_seam_string(const PrintObject *po, std::pair start_seam, const SeamPlacerImpl::SeamComparator &comparator) const; + std::optional> find_next_seam_in_layer(const std::vector &layers, + const Vec3f & projected_position, + const size_t layer_idx, + const float max_distance, + const SeamPlacerImpl::SeamComparator & comparator) const; +}; + +} // namespace Slic3r + #endif // libslic3r_SeamPlacer_hpp_ diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 1c4b45466a..f20b3091fa 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -474,7 +474,8 @@ void ToolOrdering::reorder_extruders(std::vector tool_order_layer0 if (m_layer_tools.empty()) return; - assert(!tool_order_layer0.empty()); + if (tool_order_layer0.empty()) + return; // Reorder the extruders of first layer { diff --git a/src/libslic3r/Geometry/Bicubic.hpp b/src/libslic3r/Geometry/Bicubic.hpp new file mode 100644 index 0000000000..98c6f8bb29 --- /dev/null +++ b/src/libslic3r/Geometry/Bicubic.hpp @@ -0,0 +1,291 @@ +#ifndef BICUBIC_HPP +#define BICUBIC_HPP + +#include +#include +#include + +#include + +namespace Slic3r { + +namespace Geometry { + +namespace BicubicInternal { +// Linear kernel, to be able to test cubic methods with hat kernels. +template +struct LinearKernel +{ + typedef T FloatType; + + static T a00() { + return T(0.); + } + static T a01() { + return T(0.); + } + static T a02() { + return T(0.); + } + static T a03() { + return T(0.); + } + static T a10() { + return T(1.); + } + static T a11() { + return T(-1.); + } + static T a12() { + return T(0.); + } + static T a13() { + return T(0.); + } + static T a20() { + return T(0.); + } + static T a21() { + return T(1.); + } + static T a22() { + return T(0.); + } + static T a23() { + return T(0.); + } + static T a30() { + return T(0.); + } + static T a31() { + return T(0.); + } + static T a32() { + return T(0.); + } + static T a33() { + return T(0.); + } +}; + +// Interpolation kernel aka Catmul-Rom aka Keyes kernel. +template +struct CubicCatmulRomKernel +{ + typedef T FloatType; + + static T a00() { + return 0; + } + static T a01() { + return T( -0.5); + } + static T a02() { + return T( 1.); + } + static T a03() { + return T( -0.5); + } + static T a10() { + return T( 1.); + } + static T a11() { + return 0; + } + static T a12() { + return T( -5. / 2.); + } + static T a13() { + return T( 3. / 2.); + } + static T a20() { + return 0; + } + static T a21() { + return T( 0.5); + } + static T a22() { + return T( 2.); + } + static T a23() { + return T( -3. / 2.); + } + static T a30() { + return 0; + } + static T a31() { + return 0; + } + static T a32() { + return T( -0.5); + } + static T a33() { + return T( 0.5); + } +}; + +// B-spline kernel +template +struct CubicBSplineKernel +{ + typedef T FloatType; + + static T a00() { + return T( 1. / 6.); + } + static T a01() { + return T( -3. / 6.); + } + static T a02() { + return T( 3. / 6.); + } + static T a03() { + return T( -1. / 6.); + } + static T a10() { + return T( 4. / 6.); + } + static T a11() { + return 0; + } + static T a12() { + return T( -6. / 6.); + } + static T a13() { + return T( 3. / 6.); + } + static T a20() { + return T( 1. / 6.); + } + static T a21() { + return T( 3. / 6.); + } + static T a22() { + return T( 3. / 6.); + } + static T a23() { + return T( -3. / 6.); + } + static T a30() { + return 0; + } + static T a31() { + return 0; + } + static T a32() { + return 0; + } + static T a33() { + return T( 1. / 6.); + } +}; + +template +inline T clamp(T a, T lower, T upper) + { + return (a < lower) ? lower : + (a > upper) ? upper : a; +} +} + +template +struct CubicKernelWrapper +{ + typedef typename Kernel::FloatType FloatType; + + static constexpr size_t kernel_span = 4; + + static FloatType kernel(FloatType x) + { + x = fabs(x); + if (x >= (FloatType) 2.) + return 0.0f; + if (x <= (FloatType) 1.) { + FloatType x2 = x * x; + FloatType x3 = x2 * x; + return Kernel::a10() + Kernel::a11() * x + Kernel::a12() * x2 + Kernel::a13() * x3; + } + assert(x > (FloatType )1. && x < (FloatType )2.); + x -= (FloatType) 1.; + FloatType x2 = x * x; + FloatType x3 = x2 * x; + return Kernel::a00() + Kernel::a01() * x + Kernel::a02() * x2 + Kernel::a03() * x3; + } + + static FloatType interpolate(FloatType f0, FloatType f1, FloatType f2, FloatType f3, FloatType x) + { + const FloatType x2 = x * x; + const FloatType x3 = x * x * x; + return f0 * (Kernel::a00() + Kernel::a01() * x + Kernel::a02() * x2 + Kernel::a03() * x3) + + f1 * (Kernel::a10() + Kernel::a11() * x + Kernel::a12() * x2 + Kernel::a13() * x3) + + f2 * (Kernel::a20() + Kernel::a21() * x + Kernel::a22() * x2 + Kernel::a23() * x3) + + f3 * (Kernel::a30() + Kernel::a31() * x + Kernel::a32() * x2 + Kernel::a33() * x3); + } +}; + +// Linear splines +template +using LinearKernel = CubicKernelWrapper>; + +// Catmul-Rom splines +template +using CubicCatmulRomKernel = CubicKernelWrapper>; + +// Cubic B-splines +template +using CubicBSplineKernel = CubicKernelWrapper>; + +template +static typename KernelWrapper::FloatType cubic_interpolate(const Eigen::ArrayBase &F, + const typename KernelWrapper::FloatType pt) { + typedef typename KernelWrapper::FloatType T; + const int w = int(F.size()); + const int ix = (int) floor(pt); + const T s = pt - T( ix); + + if (ix > 1 && ix + 2 < w) { + // Inside the fully interpolated region. + return KernelWrapper::interpolate(F[ix - 1], F[ix], F[ix + 1], F[ix + 2], s); + } + // Transition region. Extend with a constant function. + auto f = [&F, w](T x) { + return F[BicubicInternal::clamp(x, 0, w - 1)]; + }; + return KernelWrapper::interpolate(f(ix - 1), f(ix), f(ix + 1), f(ix + 2), s); +} + +template +static float bicubic_interpolate(const Eigen::MatrixBase &F, + const Eigen::Matrix &pt) { + typedef typename Kernel::FloatType T; + const int w = F.cols(); + const int h = F.rows(); + const int ix = (int) floor(pt[0]); + const int iy = (int) floor(pt[1]); + const T s = pt[0] - T( ix); + const T t = pt[1] - T( iy); + + if (ix > 1 && ix + 2 < w && iy > 1 && iy + 2 < h) { + // Inside the fully interpolated region. + return Kernel::interpolate( + Kernel::interpolate(F(ix - 1, iy - 1), F(ix, iy - 1), F(ix + 1, iy - 1), F(ix + 2, iy - 1), s), + Kernel::interpolate(F(ix - 1, iy), F(ix, iy), F(ix + 1, iy), F(ix + 2, iy), s), + Kernel::interpolate(F(ix - 1, iy + 1), F(ix, iy + 1), F(ix + 1, iy + 1), F(ix + 2, iy + 1), s), + Kernel::interpolate(F(ix - 1, iy + 2), F(ix, iy + 2), F(ix + 1, iy + 2), F(ix + 2, iy + 2), s), t); + } + // Transition region. Extend with a constant function. + auto f = [&F, w, h](int x, int y) { + return F(BicubicInternal::clamp(x, 0, w - 1), BicubicInternal::clamp(y, 0, h - 1)); + }; + return Kernel::interpolate( + Kernel::interpolate(f(ix - 1, iy - 1), f(ix, iy - 1), f(ix + 1, iy - 1), f(ix + 2, iy - 1), s), + Kernel::interpolate(f(ix - 1, iy), f(ix, iy), f(ix + 1, iy), f(ix + 2, iy), s), + Kernel::interpolate(f(ix - 1, iy + 1), f(ix, iy + 1), f(ix + 1, iy + 1), f(ix + 2, iy + 1), s), + Kernel::interpolate(f(ix - 1, iy + 2), f(ix, iy + 2), f(ix + 1, iy + 2), f(ix + 2, iy + 2), s), t); +} + +} //namespace Geometry + +} // namespace Slic3r + +#endif /* BICUBIC_HPP */ diff --git a/src/libslic3r/Geometry/Curves.hpp b/src/libslic3r/Geometry/Curves.hpp new file mode 100644 index 0000000000..f4a5a0067e --- /dev/null +++ b/src/libslic3r/Geometry/Curves.hpp @@ -0,0 +1,218 @@ +#ifndef SRC_LIBSLIC3R_GEOMETRY_CURVES_HPP_ +#define SRC_LIBSLIC3R_GEOMETRY_CURVES_HPP_ + +#include "libslic3r/Point.hpp" +#include "Bicubic.hpp" + +#include + +//#define LSQR_DEBUG + +namespace Slic3r { +namespace Geometry { + +template +struct PolynomialCurve { + Eigen::MatrixXf coefficients; + + Vec get_fitted_value(const NumberType& value) const { + Vec result = Vec::Zero(); + size_t order = this->coefficients.rows() - 1; + auto x = NumberType(1.); + for (size_t index = 0; index < order + 1; ++index, x *= value) + result += x * this->coefficients.col(index); + return result; + } +}; + +//https://towardsdatascience.com/least-square-polynomial-CURVES-using-c-eigen-package-c0673728bd01 +template +PolynomialCurve fit_polynomial(const std::vector> &observations, + const std::vector &observation_points, + const std::vector &weights, size_t order) { + // check to make sure inputs are correct + size_t cols = order + 1; + assert(observation_points.size() >= cols); + assert(observation_points.size() == weights.size()); + assert(observations.size() == weights.size()); + + Eigen::MatrixXf data_points(Dimension, observations.size()); + Eigen::MatrixXf T(observations.size(), cols); + for (size_t i = 0; i < weights.size(); ++i) { + auto squared_weight = sqrt(weights[i]); + data_points.col(i) = observations[i] * squared_weight; + // Populate the matrix + auto x = squared_weight; + auto c = observation_points[i]; + for (size_t j = 0; j < cols; ++j, x *= c) + T(i, j) = x; + } + + const auto QR = T.householderQr(); + Eigen::MatrixXf coefficients(Dimension, cols); + // Solve for linear least square fit + for (size_t dim = 0; dim < Dimension; ++dim) { + coefficients.row(dim) = QR.solve(data_points.row(dim).transpose()); + } + + return {std::move(coefficients)}; +} + +template +struct PiecewiseFittedCurve { + using Kernel = KernelType; + + Eigen::MatrixXf coefficients; + NumberType start; + NumberType segment_size; + size_t endpoints_level_of_freedom; + + Vec get_fitted_value(const NumberType &observation_point) const { + Vec result = Vec::Zero(); + + //find corresponding segment index; expects kernels to be centered + int middle_right_segment_index = floor((observation_point - start) / segment_size); + //find index of first segment that is affected by the point i; this can be deduced from kernel_span + int start_segment_idx = middle_right_segment_index - Kernel::kernel_span / 2 + 1; + for (int segment_index = start_segment_idx; segment_index < int(start_segment_idx + Kernel::kernel_span); + segment_index++) { + NumberType segment_start = start + segment_index * segment_size; + NumberType normalized_segment_distance = (segment_start - observation_point) / segment_size; + + int parameter_index = segment_index + endpoints_level_of_freedom; + parameter_index = std::clamp(parameter_index, 0, int(coefficients.cols()) - 1); + result += Kernel::kernel(normalized_segment_distance) * coefficients.col(parameter_index); + } + return result; + } +}; + +// observations: data to be fitted by the curve +// observation points: growing sequence of points where the observations were made. +// In other words, for function f(x) = y, observations are y0...yn, and observation points are x0...xn +// weights: how important the observation is +// segments_count: number of segments inside the valid length of the curve +// endpoints_level_of_freedom: number of additional parameters at each end; reasonable values depend on the kernel span +template +PiecewiseFittedCurve fit_curve( + const std::vector> &observations, + const std::vector &observation_points, + const std::vector &weights, + size_t segments_count, + size_t endpoints_level_of_freedom) { + + // check to make sure inputs are correct + assert(segments_count > 0); + assert(observations.size() > 0); + assert(observation_points.size() == observations.size()); + assert(observation_points.size() == weights.size()); + assert(segments_count <= observations.size()); + + //prepare sqrt of weights, which will then be applied to both matrix T and observed data: https://en.wikipedia.org/wiki/Weighted_least_squares + std::vector sqrt_weights(weights.size()); + for (size_t index = 0; index < weights.size(); ++index) { + assert(weights[index] > 0); + sqrt_weights[index] = sqrt(weights[index]); + } + + // prepare result and compute metadata + PiecewiseFittedCurve result { }; + + NumberType valid_length = observation_points.back() - observation_points.front(); + NumberType segment_size = valid_length / NumberType(segments_count); + result.start = observation_points.front(); + result.segment_size = segment_size; + result.endpoints_level_of_freedom = endpoints_level_of_freedom; + + // prepare observed data + // Eigen defaults to column major memory layout. + Eigen::MatrixXf data_points(Dimension, observations.size()); + for (size_t index = 0; index < observations.size(); ++index) { + data_points.col(index) = observations[index] * sqrt_weights[index]; + } + // parameters count is always increased by one to make the parametric space of the curve symmetric. + // without this fix, the end of the curve is less flexible than the beginning + size_t parameters_count = segments_count + 1 + 2 * endpoints_level_of_freedom; + //Create weight matrix T for each point and each segment; + Eigen::MatrixXf T(observation_points.size(), parameters_count); + T.setZero(); + //Fill the weight matrix + for (size_t i = 0; i < observation_points.size(); ++i) { + NumberType observation_point = observation_points[i]; + //find corresponding segment index; expects kernels to be centered + int middle_right_segment_index = floor((observation_point - result.start) / result.segment_size); + //find index of first segment that is affected by the point i; this can be deduced from kernel_span + int start_segment_idx = middle_right_segment_index - int(Kernel::kernel_span / 2) + 1; + for (int segment_index = start_segment_idx; segment_index < int(start_segment_idx + Kernel::kernel_span); + segment_index++) { + NumberType segment_start = result.start + segment_index * result.segment_size; + NumberType normalized_segment_distance = (segment_start - observation_point) / result.segment_size; + + int parameter_index = segment_index + endpoints_level_of_freedom; + parameter_index = std::clamp(parameter_index, 0, int(parameters_count) - 1); + T(i, parameter_index) += Kernel::kernel(normalized_segment_distance) * sqrt_weights[i]; + } + } + +#ifdef LSQR_DEBUG + std::cout << "weight matrix: " << std::endl; + for (int obs = 0; obs < observation_points.size(); ++obs) { + std::cout << std::endl; + for (int segment = 0; segment < parameters_count; ++segment) { + std::cout << T(obs, segment) << " "; + } + } + std::cout << std::endl; +#endif + + // Solve for linear least square fit + result.coefficients.resize(Dimension, parameters_count); + const auto QR = T.fullPivHouseholderQr(); + for (size_t dim = 0; dim < Dimension; ++dim) { + result.coefficients.row(dim) = QR.solve(data_points.row(dim).transpose()); + } + + return result; +} + + +template +PiecewiseFittedCurve> +fit_linear_spline( + const std::vector> &observations, + std::vector observation_points, + std::vector weights, + size_t segments_count, + size_t endpoints_level_of_freedom = 0) { + return fit_curve>(observations, observation_points, weights, segments_count, + endpoints_level_of_freedom); +} + +template +PiecewiseFittedCurve> +fit_cubic_bspline( + const std::vector> &observations, + std::vector observation_points, + std::vector weights, + size_t segments_count, + size_t endpoints_level_of_freedom = 0) { + return fit_curve>(observations, observation_points, weights, segments_count, + endpoints_level_of_freedom); +} + +template +PiecewiseFittedCurve> +fit_catmul_rom_spline( + const std::vector> &observations, + std::vector observation_points, + std::vector weights, + size_t segments_count, + size_t endpoints_level_of_freedom = 0) { + return fit_curve>(observations, observation_points, weights, segments_count, + endpoints_level_of_freedom); +} + +} +} + +#endif /* SRC_LIBSLIC3R_GEOMETRY_CURVES_HPP_ */ diff --git a/src/libslic3r/KDTreeIndirect.hpp b/src/libslic3r/KDTreeIndirect.hpp index 12e462569e..37c10827b1 100644 --- a/src/libslic3r/KDTreeIndirect.hpp +++ b/src/libslic3r/KDTreeIndirect.hpp @@ -11,224 +11,362 @@ namespace Slic3r { +enum class VisitorReturnMask : unsigned int { + CONTINUE_LEFT = 1, + CONTINUE_RIGHT = 2, + STOP = 4, +}; + // KD tree for N-dimensional closest point search. template class KDTreeIndirect { public: - static constexpr size_t NumDimensions = ANumDimensions; - using CoordinateFn = ACoordinateFn; - using CoordType = ACoordType; + static constexpr size_t NumDimensions = ANumDimensions; + using CoordinateFn = ACoordinateFn; + using CoordType = ACoordType; // Following could be static constexpr size_t, but that would not link in C++11 enum : size_t { npos = size_t(-1) }; - KDTreeIndirect(CoordinateFn coordinate) : coordinate(coordinate) {} - KDTreeIndirect(CoordinateFn coordinate, std::vector indices) : coordinate(coordinate) { this->build(std::move(indices)); } - KDTreeIndirect(CoordinateFn coordinate, std::vector &&indices) : coordinate(coordinate) { this->build(std::move(indices)); } - KDTreeIndirect(CoordinateFn coordinate, size_t num_indices) : coordinate(coordinate) { this->build(num_indices); } - KDTreeIndirect(KDTreeIndirect &&rhs) : m_nodes(std::move(rhs.m_nodes)), coordinate(std::move(rhs.coordinate)) {} - KDTreeIndirect& operator=(KDTreeIndirect &&rhs) { m_nodes = std::move(rhs.m_nodes); coordinate = std::move(rhs.coordinate); return *this; } - void clear() { m_nodes.clear(); } + KDTreeIndirect(CoordinateFn coordinate) : coordinate(coordinate) {} + KDTreeIndirect(CoordinateFn coordinate, std::vector indices) : coordinate(coordinate) { this->build(indices); } + KDTreeIndirect(CoordinateFn coordinate, size_t num_indices) : coordinate(coordinate) { this->build(num_indices); } + KDTreeIndirect(KDTreeIndirect &&rhs) : m_nodes(std::move(rhs.m_nodes)), coordinate(std::move(rhs.coordinate)) {} + KDTreeIndirect& operator=(KDTreeIndirect &&rhs) { m_nodes = std::move(rhs.m_nodes); coordinate = std::move(rhs.coordinate); return *this; } + void clear() { m_nodes.clear(); } - void build(size_t num_indices) - { - std::vector indices; - indices.reserve(num_indices); - for (size_t i = 0; i < num_indices; ++ i) - indices.emplace_back(i); - this->build(std::move(indices)); - } + void build(size_t num_indices) + { + std::vector indices; + indices.reserve(num_indices); + for (size_t i = 0; i < num_indices; ++ i) + indices.emplace_back(i); + this->build(indices); + } - void build(std::vector &&indices) - { - if (indices.empty()) - clear(); - else { - // Allocate enough memory for a full binary tree. - m_nodes.assign(next_highest_power_of_2(indices.size() + 1), npos); - build_recursive(indices, 0, 0, 0, indices.size() - 1); - } - indices.clear(); - } + void build(std::vector &indices) + { + if (indices.empty()) + clear(); + else { + // Allocate enough memory for a full binary tree. + m_nodes.assign(next_highest_power_of_2(indices.size() + 1), npos); + build_recursive(indices, 0, 0, 0, indices.size() - 1); + } + indices.clear(); + } - enum class VisitorReturnMask : unsigned int - { - CONTINUE_LEFT = 1, - CONTINUE_RIGHT = 2, - STOP = 4, - }; - template - unsigned int descent_mask(const CoordType &point_coord, const CoordType &search_radius, size_t idx, size_t dimension) const - { - CoordType dist = point_coord - this->coordinate(idx, dimension); - return (dist * dist < search_radius + CoordType(EPSILON)) ? - // The plane intersects a hypersphere centered at point_coord of search_radius. - ((unsigned int)(VisitorReturnMask::CONTINUE_LEFT) | (unsigned int)(VisitorReturnMask::CONTINUE_RIGHT)) : - // The plane does not intersect the hypersphere. - (dist > CoordType(0)) ? (unsigned int)(VisitorReturnMask::CONTINUE_RIGHT) : (unsigned int)(VisitorReturnMask::CONTINUE_LEFT); - } + template + unsigned int descent_mask(const CoordType &point_coord, const CoordType &search_radius, size_t idx, size_t dimension) const + { + CoordType dist = point_coord - this->coordinate(idx, dimension); + return (dist * dist < search_radius + CoordType(EPSILON)) ? + // The plane intersects a hypersphere centered at point_coord of search_radius. + ((unsigned int)(VisitorReturnMask::CONTINUE_LEFT) | (unsigned int)(VisitorReturnMask::CONTINUE_RIGHT)) : + // The plane does not intersect the hypersphere. + (dist > CoordType(0)) ? (unsigned int)(VisitorReturnMask::CONTINUE_RIGHT) : (unsigned int)(VisitorReturnMask::CONTINUE_LEFT); + } - // Visitor is supposed to return a bit mask of VisitorReturnMask. - template - void visit(Visitor &visitor) const - { + // Visitor is supposed to return a bit mask of VisitorReturnMask. + template + void visit(Visitor &visitor) const + { visit_recursive(0, 0, visitor); - } + } - CoordinateFn coordinate; + CoordinateFn coordinate; private: - // Build a balanced tree by splitting the input sequence by an axis aligned plane at a dimension. - void build_recursive(std::vector &input, size_t node, const size_t dimension, const size_t left, const size_t right) - { - if (left > right) - return; + // Build a balanced tree by splitting the input sequence by an axis aligned plane at a dimension. + void build_recursive(std::vector &input, size_t node, const size_t dimension, const size_t left, const size_t right) + { + if (left > right) + return; - assert(node < m_nodes.size()); + assert(node < m_nodes.size()); - if (left == right) { - // Insert a node into the balanced tree. - m_nodes[node] = input[left]; - return; - } + if (left == right) { + // Insert a node into the balanced tree. + m_nodes[node] = input[left]; + return; + } - // Partition the input to left / right pieces of the same length to produce a balanced tree. - size_t center = (left + right) / 2; - partition_input(input, dimension, left, right, center); - // Insert a node into the tree. - m_nodes[node] = input[center]; - // Build up the left / right subtrees. - size_t next_dimension = dimension; - if (++ next_dimension == NumDimensions) - next_dimension = 0; - if (center > left) - build_recursive(input, node * 2 + 1, next_dimension, left, center - 1); - build_recursive(input, node * 2 + 2, next_dimension, center + 1, right); - } + // Partition the input to left / right pieces of the same length to produce a balanced tree. + size_t center = (left + right) / 2; + partition_input(input, dimension, left, right, center); + // Insert a node into the tree. + m_nodes[node] = input[center]; + // Build up the left / right subtrees. + size_t next_dimension = dimension; + if (++ next_dimension == NumDimensions) + next_dimension = 0; + if (center > left) + build_recursive(input, node * 2 + 1, next_dimension, left, center - 1); + build_recursive(input, node * 2 + 2, next_dimension, center + 1, right); + } - // Partition the input m_nodes at "k" and "dimension" using the QuickSelect method: - // https://en.wikipedia.org/wiki/Quickselect - // Items left of the k'th item are lower than the k'th item in the "dimension", - // items right of the k'th item are higher than the k'th item in the "dimension", - void partition_input(std::vector &input, const size_t dimension, size_t left, size_t right, const size_t k) const - { - while (left < right) { - size_t center = (left + right) / 2; - CoordType pivot; - { - // Bubble sort the input[left], input[center], input[right], so that a median of the three values - // will end up in input[center]. - CoordType left_value = this->coordinate(input[left], dimension); - CoordType center_value = this->coordinate(input[center], dimension); - CoordType right_value = this->coordinate(input[right], dimension); - if (left_value > center_value) { - std::swap(input[left], input[center]); - std::swap(left_value, center_value); - } - if (left_value > right_value) { - std::swap(input[left], input[right]); - right_value = left_value; - } - if (center_value > right_value) { - std::swap(input[center], input[right]); - center_value = right_value; - } - pivot = center_value; - } - if (right <= left + 2) - // The interval is already sorted. - break; - size_t i = left; - size_t j = right - 1; - std::swap(input[center], input[j]); - // Partition the set based on the pivot. - for (;;) { - // Skip left points that are already at correct positions. - // Search will certainly stop at position (right - 1), which stores the pivot. - while (this->coordinate(input[++ i], dimension) < pivot) ; - // Skip right points that are already at correct positions. - while (this->coordinate(input[-- j], dimension) > pivot && i < j) ; - if (i >= j) - break; - std::swap(input[i], input[j]); - } - // Restore pivot to the center of the sequence. - std::swap(input[i], input[right - 1]); - // Which side the kth element is in? - if (k < i) - right = i - 1; - else if (k == i) - // Sequence is partitioned, kth element is at its place. - break; - else - left = i + 1; - } - } + // Partition the input m_nodes at "k" and "dimension" using the QuickSelect method: + // https://en.wikipedia.org/wiki/Quickselect + // Items left of the k'th item are lower than the k'th item in the "dimension", + // items right of the k'th item are higher than the k'th item in the "dimension", + void partition_input(std::vector &input, const size_t dimension, size_t left, size_t right, const size_t k) const + { + while (left < right) { + size_t center = (left + right) / 2; + CoordType pivot; + { + // Bubble sort the input[left], input[center], input[right], so that a median of the three values + // will end up in input[center]. + CoordType left_value = this->coordinate(input[left], dimension); + CoordType center_value = this->coordinate(input[center], dimension); + CoordType right_value = this->coordinate(input[right], dimension); + if (left_value > center_value) { + std::swap(input[left], input[center]); + std::swap(left_value, center_value); + } + if (left_value > right_value) { + std::swap(input[left], input[right]); + right_value = left_value; + } + if (center_value > right_value) { + std::swap(input[center], input[right]); + center_value = right_value; + } + pivot = center_value; + } + if (right <= left + 2) + // The interval is already sorted. + break; + size_t i = left; + size_t j = right - 1; + std::swap(input[center], input[j]); + // Partition the set based on the pivot. + for (;;) { + // Skip left points that are already at correct positions. + // Search will certainly stop at position (right - 1), which stores the pivot. + while (this->coordinate(input[++ i], dimension) < pivot) ; + // Skip right points that are already at correct positions. + while (this->coordinate(input[-- j], dimension) > pivot && i < j) ; + if (i >= j) + break; + std::swap(input[i], input[j]); + } + // Restore pivot to the center of the sequence. + std::swap(input[i], input[right - 1]); + // Which side the kth element is in? + if (k < i) + right = i - 1; + else if (k == i) + // Sequence is partitioned, kth element is at its place. + break; + else + left = i + 1; + } + } - template - void visit_recursive(size_t node, size_t dimension, Visitor &visitor) const - { - assert(! m_nodes.empty()); - if (node >= m_nodes.size() || m_nodes[node] == npos) - return; + template + void visit_recursive(size_t node, size_t dimension, Visitor &visitor) const + { + assert(! m_nodes.empty()); + if (node >= m_nodes.size() || m_nodes[node] == npos) + return; - // Left / right child node index. - size_t left = node * 2 + 1; - size_t right = left + 1; - unsigned int mask = visitor(m_nodes[node], dimension); - if ((mask & (unsigned int)VisitorReturnMask::STOP) == 0) { - size_t next_dimension = (++ dimension == NumDimensions) ? 0 : dimension; - if (mask & (unsigned int)VisitorReturnMask::CONTINUE_LEFT) - visit_recursive(left, next_dimension, visitor); - if (mask & (unsigned int)VisitorReturnMask::CONTINUE_RIGHT) - visit_recursive(right, next_dimension, visitor); - } - } + // Left / right child node index. + size_t left = node * 2 + 1; + size_t right = left + 1; + unsigned int mask = visitor(m_nodes[node], dimension); + if ((mask & (unsigned int)VisitorReturnMask::STOP) == 0) { + size_t next_dimension = (++ dimension == NumDimensions) ? 0 : dimension; + if (mask & (unsigned int)VisitorReturnMask::CONTINUE_LEFT) + visit_recursive(left, next_dimension, visitor); + if (mask & (unsigned int)VisitorReturnMask::CONTINUE_RIGHT) + visit_recursive(right, next_dimension, visitor); + } + } - std::vector m_nodes; + std::vector m_nodes; }; // Find a closest point using Euclidian metrics. // Returns npos if not found. -template -size_t find_closest_point(const KDTreeIndirectType &kdtree, const PointType &point, FilterFn filter) +template +std::array find_closest_points( + const KDTreeIndirect &kdtree, + const PointType &point, + FilterFn filter) { - using CoordType = typename KDTreeIndirectType::CoordType; + using Tree = KDTreeIndirect; - struct Visitor { - const KDTreeIndirectType &kdtree; - const PointType &point; - const FilterFn filter; - size_t min_idx = KDTreeIndirectType::npos; - CoordType min_dist = std::numeric_limits::max(); + struct Visitor + { + const Tree &kdtree; + const PointType &point; + const FilterFn filter; - Visitor(const KDTreeIndirectType &kdtree, const PointType &point, FilterFn filter) : kdtree(kdtree), point(point), filter(filter) {} - unsigned int operator()(size_t idx, size_t dimension) { - if (this->filter(idx)) { - auto dist = CoordType(0); - for (size_t i = 0; i < KDTreeIndirectType::NumDimensions; ++ i) { - CoordType d = point[i] - kdtree.coordinate(idx, i); - dist += d * d; - } - if (dist < min_dist) { - min_dist = dist; - min_idx = idx; - } - } - return kdtree.descent_mask(point[dimension], min_dist, idx, dimension); - } - } visitor(kdtree, point, filter); + std::array, K> results; - kdtree.visit(visitor); - return visitor.min_idx; + Visitor(const Tree &kdtree, const PointType &point, FilterFn filter) + : kdtree(kdtree), point(point), filter(filter) + { + results.fill(std::make_pair(Tree::npos, + std::numeric_limits::max())); + } + unsigned int operator()(size_t idx, size_t dimension) + { + if (this->filter(idx)) { + auto dist = CoordT(0); + for (size_t i = 0; i < D; ++i) { + CoordT d = point[i] - kdtree.coordinate(idx, i); + dist += d * d; + } + + auto res = std::make_pair(idx, dist); + auto it = std::lower_bound(results.begin(), results.end(), + res, [](auto &r1, auto &r2) { + return r1.second < r2.second; + }); + + if (it != results.end()) { + std::rotate(it, std::prev(results.end()), results.end()); + *it = res; + } + } + return kdtree.descent_mask(point[dimension], + results.front().second, idx, + dimension); + } + } visitor(kdtree, point, filter); + + kdtree.visit(visitor); + std::array ret; + for (size_t i = 0; i < K; i++) ret[i] = visitor.results[i].first; + + return ret; +} + +template +std::array find_closest_points( + const KDTreeIndirect &kdtree, const PointType &point) +{ + return find_closest_points(kdtree, point, [](size_t) { return true; }); +} + +template +size_t find_closest_point(const KDTreeIndirect &kdtree, + const PointType &point, + FilterFn filter) +{ + return find_closest_points<1>(kdtree, point, filter)[0]; } template size_t find_closest_point(const KDTreeIndirectType& kdtree, const PointType& point) { - return find_closest_point(kdtree, point, [](size_t) { return true; }); + return find_closest_point(kdtree, point, [](size_t) { return true; }); +} + +// Find nearby points (spherical neighbourhood) using Euclidian metrics. +template +std::vector find_nearby_points(const KDTreeIndirectType &kdtree, const PointType ¢er, + const typename KDTreeIndirectType::CoordType& max_distance, FilterFn filter) +{ + using CoordType = typename KDTreeIndirectType::CoordType; + + struct Visitor { + const KDTreeIndirectType &kdtree; + const PointType center; + const CoordType max_distance_squared; + const FilterFn filter; + std::vector result; + + Visitor(const KDTreeIndirectType &kdtree, const PointType& center, const CoordType &max_distance, + FilterFn filter) : + kdtree(kdtree), center(center), max_distance_squared(max_distance*max_distance), filter(filter) { + } + unsigned int operator()(size_t idx, size_t dimension) { + if (this->filter(idx)) { + auto dist = CoordType(0); + for (size_t i = 0; i < KDTreeIndirectType::NumDimensions; ++i) { + CoordType d = center[i] - kdtree.coordinate(idx, i); + dist += d * d; + } + if (dist < max_distance_squared) { + result.push_back(idx); + } + } + return kdtree.descent_mask(center[dimension], max_distance_squared, idx, dimension); + } + } visitor(kdtree, center, max_distance, filter); + + kdtree.visit(visitor); + return visitor.result; +} + +template +std::vector find_nearby_points(const KDTreeIndirectType &kdtree, const PointType ¢er, + const typename KDTreeIndirectType::CoordType& max_distance) +{ + return find_nearby_points(kdtree, center, max_distance, [](size_t) { + return true; + }); +} + +// Find nearby points (spherical neighbourhood) using Euclidian metrics. +template +std::vector find_nearby_points(const KDTreeIndirectType &kdtree, + const PointType &bb_min, + const PointType &bb_max, + FilterFn filter) +{ + struct Visitor { + const KDTreeIndirectType &kdtree; + const PointType &bb_min, &bb_max; + const FilterFn filter; + std::vector result; + + Visitor(const KDTreeIndirectType &kdtree, const PointType& bbmin, const PointType& bbmax, + FilterFn filter) : + kdtree(kdtree), bb_min{bbmin}, bb_max{bbmax}, filter(filter) { + } + unsigned int operator()(size_t idx, size_t dimension) { + unsigned int ret = + static_cast(VisitorReturnMask::CONTINUE_LEFT) | + static_cast(VisitorReturnMask::CONTINUE_RIGHT); + + if (this->filter(idx)) { + PointType p; + bool contains = true; + for (size_t i = 0; i < KDTreeIndirectType::NumDimensions; ++i) { + p(i) = kdtree.coordinate(idx, i); + contains = contains && bb_min(i) <= p(i) && p(i) <= bb_max(i); + } + + if (p(dimension) < bb_min(dimension)) + ret = static_cast(VisitorReturnMask::CONTINUE_RIGHT); + if (p(dimension) > bb_max(dimension)) + ret = static_cast(VisitorReturnMask::CONTINUE_LEFT); + + if (contains) + result.emplace_back(idx); + } + + return ret; + } + } visitor(kdtree, bb_min, bb_max, filter); + + kdtree.visit(visitor); + return visitor.result; } } // namespace Slic3r diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 5f9c8c1cbc..ba5516ba4e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -137,7 +137,7 @@ Model::~Model() // Loading model from a file, it may be a simple geometry file as STL or OBJ, however it may be a project file as well. Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, LoadStrategy options, PlateDataPtrs* plate_data, std::vector* project_presets, bool *is_xxx, Semver* file_version, Import3mfProgressFn proFn, - ImportStepProgressFn stepFn, StepIsUtf8Fn stepIsUtf8Fn, BBLProject* project) + ImportstlProgressFn stlFn, ImportStepProgressFn stepFn, StepIsUtf8Fn stepIsUtf8Fn, BBLProject* project) { Model model; @@ -163,7 +163,7 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c boost::algorithm::iends_with(input_file, ".step")) result = load_step(input_file.c_str(), &model, stepFn, stepIsUtf8Fn); else if (boost::algorithm::iends_with(input_file, ".stl")) - result = load_stl(input_file.c_str(), &model); + result = load_stl(input_file.c_str(), &model, nullptr, stlFn); else if (boost::algorithm::iends_with(input_file, ".obj")) result = load_obj(input_file.c_str(), &model); //BBS: remove the old .amf.xml files @@ -185,10 +185,10 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c if (model.objects.empty()) throw Slic3r::RuntimeError("The supplied file couldn't be read because it's empty"); - + for (ModelObject *o : model.objects) o->input_file = input_file; - + if (options & LoadStrategy::AddDefaultInstances) model.add_default_instances(); @@ -259,14 +259,14 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig //BBS //CustomGCode::update_custom_gcode_per_print_z_from_config(model.custom_gcode_per_print_z, config); - + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_UPDATE_GCODE\n"); if (proFn) { proFn(IMPORT_STAGE_UPDATE_GCODE, 0, 1, cb_cancel); if (cb_cancel) throw Slic3r::RuntimeError("Canceled"); } - + CustomGCode::check_mode_for_custom_gcode_per_print_z(model.custom_gcode_per_print_z); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << boost::format("import 3mf IMPORT_STAGE_CHECK_MODE_GCODE\n"); @@ -416,7 +416,7 @@ void Model::collect_reusable_objects(std::vector& objects) std::mem_fn(&ObjectBase::id)); model_object->volumes.clear(); } - // we never own these objects + // we never own these objects this->objects.clear(); } @@ -591,7 +591,7 @@ void Model::convert_multipart_object(unsigned int max_extruders) assert(this->objects.size() >= 2); if (this->objects.size() < 2) return; - + ModelObject* object = new ModelObject(this); object->input_file = this->objects.front()->input_file; object->name = boost::filesystem::path(this->objects.front()->input_file).stem().string(); @@ -601,7 +601,7 @@ void Model::convert_multipart_object(unsigned int max_extruders) for (const ModelObject* o : this->objects) for (const ModelVolume* v : o->volumes) { - // If there are more than one object, put all volumes together + // If there are more than one object, put all volumes together // Each object may contain any number of volumes and instances // The volumes transformations are relative to the object containing them... Geometry::Transformation trafo_volume = v->get_transformation(); @@ -620,7 +620,7 @@ void Model::convert_multipart_object(unsigned int max_extruders) } else { for (const ModelInstance* i : o->instances) // ...so, transform everything to a common reference system (world) - copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume); + copy_volume(object->add_volume(*v))->set_transformation(i->get_transformation() * trafo_volume); } } @@ -1010,6 +1010,20 @@ ModelVolume* ModelObject::add_volume(const ModelVolume &other, TriangleMesh &&me return v; } +ModelVolume* ModelObject::add_volume_with_shared_mesh(const ModelVolume &other, ModelVolumeType type /*= ModelVolumeType::INVALID*/) +{ + ModelVolume* v = new ModelVolume(this, other.m_mesh); + if (type != ModelVolumeType::INVALID && v->type() != type) + v->set_type(type); + this->volumes.push_back(v); + // The volume should already be centered at this point of time when copying shared pointers of the triangle mesh and convex hull. +// v->center_geometry_after_creation(); +// this->invalidate_bounding_box(); + // BBS: backup + Slic3r::save_object_mesh(*this); + return v; +} + void ModelObject::delete_volume(size_t idx) { ModelVolumePtrs::iterator i = this->volumes.begin() + idx; @@ -1324,7 +1338,7 @@ Polygon ModelObject::convex_hull_2d(const Transform3d& trafo_instance) const void ModelObject::center_around_origin(bool include_modifiers) { - // calculate the displacements needed to + // calculate the displacements needed to // center this object around the origin const BoundingBoxf3 bb = include_modifiers ? full_raw_mesh_bounding_box() : raw_mesh_bounding_box(); @@ -1476,8 +1490,8 @@ void ModelObject::convert_units(ModelObjectPtrs& new_objects, ConversionType con // Perform conversion only if the target "imperial" state is different from the current one. // This check supports conversion of "mixed" set of volumes, each with different "imperial" state. - if (//vol->source.is_converted_from_inches != from_imperial && - (volume_idxs.empty() || + if (//vol->source.is_converted_from_inches != from_imperial && + (volume_idxs.empty() || std::find(volume_idxs.begin(), volume_idxs.end(), vol_idx) != volume_idxs.end())) { vol->scale_geometry_after_creation(koef); vol->set_offset(Vec3d(koef, koef, koef).cwiseProduct(volume->get_offset())); @@ -1538,7 +1552,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, std::array plane_poi bool keep_lower = attributes.has(ModelObjectCutAttribute::KeepLower); bool cut_to_parts = attributes.has(ModelObjectCutAttribute::CutToParts); ModelObject* upper = keep_upper ? ModelObject::new_clone(*this) : nullptr; - ModelObject* lower = cut_to_parts ? upper : (keep_lower ? ModelObject::new_clone(*this) : nullptr); + ModelObject* lower = (cut_to_parts&&upper!=nullptr) ? upper : (keep_lower ? ModelObject::new_clone(*this) : nullptr); if (attributes.has(ModelObjectCutAttribute::KeepUpper)) { upper->set_model(nullptr); @@ -1598,7 +1612,7 @@ ModelObjectPtrs ModelObject::cut(size_t instance, std::array plane_poi if (attributes.has(ModelObjectCutAttribute::KeepLower)) lower->add_volume(*volume); } - else if (! volume->mesh().empty()) { + else if (! volume->mesh().empty()) { // Transform the mesh by the combined transformation matrix. // Flip the triangles in case the composite transformation is left handed. TriangleMesh mesh(volume->mesh()); @@ -1744,7 +1758,7 @@ ModelObjectPtrs ModelObject::segment(size_t instance, unsigned int max_extruders // Modifiers are not cut, but we still need to add the instance transformation // to the modifier volume transformation to preserve their shape properly. volume->set_transformation(Geometry::Transformation(instance_matrix * volume_matrix)); - upper->add_volume(*volume); + upper->add_volume(*volume); } else if (!volume->mesh().empty()) { // Transform the mesh by the combined transformation matrix. @@ -2185,7 +2199,7 @@ void ModelObject::print_info() const using namespace std; cout << fixed; boost::nowide::cout << "[" << boost::filesystem::path(this->input_file).filename().string() << "]" << endl; - + TriangleMesh mesh = this->raw_mesh(); BoundingBoxf3 bb = mesh.bounding_box(); Vec3d size = bb.size(); @@ -2203,7 +2217,7 @@ void ModelObject::print_info() const cout << "manifold = " << (mesh.stats().manifold() ? "yes" : "no") << endl; if (! mesh.stats().manifold()) cout << "open_edges = " << mesh.stats().open_edges << endl; - + if (mesh.stats().repaired()) { const RepairedMeshErrors& stats = mesh.stats().repaired_errors; if (stats.degenerate_facets > 0) @@ -2286,7 +2300,7 @@ void ModelVolume::set_material_id(t_model_material_id material_id) } ModelMaterial* ModelVolume::material() const -{ +{ return this->object->get_model()->get_material(m_material_id); } @@ -2362,8 +2376,10 @@ void ModelVolume::center_geometry_after_creation(bool update_source_offset) Vec3d shift = this->mesh().bounding_box().center(); if (!shift.isApprox(Vec3d::Zero())) { - if (m_mesh) - const_cast(m_mesh.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2)); + if (m_mesh) { + const_cast(m_mesh.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2)); + const_cast(m_mesh.get())->set_init_shift(shift); + } if (m_convex_hull) const_cast(m_convex_hull.get())->translate(-(float)shift(0), -(float)shift(1), -(float)shift(2)); translate(shift); @@ -2803,7 +2819,7 @@ double Model::getThermalLength(const std::vector modelVolumePtrs) } return thermalLength; } -// max printing speed, difference in bed temperature and envirument temperature and bed adhension coefficients are considered +// max printing speed, difference in bed temperature and envirument temperature and bed adhension coefficients are considered double ModelInstance::get_auto_brim_width(double deltaT, double adhension) const { BoundingBoxf3 raw_bbox = object->raw_mesh_bounding_box(); @@ -2896,7 +2912,7 @@ double ModelInstance::get_auto_brim_width() const void ModelInstance::get_arrange_polygon(void* ap) const { // static const double SIMPLIFY_TOLERANCE_MM = 0.1; - + Vec3d rotation = get_rotation(); rotation.z() = 0.; Transform3d trafo_instance = @@ -2909,7 +2925,7 @@ void ModelInstance::get_arrange_polygon(void* ap) const // pp = p.simplify(scaled(SIMPLIFY_TOLERANCE_MM)); // if (!pp.empty()) p = pp.front(); // } - + arrangement::ArrangePolygon& ret = *(arrangement::ArrangePolygon*)ap; ret.poly.contour = std::move(p); ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))}; @@ -3039,6 +3055,12 @@ void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::stri } } +bool FacetsAnnotation::equals(const FacetsAnnotation &other) const +{ + const std::pair>, std::vector>& data = other.get_data(); + return (m_data == data); +} + // Test whether the two models contain the same number of ModelObjects with the same set of IDs // ordered in the same order. In that case it is not necessary to kill the background processing. bool model_object_list_equal(const Model &model_old, const Model &model_new) @@ -3140,22 +3162,22 @@ bool model_property_changed(const ModelObject &model_object_old, const ModelObje bool model_custom_supports_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - return model_property_changed(mo, mo_new, - [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.supported_facets.timestamp_matches(mv_new.supported_facets); }); } bool model_custom_seam_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - return model_property_changed(mo, mo_new, - [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.seam_facets.timestamp_matches(mv_new.seam_facets); }); } bool model_mmu_segmentation_data_changed(const ModelObject& mo, const ModelObject& mo_new) { - return model_property_changed(mo, mo_new, - [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, + return model_property_changed(mo, mo_new, + [](const ModelVolumeType t) { return t == ModelVolumeType::MODEL_PART; }, [](const ModelVolume &mv_old, const ModelVolume &mv_new){ return mv_old.mmu_segmentation_facets.timestamp_matches(mv_new.mmu_segmentation_facets); }); } @@ -3189,7 +3211,7 @@ bool model_has_advanced_features(const Model &model) void check_model_ids_validity(const Model &model) { std::set ids; - auto check = [&ids](ObjectID id) { + auto check = [&ids](ObjectID id) { assert(id.valid()); assert(ids.find(id) == ids.end()); ids.insert(id); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 4629998021..ac78f5c981 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -18,6 +18,8 @@ #include "Format/bbs_3mf.hpp" //BBS: add step #include "Format/STEP.hpp" +//BBS: add stl +#include "Format/STL.hpp" #include #include @@ -306,6 +308,7 @@ public: ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART); ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::INVALID); ModelVolume* add_volume(const ModelVolume &volume, TriangleMesh &&mesh); + ModelVolume* add_volume_with_shared_mesh(const ModelVolume &other, ModelVolumeType type = ModelVolumeType::MODEL_PART); void delete_volume(size_t idx); void clear_volumes(); void sort_volumes(bool full_sort); @@ -615,6 +618,7 @@ public: void set_triangle_from_string(int triangle_id, const std::string& str); // After deserializing the last triangle, shrink data to fit. void shrink_to_fit() { m_data.first.shrink_to_fit(); m_data.second.shrink_to_fit(); } + bool equals(const FacetsAnnotation &other) const; private: // Constructors to be only called by derived classes. @@ -674,6 +678,7 @@ public: // The triangular model. const TriangleMesh& mesh() const { return *m_mesh.get(); } + const TriangleMesh* mesh_ptr() const { return m_mesh.get(); } void set_mesh(const TriangleMesh &mesh) { m_mesh = std::make_shared(mesh); } void set_mesh(TriangleMesh &&mesh) { m_mesh = std::make_shared(std::move(mesh)); } void set_mesh(const indexed_triangle_set &mesh) { m_mesh = std::make_shared(mesh); } @@ -857,6 +862,18 @@ private: if (mesh.facets_count() > 1) calculate_convex_hull(); } + ModelVolume(ModelObject *object, const std::shared_ptr &mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART) : m_mesh(mesh), m_type(type), object(object) + { + assert(this->id().valid()); + assert(this->config.id().valid()); + assert(this->supported_facets.id().valid()); + assert(this->seam_facets.id().valid()); + assert(this->mmu_segmentation_facets.id().valid()); + assert(this->id() != this->config.id()); + assert(this->id() != this->supported_facets.id()); + assert(this->id() != this->seam_facets.id()); + assert(this->id() != this->mmu_segmentation_facets.id()); + } ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull, ModelVolumeType type = ModelVolumeType::MODEL_PART) : m_mesh(new TriangleMesh(std::move(mesh))), m_convex_hull(new TriangleMesh(std::move(convex_hull))), m_type(type), object(object) { assert(this->id().valid()); @@ -1282,7 +1299,7 @@ public: DynamicPrintConfig* config = nullptr, ConfigSubstitutionContext* config_substitutions = nullptr, LoadStrategy options = LoadStrategy::AddDefaultInstances, PlateDataPtrs* plate_data = nullptr, std::vector* project_presets = nullptr, bool* is_xxx = nullptr, Semver* file_version = nullptr, Import3mfProgressFn proFn = nullptr, - ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn stepIsUtf8Fn = nullptr, BBLProject* project = nullptr); + ImportstlProgressFn stlFn = nullptr, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn stepIsUtf8Fn = nullptr, BBLProject* project = nullptr); // BBS static double findMaxSpeed(const ModelObject* object); static double getThermalLength(const ModelVolume* modelVolumePtr); diff --git a/src/libslic3r/MultiPoint.cpp b/src/libslic3r/MultiPoint.cpp index 227f0eea3d..0076300ea6 100644 --- a/src/libslic3r/MultiPoint.cpp +++ b/src/libslic3r/MultiPoint.cpp @@ -63,6 +63,23 @@ int MultiPoint::find_point(const Point &point) const return -1; // not found } +int MultiPoint::find_point(const Point &point, double scaled_epsilon) const +{ + if (scaled_epsilon == 0) return this->find_point(point); + + auto dist2_min = std::numeric_limits::max(); + auto eps2 = scaled_epsilon * scaled_epsilon; + int idx_min = -1; + for (const Point &pt : this->points) { + double d2 = (pt - point).cast().squaredNorm(); + if (d2 < dist2_min) { + idx_min = int(&pt - &this->points.front()); + dist2_min = d2; + } + } + return dist2_min < eps2 ? idx_min : -1; +} + bool MultiPoint::has_boundary_point(const Point &point) const { double dist = (point.projection_onto(*this) - point).cast().norm(); diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index 86555c33a6..4c1f9049ed 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -43,7 +43,12 @@ public: double length() const; bool is_valid() const { return this->points.size() >= 2; } + // Return index of a polygon point exactly equal to point. + // Return -1 if no such point exists. int find_point(const Point &point) const; + // Return index of the closest point to point closer than scaled_epsilon. + // Return -1 if no such point exists. + int find_point(const Point &point, const double scaled_epsilon) const; bool has_boundary_point(const Point &point) const; int closest_point_index(const Point &point) const { int idx = -1; diff --git a/src/libslic3r/NormalUtils.cpp b/src/libslic3r/NormalUtils.cpp new file mode 100644 index 0000000000..dc94515656 --- /dev/null +++ b/src/libslic3r/NormalUtils.cpp @@ -0,0 +1,142 @@ +#include "NormalUtils.hpp" + +using namespace Slic3r; + +Vec3f NormalUtils::create_triangle_normal( + const stl_triangle_vertex_indices &indices, + const std::vector & vertices) +{ + const stl_vertex &v0 = vertices[indices[0]]; + const stl_vertex &v1 = vertices[indices[1]]; + const stl_vertex &v2 = vertices[indices[2]]; + Vec3f direction = (v1 - v0).cross(v2 - v0); + direction.normalize(); + return direction; +} + +std::vector NormalUtils::create_triangle_normals( + const indexed_triangle_set &its) +{ + std::vector normals; + normals.reserve(its.indices.size()); + for (const Vec3crd &index : its.indices) { + normals.push_back(create_triangle_normal(index, its.vertices)); + } + return normals; +} + +NormalUtils::Normals NormalUtils::create_normals_average_neighbor( + const indexed_triangle_set &its) +{ + size_t count_vertices = its.vertices.size(); + std::vector normals(count_vertices, Vec3f(.0f, .0f, .0f)); + std::vector count(count_vertices, 0); + for (const Vec3crd &indice : its.indices) { + Vec3f normal = create_triangle_normal(indice, its.vertices); + for (int i = 0; i < 3; ++i) { + normals[indice[i]] += normal; + ++count[indice[i]]; + } + } + // normalize to size 1 + for (auto &normal : normals) { + size_t index = &normal - &normals.front(); + normal /= static_cast(count[index]); + } + return normals; +} + +// calc triangle angle of vertex defined by index to triangle indices +float NormalUtils::indice_angle(int i, + const Vec3crd & indice, + const std::vector &vertices) +{ + int i1 = (i == 0) ? 2 : (i - 1); + int i2 = (i == 2) ? 0 : (i + 1); + + Vec3f v1 = vertices[i1] - vertices[i]; + Vec3f v2 = vertices[i2] - vertices[i]; + + v1.normalize(); + v2.normalize(); + + float w = v1.dot(v2); + if (w > 1.f) + w = 1.f; + else if (w < -1.f) + w = -1.f; + return acos(w); +} + +NormalUtils::Normals NormalUtils::create_normals_angle_weighted( + const indexed_triangle_set &its) +{ + size_t count_vertices = its.vertices.size(); + std::vector normals(count_vertices, Vec3f(.0f, .0f, .0f)); + std::vector count(count_vertices, 0.f); + for (const Vec3crd &indice : its.indices) { + Vec3f normal = create_triangle_normal(indice, its.vertices); + Vec3f angles(indice_angle(0, indice, its.vertices), + indice_angle(1, indice, its.vertices), 0.f); + angles[2] = (M_PI - angles[0] - angles[1]); + for (int i = 0; i < 3; ++i) { + const float &weight = angles[i]; + normals[indice[i]] += normal * weight; + count[indice[i]] += weight; + } + } + // normalize to size 1 + for (auto &normal : normals) { + size_t index = &normal - &normals.front(); + normal /= count[index]; + } + return normals; +} + +NormalUtils::Normals NormalUtils::create_normals_nelson_weighted( + const indexed_triangle_set &its) +{ + size_t count_vertices = its.vertices.size(); + std::vector normals(count_vertices, Vec3f(.0f, .0f, .0f)); + std::vector count(count_vertices, 0.f); + const std::vector &vertices = its.vertices; + for (const Vec3crd &indice : its.indices) { + Vec3f normal = create_triangle_normal(indice, vertices); + + const stl_vertex &v0 = vertices[indice[0]]; + const stl_vertex &v1 = vertices[indice[1]]; + const stl_vertex &v2 = vertices[indice[2]]; + + float e0 = (v0 - v1).norm(); + float e1 = (v1 - v2).norm(); + float e2 = (v2 - v0).norm(); + + Vec3f coefs(e0 * e2, e0 * e1, e1 * e2); + for (int i = 0; i < 3; ++i) { + const float &weight = coefs[i]; + normals[indice[i]] += normal * weight; + count[indice[i]] += weight; + } + } + // normalize to size 1 + for (auto &normal : normals) { + size_t index = &normal - &normals.front(); + normal /= count[index]; + } + return normals; +} + +// calculate normals by averaging normals of neghbor triangles +std::vector NormalUtils::create_normals( + const indexed_triangle_set &its, VertexNormalType type) +{ + switch (type) { + case VertexNormalType::AverageNeighbor: + return create_normals_average_neighbor(its); + case VertexNormalType::AngleWeighted: + return create_normals_angle_weighted(its); + case VertexNormalType::NelsonMaxWeighted: + default: + return create_normals_nelson_weighted(its); + } +} diff --git a/src/libslic3r/NormalUtils.hpp b/src/libslic3r/NormalUtils.hpp new file mode 100644 index 0000000000..60ec57f724 --- /dev/null +++ b/src/libslic3r/NormalUtils.hpp @@ -0,0 +1,69 @@ +#ifndef slic3r_NormalUtils_hpp_ +#define slic3r_NormalUtils_hpp_ + +#include "Point.hpp" +#include "Model.hpp" + +namespace Slic3r { + +/// +/// Collection of static function +/// to create normals +/// +class NormalUtils +{ +public: + using Normal = Vec3f; + using Normals = std::vector; + NormalUtils() = delete; // only static functions + + enum class VertexNormalType { + AverageNeighbor, + AngleWeighted, + NelsonMaxWeighted + }; + + /// + /// Create normal for triangle defined by indices from vertices + /// + /// index into vertices + /// vector of vertices + /// normal to triangle(normalized to size 1) + static Normal create_triangle_normal( + const stl_triangle_vertex_indices &indices, + const std::vector & vertices); + + /// + /// Create normals for each vertices + /// + /// indices and vertices + /// Vector of normals + static Normals create_triangle_normals(const indexed_triangle_set &its); + + /// + /// Create normals for each vertex by averaging neighbor triangles normal + /// + /// Triangle indices and vertices + /// Type of calculation normals + /// Normal for each vertex + static Normals create_normals( + const indexed_triangle_set &its, + VertexNormalType type = VertexNormalType::NelsonMaxWeighted); + static Normals create_normals_average_neighbor(const indexed_triangle_set &its); + static Normals create_normals_angle_weighted(const indexed_triangle_set &its); + static Normals create_normals_nelson_weighted(const indexed_triangle_set &its); + + /// + /// Calculate angle of trinagle side. + /// + /// index to indices, define angle point + /// address to vertices + /// vertices data + /// Angle [in radian] + static float indice_angle(int i, + const Vec3crd & indice, + const std::vector &vertices); +}; + +} // namespace Slic3r +#endif // slic3r_NormalUtils_hpp_ diff --git a/src/libslic3r/Polyline.cpp b/src/libslic3r/Polyline.cpp index ca11357bb4..78b064e24f 100644 --- a/src/libslic3r/Polyline.cpp +++ b/src/libslic3r/Polyline.cpp @@ -517,6 +517,28 @@ bool remove_degenerate(Polylines &polylines) return modified; } +std::pair foot_pt(const Points &polyline, const Point &pt) +{ + if (polyline.size() < 2) return std::make_pair(-1, Point(0, 0)); + + auto d2_min = std::numeric_limits::max(); + Point foot_pt_min; + Point prev = polyline.front(); + auto it = polyline.begin(); + auto it_proj = polyline.begin(); + for (++it; it != polyline.end(); ++it) { + Point foot_pt = pt.projection_onto(Line(prev, *it)); + double d2 = (foot_pt - pt).cast().squaredNorm(); + if (d2 < d2_min) { + d2_min = d2; + foot_pt_min = foot_pt; + it_proj = it; + } + prev = *it; + } + return std::make_pair(int(it_proj - polyline.begin()) - 1, foot_pt_min); +} + ThickLines ThickPolyline::thicklines() const { ThickLines lines; diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp index d97801ac63..45361f68e2 100644 --- a/src/libslic3r/Polyline.hpp +++ b/src/libslic3r/Polyline.hpp @@ -222,6 +222,9 @@ const Point& leftmost_point(const Polylines &polylines); bool remove_degenerate(Polylines &polylines); +// Returns index of a segment of a polyline and foot point of pt on polyline. +std::pair foot_pt(const Points &polyline, const Point &pt); + class ThickPolyline : public Polyline { public: ThickPolyline() : endpoints(std::make_pair(false, false)) {} diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 21a8ceee6b..270ee69f65 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -691,7 +691,7 @@ static std::vector s_Preset_filament_options { "filament_flow_ratio", "filament_density", "filament_cost", "filament_minimal_purge_on_wipe_tower", "chamber_temperature", "nozzle_temperature", "nozzle_temperature_initial_layer", // BBS - "cool_plate_temp", "eng_plate_temp", "hot_plate_temp", "cool_plate_temp_initial_layer", "eng_plate_temp_initial_layer", "hot_plate_temp_initial_layer", + "cool_plate_temp", "eng_plate_temp", "hot_plate_temp", "textured_plate_temp", "cool_plate_temp_initial_layer", "eng_plate_temp_initial_layer", "hot_plate_temp_initial_layer","textured_plate_temp_initial_layer", // "bed_type", //BBS:temperature_vitrification "temperature_vitrification", "reduce_fan_stop_start_freq", "slow_down_for_layer_cooling", "fan_min_speed", @@ -1400,7 +1400,7 @@ bool PresetCollection::load_user_preset(std::string name, std::map PresetCollection::load_external_preset( Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select) { + lock(); auto it = this->find_preset_internal(name); if (it == m_presets.end() || it->name != name) { // The preset was not found. Create a new preset. + if (m_presets.begin() + m_idx_selected >= it) + ++m_idx_selected; it = m_presets.emplace(it, Preset(m_type, name, false)); } Preset &preset = *it; @@ -1842,6 +1845,7 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string preset.is_dirty = false; if (select) this->select_preset_by_name(name, true); + unlock(); //BBS: add config related logs BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", preset type %1%, name %2%, path %3%, is_system %4%, is_default %5% is_visible %6%")%Preset::get_type_string(m_type) %preset.name %preset.file %preset.is_system %preset.is_default %preset.is_visible; return preset; diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index 669149697f..641f407141 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -592,6 +592,102 @@ PresetsConfigSubstitutions PresetBundle::load_user_presets(AppConfig &config, st return substitutions; } +PresetsConfigSubstitutions PresetBundle::import_presets(std::vector & files, + std::function override_confirm, + ForwardCompatibilitySubstitutionRule rule) +{ + PresetsConfigSubstitutions substitutions; + int overwrite = 0; + std::vector result; + for (auto &file : files) { + if (Slic3r::is_json_file(file)) { + try { + DynamicPrintConfig config; + // BBS: change to json format + // ConfigSubstitutions config_substitutions = config.load_from_ini(preset.file, substitution_rule); + std::map key_values; + std::string reason; + ConfigSubstitutions config_substitutions = config.load_from_json(file, rule, key_values, reason); + std::string name = key_values[BBL_JSON_KEY_NAME]; + std::string version_str = key_values[BBL_JSON_KEY_VERSION]; + boost::optional version = Semver::parse(version_str); + if (!version) continue; + Semver app_version = *(Semver::parse(SLIC3R_VERSION)); + if (version->maj() != app_version.maj()) { + BOOST_LOG_TRIVIAL(warning) << "Preset incompatibla, not loading: " << name; + continue; + } + + PresetCollection * collection = nullptr; + if (config.has("printer_settings_id")) + collection = &printers; + else if (config.has("print_settings_id")) + collection = &prints; + else if (config.has("filament_settings_id")) + collection = &filaments; + if (collection == nullptr) { + BOOST_LOG_TRIVIAL(warning) << "Preset type is unknown, not loading: " << name; + continue; + } + if (auto p = collection->find_preset(name, false)) { + if (p->is_default || p->is_system) { + BOOST_LOG_TRIVIAL(warning) << "Preset already present and is system preset, not loading: " << name; + continue; + } + overwrite = override_confirm(name); + if (overwrite == 0 || overwrite == 2) { + BOOST_LOG_TRIVIAL(warning) << "Preset already present, not loading: " << name; + continue; + } + } + + DynamicPrintConfig new_config; + Preset * inherit_preset = nullptr; + ConfigOption *inherits_config = config.option(BBL_JSON_KEY_INHERITS); + if (inherits_config) { + ConfigOptionString *option_str = dynamic_cast(inherits_config); + std::string inherits_value = option_str->value; + inherit_preset = collection->find_preset(inherits_value, false, true); + } + if (inherit_preset) { + new_config = inherit_preset->config; + } else { + // Find a default preset for the config. The PrintPresetCollection provides different default preset based on the "printer_technology" field. + // new_config = default_preset.config; + // we should skip this preset here + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", can not find inherit preset for user preset %1%, just skip") % name; + continue; + } + new_config.apply(std::move(config)); + + Preset &preset = collection->load_preset(collection->path_from_name(name), name, std::move(new_config), false); + preset.is_external = true; + preset.version = *version; + if (inherit_preset) + preset.base_id = inherit_preset->setting_id; + Preset::normalize(preset.config); + // Report configuration fields, which are misplaced into a wrong group. + const Preset &default_preset = collection->default_preset_for(new_config); + std::string incorrect_keys = Preset::remove_invalid_keys(preset.config, default_preset.config); + if (!incorrect_keys.empty()) + BOOST_LOG_TRIVIAL(error) << "Error in a preset file: The preset \"" << preset.file << "\" contains the following incorrect keys: " << incorrect_keys + << ", which were removed"; + if (!config_substitutions.empty()) + substitutions.push_back({name, collection->type(), PresetConfigSubstitutions::Source::UserFile, file, std::move(config_substitutions)}); + + preset.save(inherit_preset ? &inherit_preset->config : nullptr); + result.push_back(file); + } catch (const std::ifstream::failure &err) { + BOOST_LOG_TRIVIAL(error) << boost::format("The config cannot be loaded: %1%. Reason: %2%") % file % err.what(); + } catch (const std::runtime_error &err) { + BOOST_LOG_TRIVIAL(error) << boost::format("Failed importing config file: %1%. Reason: %2%") % file % err.what(); + } + } + } + files = result; + return substitutions; +} + //BBS save user preset to user_id preset folder void PresetBundle::save_user_presets(AppConfig& config, std::vector& need_to_delete_list) { @@ -626,6 +722,17 @@ void PresetBundle::update_user_presets_directory(const std::string preset_folder BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" finished"); } +void PresetBundle::remove_user_presets_directory(const std::string preset_folder) +{ + const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + preset_folder; + + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" enter, delete directory : %1%") % dir_user_presets; + fs::path folder(dir_user_presets); + if (fs::exists(folder)) { + fs::remove_all(folder); + } +} + void PresetBundle::update_system_preset_setting_ids(std::map>& system_presets) { for (auto iterator: system_presets) @@ -3215,6 +3322,36 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri } }*/ +std::vector PresetBundle::export_current_configs(const std::string & path, + std::function override_confirm, + bool include_modify, + bool export_system_settings) +{ + const Preset &print_preset = include_modify ? prints.get_edited_preset() : prints.get_selected_preset(); + const Preset &printer_preset = include_modify ? printers.get_edited_preset() : printers.get_selected_preset(); + std::set presets { &print_preset, &printer_preset }; + for (auto &f : filament_presets) { + auto filament_preset = filaments.find_preset(f, include_modify); + if (filament_preset) presets.insert(filament_preset); + } + + int overwrite = 0; + std::vector result; + for (auto preset : presets) { + if ((preset->is_system && !export_system_settings) || preset->is_default) + continue; + std::string file = path + "/" + preset->name + ".json"; + if (boost::filesystem::exists(file) && overwrite < 2) { + overwrite = override_confirm(preset->name); + if (overwrite == 0 || overwrite == 2) + continue; + } + preset->config.save_to_json(file, preset->name, "", preset->version.to_string()); + result.push_back(file); + } + return result; +} + // Set the filament preset name. As the name could come from the UI selection box, // an optional "(modified)" suffix will be removed from the filament name. void PresetBundle::set_filament_preset(size_t idx, const std::string &name) diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index cb279f0044..0cd7aef994 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -46,9 +46,11 @@ public: // BBS Load user presets PresetsConfigSubstitutions load_user_presets(AppConfig &config, std::map>& my_presets, ForwardCompatibilitySubstitutionRule rule); + PresetsConfigSubstitutions import_presets(std::vector &files, std::function override_confirm, ForwardCompatibilitySubstitutionRule rule); void save_user_presets(AppConfig& config, std::vector& need_to_delete_list); void remove_users_preset(AppConfig &config); - void update_user_presets_directory(const std::string preset_folder); + void update_user_presets_directory(const std::string preset_folder); + void remove_user_presets_directory(const std::string preset_folder); void update_system_preset_setting_ids(std::map>& system_presets); //BBS: add API to get previous machine @@ -164,6 +166,8 @@ public: //void export_current_configbundle(const std::string &path); //BBS: add a function to export system presets for cloud-slicer //void export_system_configs(const std::string &path); + std::vector export_current_configs(const std::string &path, std::function override_confirm, + bool include_modify, bool export_system_settings = false); // Enable / disable the "- default -" preset. void set_default_suppressed(bool default_suppressed); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 4331192c49..75c79898e1 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -96,6 +96,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "cool_plate_temp_initial_layer", "eng_plate_temp_initial_layer", "hot_plate_temp_initial_layer", + "textured_plate_temp_initial_layer", "gcode_add_line_number", "layer_change_gcode", "fan_min_speed", @@ -175,6 +176,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "cool_plate_temp" || opt_key == "eng_plate_temp" || opt_key == "hot_plate_temp" + || opt_key == "textured_plate_temp" || opt_key == "enable_prime_tower" || opt_key == "prime_tower_width" || opt_key == "prime_tower_brim_width" @@ -1132,6 +1134,46 @@ void Print::auto_assign_extruders(ModelObject* model_object) const } } +void PrintObject::set_shared_object(PrintObject *object) +{ + m_shared_object = object; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, found shared object from %2%")%this%m_shared_object; +} + +void PrintObject::clear_shared_object() +{ + if (m_shared_object) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, clear previous shared object data %2%")%this %m_shared_object; + m_layers.clear(); + m_support_layers.clear(); + m_tree_support_layers.clear(); + + m_shared_object = nullptr; + + invalidate_all_steps_without_cancel(); + } +} + +void PrintObject::copy_layers_from_shared_object() +{ + if (m_shared_object) { + m_layers.clear(); + m_support_layers.clear(); + m_tree_support_layers.clear(); + + firstLayerObjSliceByVolume.clear(); + firstLayerObjSliceByGroups.clear(); + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, copied layers from object %2%")%this%m_shared_object; + m_layers = m_shared_object->layers(); + m_support_layers = m_shared_object->support_layers(); + m_tree_support_layers = m_shared_object->tree_support_layers(); + + firstLayerObjSliceByVolume = m_shared_object->firstLayerObjSlice(); + firstLayerObjSliceByGroups = m_shared_object->firstLayerObjGroups(); + } +} + // BBS BoundingBox PrintObject::get_first_layer_bbox(float& a, float& layer_height, std::string& name) { @@ -1181,15 +1223,115 @@ void Print::process() { name_tbb_thread_pool_threads_set_locale(); + //compute the PrintObject with the same geometries + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, enter")%this; + for (PrintObject *obj : m_objects) + obj->clear_shared_object(); + + //add the print_object share check logic + auto is_print_object_the_same = [this](const PrintObject* object1, const PrintObject* object2) -> bool{ + if (object1->trafo().matrix() != object2->trafo().matrix()) + return false; + const ModelObject* model_obj1 = object1->model_object(); + const ModelObject* model_obj2 = object2->model_object(); + if (model_obj1->volumes.size() != model_obj2->volumes.size()) + return false; + bool has_extruder1 = model_obj1->config.has("extruder"); + bool has_extruder2 = model_obj2->config.has("extruder"); + if ((has_extruder1 != has_extruder2) + || (has_extruder1 && model_obj1->config.extruder() != model_obj2->config.extruder())) + return false; + for (int index = 0; index < model_obj1->volumes.size(); index++) { + const ModelVolume &model_volume1 = *model_obj1->volumes[index]; + const ModelVolume &model_volume2 = *model_obj2->volumes[index]; + if (model_volume1.type() != model_volume2.type()) + return false; + if (model_volume1.mesh_ptr() != model_volume2.mesh_ptr()) + return false; + has_extruder1 = model_volume1.config.has("extruder"); + has_extruder2 = model_volume2.config.has("extruder"); + if ((has_extruder1 != has_extruder2) + || (has_extruder1 && model_volume1.config.extruder() != model_volume2.config.extruder())) + return false; + if (!model_volume1.supported_facets.equals(model_volume2.supported_facets)) + return false; + if (!model_volume1.seam_facets.equals(model_volume2.seam_facets)) + return false; + if (!model_volume1.mmu_segmentation_facets.equals(model_volume2.mmu_segmentation_facets)) + return false; + if (model_volume1.config.get() != model_volume2.config.get()) + return false; + } + //if (!object1->config().equals(object2->config())) + // return false; + if (model_obj1->config.get() != model_obj2->config.get()) + return false; + return true; + }; + int object_count = m_objects.size(); + std::set need_slicing_objects; + for (int index = 0; index < object_count; index++) + { + PrintObject *obj = m_objects[index]; + for (PrintObject *slicing_obj : need_slicing_objects) + { + if (is_print_object_the_same(obj, slicing_obj)) { + obj->set_shared_object(slicing_obj); + break; + } + } + if (!obj->get_shared_object()) + need_slicing_objects.insert(obj); + } + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": total object counts %1% in current print, need to slice %2%")%m_objects.size()%need_slicing_objects.size(); BOOST_LOG_TRIVIAL(info) << "Starting the slicing process." << log_memory_info(); + for (PrintObject *obj : m_objects) { + if (need_slicing_objects.count(obj) != 0) { + obj->make_perimeters(); + } + else { + if (obj->set_started(posSlice)) + obj->set_done(posSlice); + if (obj->set_started(posPerimeters)) + obj->set_done(posPerimeters); + } + } + for (PrintObject *obj : m_objects) { + if (need_slicing_objects.count(obj) != 0) { + obj->infill(); + } + else { + if (obj->set_started(posPrepareInfill)) + obj->set_done(posPrepareInfill); + if (obj->set_started(posInfill)) + obj->set_done(posInfill); + } + } + for (PrintObject *obj : m_objects) { + if (need_slicing_objects.count(obj) != 0) { + obj->ironing(); + } + else { + if (obj->set_started(posIroning)) + obj->set_done(posIroning); + } + } + for (PrintObject *obj : m_objects) { + if (need_slicing_objects.count(obj) != 0) { + obj->generate_support_material(); + } + else { + if (obj->set_started(posSupportMaterial)) + obj->set_done(posSupportMaterial); + } + } + for (PrintObject *obj : m_objects) - obj->make_perimeters(); - for (PrintObject *obj : m_objects) - obj->infill(); - for (PrintObject *obj : m_objects) - obj->ironing(); - for (PrintObject *obj : m_objects) - obj->generate_support_material(); + { + if (need_slicing_objects.count(obj) == 0) + obj->copy_layers_from_shared_object(); + } if (this->set_started(psWipeTower)) { m_wipe_tower_data.clear(); m_tool_ordering.clear(); @@ -1292,8 +1434,17 @@ void Print::process() this->set_done(psSkirtBrim); } //BBS - for (PrintObject *obj : m_objects) - obj->simplify_extrusion_path(); + for (PrintObject *obj : m_objects) { + if (need_slicing_objects.count(obj) != 0) { + obj->simplify_extrusion_path(); + } + else { + if (obj->set_started(posSimplifyPath)) + obj->set_done(posSimplifyPath); + if (obj->set_started(posSimplifySupportPath)) + obj->set_done(posSimplifySupportPath); + } + } BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); } @@ -1634,7 +1785,7 @@ void Print::_make_wipe_tower() for (LayerTools& layer_tools : layer_tools_array) { layer_tools.has_wipe_tower = true; if (layer_tools.wipe_tower_partitions == 0) { - layer_tools.wipe_tower_partitions = 1; + layer_tools.wipe_tower_partitions = 1; } } } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index b07b6719e6..084763db3a 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -49,6 +49,12 @@ struct groupedVolumeSlices ExPolygons slices; }; +enum SupportNecessaryType { + NoNeedSupp=0, + SharpTail, + LargeOverhang, +}; + namespace FillAdaptive { struct Octree; struct OctreeDeleter; @@ -409,6 +415,11 @@ public: //BBS BoundingBox get_first_layer_bbox(float& area, float& layer_height, std::string& name); + PrintObject* get_shared_object() const { return m_shared_object; } + void set_shared_object(PrintObject *object); + void clear_shared_object(); + void copy_layers_from_shared_object(); + // BBS: Boundingbox of the first layer BoundingBox firstLayerObjectBrimBoundingBox; private: @@ -457,7 +468,7 @@ private: std::pair prepare_adaptive_infill_data(); // BBS - bool is_support_necessary(); + SupportNecessaryType is_support_necessary(); // XYZ in scaled coordinates Vec3crd m_size; @@ -489,6 +500,8 @@ private: // BBS: per object skirt ExtrusionEntityCollection m_skirt; + PrintObject* m_shared_object{ nullptr }; + public: //BBS: When printing multi-material objects, this settings will make slicer to clip the overlapping object parts one by the other. //(2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc). diff --git a/src/libslic3r/PrintBase.hpp b/src/libslic3r/PrintBase.hpp index 5196d63698..c6ecf4ebeb 100644 --- a/src/libslic3r/PrintBase.hpp +++ b/src/libslic3r/PrintBase.hpp @@ -629,6 +629,8 @@ protected: { return m_state.invalidate_multiple(il.begin(), il.end(), PrintObjectBase::cancel_callback(m_print)); } bool invalidate_all_steps() { return m_state.invalidate_all(PrintObjectBase::cancel_callback(m_print)); } + bool invalidate_all_steps_without_cancel() + { return m_state.invalidate_all([](){}); } bool is_step_started_unguarded(PrintObjectStepEnum step) const { return m_state.is_started_unguarded(step); } bool is_step_done_unguarded(PrintObjectStepEnum step) const { return m_state.is_done_unguarded(step); } diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 0e52afba18..5ac91ea964 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -230,7 +230,8 @@ static const t_config_enum_values s_keys_map_OverhangFanThreshold = { static const t_config_enum_values s_keys_map_BedType = { { "Cool Plate", btPC }, { "Engineering Plate", btEP }, - { "High Temp Plate", btPEI } + { "High Temp Plate", btPEI }, + { "Textured PEI Plate", btPTE } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(BedType) @@ -462,6 +463,16 @@ void PrintConfigDef::init_fff_params() def->max = 120; def->set_default_value(new ConfigOptionInts{ 45 }); + def = this->add("textured_plate_temp", coInts); + def->label = L("Other layers"); + def->tooltip = L("Bed temperature for layers except the initial one. " + "Value 0 means the filament does not support to print on the Textured PEI Plate"); + def->sidetext = L("°C"); + def->full_label = L("Bed temperature"); + def->min = 0; + def->max = 120; + def->set_default_value(new ConfigOptionInts{45}); + def = this->add("cool_plate_temp_initial_layer", coInts); def->label = L("Initial layer"); def->full_label = L("Initial layer bed temperature"); @@ -492,6 +503,15 @@ void PrintConfigDef::init_fff_params() def->max = 120; def->set_default_value(new ConfigOptionInts{ 45 }); + def = this->add("textured_plate_temp_initial_layer", coInts); + def->label = L("Initial layer"); + def->full_label = L("Initial layer bed temperature"); + def->tooltip = L("Bed temperature of the initial layer. " + "Value 0 means the filament does not support to print on the Textured PEI Plate"); + def->sidetext = L("°C"); + def->max = 0; + def->max = 120; + def->set_default_value(new ConfigOptionInts{45}); def = this->add("curr_bed_type", coEnums); def->label = L("Bed type"); @@ -501,9 +521,11 @@ void PrintConfigDef::init_fff_params() def->enum_values.emplace_back("Cool Plate"); def->enum_values.emplace_back("Engineering Plate"); def->enum_values.emplace_back("High Temp Plate"); + def->enum_values.emplace_back("Textured PEI Plate"); def->enum_labels.emplace_back(L("Cool Plate")); def->enum_labels.emplace_back(L("Engineering Plate")); def->enum_labels.emplace_back(L("High Temp Plate")); + def->enum_labels.emplace_back(L("Textured PEI Plate")); def->set_default_value(new ConfigOptionEnum(btPC)); def = this->add("before_layer_change_gcode", coString); @@ -1091,7 +1113,7 @@ void PrintConfigDef::init_fff_params() def->tooltip = L("Filament price. For statistics only"); def->sidetext = L("money/kg"); def->min = 0; - def->mode = comDevelop; + def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); def = this->add("filament_settings_id", coStrings); @@ -2000,9 +2022,11 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("nearest"); def->enum_values.push_back("aligned"); def->enum_values.push_back("back"); + def->enum_values.push_back("random"); def->enum_labels.push_back(L("Nearest")); def->enum_labels.push_back(L("Aligned")); def->enum_labels.push_back(L("Back")); + def->enum_labels.push_back(L("Random")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnum(spAligned)); @@ -2108,10 +2132,12 @@ void PrintConfigDef::init_fff_params() def = this->add("timelapse_no_toolhead", coBool); def->label = L("Timelapse"); - def->tooltip = L("Record timelapse video of printing without showing toolhead. In this mode " - "the toolhead docks near the excess chute at each layer change, and then " - "a snapshot is taken with the chamber camera. When printing finishes a timelapse " - "video is composed of all the snapshots."); + def->tooltip = L("If enabled, a timelapse video will be generated for each print. " + "After each layer is printed, the toolhead will move to the excess chute, " + "and then a snapshot is taken with the chamber camera. " + "All of these snapshots are composed into a timelapse video when printing completes. " + "Since the melt filament may leak from the nozzle during the process of taking a snapshot, " + "prime tower is required for nozzle priming."); def->mode = comSimple; def->set_default_value(new ConfigOptionBool(false)); @@ -2406,8 +2432,7 @@ void PrintConfigDef::init_fff_params() def = this->add("independent_support_layer_height", coBool); def->label = L("Independent support layer height"); def->category = L("Support"); - def->tooltip = L("Support layer uses layer height independent with object layer. This is to support custom support gap," - "but may cause extra filament switches if support is specified as different extruder with object"); + def->tooltip = L("Support layer uses layer height independent with object layer. This is to support customizing z-gap and save print time."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(true)); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8c1c94b48d..d8fa2468b7 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -160,6 +160,7 @@ enum BedType { btPC = 0, btEP, btPEI, + btPTE, btCount }; @@ -185,6 +186,8 @@ static std::string bed_type_to_gcode_string(const BedType type) case btPEI: type_str = "high_temp_plate"; break; + case btPTE: + type_str = "frosted_plate"; default: type_str = "unknown"; break; @@ -204,6 +207,9 @@ static std::string get_bed_temp_key(const BedType type) if (type == btPEI) return "hot_plate_temp"; + if (type == btPTE) + return "textured_plate_temp"; + return ""; } @@ -218,6 +224,9 @@ static std::string get_bed_temp_1st_layer_key(const BedType type) if (type == btPEI) return "hot_plate_temp_initial_layer"; + if (type == btPTE) + return "textured_plate_temp_initial_layer"; + return ""; } @@ -786,9 +795,11 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionInts, cool_plate_temp)) ((ConfigOptionInts, eng_plate_temp)) ((ConfigOptionInts, hot_plate_temp)) // hot is short for high temperature + ((ConfigOptionInts, textured_plate_temp)) ((ConfigOptionInts, cool_plate_temp_initial_layer)) ((ConfigOptionInts, eng_plate_temp_initial_layer)) ((ConfigOptionInts, hot_plate_temp_initial_layer)) // hot is short for high temperature + ((ConfigOptionInts, textured_plate_temp_initial_layer)) ((ConfigOptionBools, enable_overhang_bridge_fan)) ((ConfigOptionInts, overhang_fan_speed)) ((ConfigOptionEnumsGeneric, overhang_fan_threshold)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 849712c475..ebac5bf93f 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -86,6 +86,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Transfor PrintObject::~PrintObject() { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, m_shared_object %2%")%this%m_shared_object; if (m_shared_regions && -- m_shared_regions->m_ref_cnt == 0) delete m_shared_regions; clear_layers(); clear_support_layers(); @@ -419,11 +420,17 @@ void PrintObject::generate_support_material() m_print->throw_if_canceled(); } else { // BBS: pop a warning if objects have significant amount of overhangs but support material is not enabled - if (this->is_support_necessary()) { + SupportNecessaryType sntype = this->is_support_necessary(); + if (sntype != NoNeedSupp) { m_print->set_status(50, L("Checking support necessity")); - - std::string warning_message = format(L("It seems object %s needs support to print. Please enable support generation."), this->model_object()->name); - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + if (sntype == SharpTail) { + std::string warning_message = format(L("It seems object %s has completely floating regions. Please re-orient the object or enable support generation."), + this->model_object()->name); + this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + } else { + std::string warning_message = format(L("It seems object %s has large overhangs. Please enable support generation."), this->model_object()->name); + this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); + } } #if 0 @@ -529,9 +536,11 @@ std::pair PrintObject::prepare void PrintObject::clear_layers() { - for (Layer *l : m_layers) - delete l; - m_layers.clear(); + if (!m_shared_object) { + for (Layer *l : m_layers) + delete l; + m_layers.clear(); + } } Layer* PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z) @@ -567,9 +576,11 @@ SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_ void PrintObject::clear_tree_support_layers() { - for (TreeSupportLayer* l : m_tree_support_layers) - delete l; - m_tree_support_layers.clear(); + if (!m_shared_object) { + for (TreeSupportLayer* l : m_tree_support_layers) + delete l; + m_tree_support_layers.clear(); + } } std::shared_ptr PrintObject::alloc_tree_support_preview_cache() @@ -596,9 +607,11 @@ TreeSupportLayer* PrintObject::add_tree_support_layer(int id, coordf_t height, c void PrintObject::clear_support_layers() { - for (Layer *l : m_support_layers) - delete l; - m_support_layers.clear(); + if (!m_shared_object) { + for (Layer *l : m_support_layers) + delete l; + m_support_layers.clear(); + } } SupportLayer* PrintObject::add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z) @@ -2448,7 +2461,7 @@ template void PrintObject::remove_bridges_from_contacts( float max_bridge_length, bool break_bridge); -bool PrintObject::is_support_necessary() +SupportNecessaryType PrintObject::is_support_necessary() { static const double super_overhang_area_threshold = SQ(scale_(5.0)); @@ -2471,7 +2484,7 @@ bool PrintObject::is_support_necessary() for (const ExPolygon& expoly : layerm->raw_slices) { // detect sharp tail if (intersection_ex({ expoly }, lower_layer_offseted).empty()) - return true; + return SharpTail; } } @@ -2503,18 +2516,19 @@ bool PrintObject::is_support_necessary() double super_overhang_area = 0.0; for (Polygon& poly : super_overhang_polys) { bool is_ccw = poly.is_counter_clockwise(); + double area_ = poly.area(); if (is_ccw) { - if (super_overhang_area > super_overhang_area_threshold) - return true; - super_overhang_area = poly.area(); + if (area_ > super_overhang_area_threshold) + return LargeOverhang; + super_overhang_area += area_; } else { - super_overhang_area -= poly.area(); + super_overhang_area -= area_; } } - if (super_overhang_area > super_overhang_area_threshold) - return true; + //if (super_overhang_area > super_overhang_area_threshold) + // return LargeOverhang; // 3. check overhang distance const double distance_threshold_scaled = extrusion_width_scaled * 2; @@ -2529,10 +2543,10 @@ bool PrintObject::is_support_necessary() }), exceed_overhang.end()); if (!exceed_overhang.empty()) - return true; + return LargeOverhang; } - return false; + return NoNeedSupp; } static void project_triangles_to_slabs(ConstLayerPtrsAdaptor layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector &out) diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 73acda3b4f..8c11723750 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -474,9 +474,7 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std if (layers[idx_layer]->slicing_errors) { buggy_layers.push_back(idx_layer); - //BBS - error_msg = L("Empty layers around bottom are replaced by nearest normal layers."); - } + } else break; // only detect empty layers near bed } @@ -484,14 +482,15 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - begin"; tbb::parallel_for( tbb::blocked_range(0, buggy_layers.size()), - [&layers, &throw_if_canceled, &buggy_layers](const tbb::blocked_range& range) { + [&layers, &throw_if_canceled, &buggy_layers, &error_msg](const tbb::blocked_range& range) { for (size_t buggy_layer_idx = range.begin(); buggy_layer_idx < range.end(); ++ buggy_layer_idx) { throw_if_canceled(); size_t idx_layer = buggy_layers[buggy_layer_idx]; - // BBS: only replace empty first layer - if (idx_layer > 0) + // BBS: only replace empty layers lower than 1mm + const coordf_t thresh_empty_layer_height = 1; + Layer* layer = layers[idx_layer]; + if (layer->print_z>= thresh_empty_layer_height) continue; - Layer *layer = layers[idx_layer]; assert(layer->slicing_errors); // Try to repair the layer surfaces by merging all contours and all holes from neighbor layers. // BOOST_LOG_TRIVIAL(trace) << "Attempting to repair layer" << idx_layer; @@ -500,42 +499,39 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std // Find the first valid layer below / above the current layer. const Surfaces *upper_surfaces = nullptr; const Surfaces *lower_surfaces = nullptr; - //BBS: only repair first layer if the 2nd layer is Good - for (size_t j = idx_layer + 1; j < /*layers.size()*/2; ++ j) - if (! layers[j]->slicing_errors) { + //BBS: only repair empty layers lowers than 1mm + for (size_t j = idx_layer + 1; j < layers.size(); ++j) { + if (!layers[j]->slicing_errors) { upper_surfaces = &layers[j]->regions()[region_id]->slices.surfaces; break; } - for (int j = /*int(idx_layer) -*/ 1; j >= 0; -- j) - if (! layers[j]->slicing_errors) { + if (layers[j]->print_z >= thresh_empty_layer_height) break; + } + for (int j = int(idx_layer) - 1; j >= 0; --j) { + if (layers[j]->print_z >= thresh_empty_layer_height) continue; + if (!layers[j]->slicing_errors) { lower_surfaces = &layers[j]->regions()[region_id]->slices.surfaces; break; } + } // Collect outer contours and holes from the valid layers above & below. - Polygons outer; - outer.reserve( + ExPolygons expolys; + expolys.reserve( ((upper_surfaces == nullptr) ? 0 : upper_surfaces->size()) + ((lower_surfaces == nullptr) ? 0 : lower_surfaces->size())); - size_t num_holes = 0; if (upper_surfaces) for (const auto &surface : *upper_surfaces) { - outer.push_back(surface.expolygon.contour); - num_holes += surface.expolygon.holes.size(); + expolys.emplace_back(surface.expolygon); } if (lower_surfaces) for (const auto &surface : *lower_surfaces) { - outer.push_back(surface.expolygon.contour); - num_holes += surface.expolygon.holes.size(); + expolys.emplace_back(surface.expolygon); } - Polygons holes; - holes.reserve(num_holes); - if (upper_surfaces) - for (const auto &surface : *upper_surfaces) - polygons_append(holes, surface.expolygon.holes); - if (lower_surfaces) - for (const auto &surface : *lower_surfaces) - polygons_append(holes, surface.expolygon.holes); - layerm->slices.set(diff_ex(union_(outer), holes), stInternal); + if (!expolys.empty()) { + //BBS + error_msg = L("Empty layers around bottom are replaced by nearest normal layers."); + layerm->slices.set(union_ex(expolys), stInternal); + } } // Update layer slices after repairing the single regions. layer->make_slices(); @@ -555,8 +551,7 @@ std::string fix_slicing_errors(PrintObject* object, LayerPtrs &layers, const std //BBS if(error_msg.empty() && !buggy_layers.empty()) - error_msg = L("The model has overlapping or self-intersecting facets. I tried to repair it, " - "however you might want to check the results or repair the input file and retry."); + error_msg = L("The model has too many empty layers."); return error_msg; } diff --git a/src/libslic3r/ProjectTask.hpp b/src/libslic3r/ProjectTask.hpp index 8d29f8ba22..8454acb025 100644 --- a/src/libslic3r/ProjectTask.hpp +++ b/src/libslic3r/ProjectTask.hpp @@ -51,6 +51,7 @@ public: { profile_ = profile; prediction = 0; + weight = 0.0f; } BBLSliceInfo(const BBLSliceInfo& obj) { diff --git a/src/libslic3r/Shape/TextShape.cpp b/src/libslic3r/Shape/TextShape.cpp new file mode 100644 index 0000000000..9185c1b018 --- /dev/null +++ b/src/libslic3r/Shape/TextShape.cpp @@ -0,0 +1,203 @@ +#include "../libslic3r.h" +#include "../Model.hpp" +#include "../TriangleMesh.hpp" + +#include "TextShape.hpp" + +#include +#include + +#include "Standard_TypeDef.hxx" +#include "STEPCAFControl_Reader.hxx" +#include "BRepMesh_IncrementalMesh.hxx" +#include "Interface_Static.hxx" +#include "XCAFDoc_DocumentTool.hxx" +#include "XCAFDoc_ShapeTool.hxx" +#include "XCAFApp_Application.hxx" +#include "TopoDS_Solid.hxx" +#include "TopoDS_Compound.hxx" +#include "TopoDS_Builder.hxx" +#include "TopoDS.hxx" +#include "TDataStd_Name.hxx" +#include "BRepBuilderAPI_Transform.hxx" +#include "TopExp_Explorer.hxx" +#include "TopExp_Explorer.hxx" +#include "BRep_Tool.hxx" +#include "Font_BRepFont.hxx" +#include "Font_BRepTextBuilder.hxx" +#include "BRepPrimAPI_MakePrism.hxx" +#include "Font_FontMgr.hxx" + +namespace Slic3r { + +std::vector init_occt_fonts() +{ + std::vector stdFontNames; + + Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance(); + aFontMgr->InitFontDataBase(); + + TColStd_SequenceOfHAsciiString availFontNames; + aFontMgr->GetAvailableFontsNames(availFontNames); + stdFontNames.reserve(availFontNames.Size()); + + for (auto afn : availFontNames) + stdFontNames.push_back(afn->ToCString()); + + return stdFontNames; +} + +static bool TextToBRep(const char* text, const char* font, const float theTextHeight, Font_FontAspect& theFontAspect, TopoDS_Shape& theShape) +{ + Standard_Integer anArgIt = 1; + Standard_CString aName = "text_shape"; + Standard_CString aText = text; + + Font_BRepFont aFont; + //TCollection_AsciiString aFontName("Courier"); + TCollection_AsciiString aFontName(font); + Standard_Real aTextHeight = theTextHeight; + Font_FontAspect aFontAspect = theFontAspect; + Standard_Boolean anIsCompositeCurve = Standard_False; + gp_Ax3 aPenAx3(gp::XOY()); + gp_Dir aNormal(0.0, 0.0, 1.0); + gp_Dir aDirection(1.0, 0.0, 0.0); + gp_Pnt aPenLoc; + + Graphic3d_HorizontalTextAlignment aHJustification = Graphic3d_HTA_LEFT; + Graphic3d_VerticalTextAlignment aVJustification = Graphic3d_VTA_BOTTOM; + Font_StrictLevel aStrictLevel = Font_StrictLevel_Any; + + aFont.SetCompositeCurveMode(anIsCompositeCurve); + if (!aFont.FindAndInit(aFontName.ToCString(), aFontAspect, aTextHeight, aStrictLevel)) + return false; + + aPenAx3 = gp_Ax3(aPenLoc, aNormal, aDirection); + + Font_BRepTextBuilder aBuilder; + theShape = aBuilder.Perform(aFont, aText, aPenAx3, aHJustification, aVJustification); + return true; +} + +static bool Prism(const TopoDS_Shape& theBase, const float thickness, TopoDS_Shape& theSolid) +{ + if (theBase.IsNull()) return false; + + gp_Vec V(0.f, 0.f, thickness); + BRepPrimAPI_MakePrism* Prism = new BRepPrimAPI_MakePrism(theBase, V, Standard_False); + + theSolid = Prism->Shape(); + return true; +} + +static void MakeMesh(TopoDS_Shape& theSolid, TriangleMesh& theMesh) +{ + const double STEP_TRANS_CHORD_ERROR = 0.005; + const double STEP_TRANS_ANGLE_RES = 1; + + BRepMesh_IncrementalMesh mesh(theSolid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); + int aNbNodes = 0; + int aNbTriangles = 0; + for (TopExp_Explorer anExpSF(theSolid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); + if (!aTriangulation.IsNull()) { + aNbNodes += aTriangulation->NbNodes(); + aNbTriangles += aTriangulation->NbTriangles(); + } + } + + stl_file stl; + stl.stats.type = inmemory; + stl.stats.number_of_facets = (uint32_t)aNbTriangles; + stl.stats.original_num_facets = stl.stats.number_of_facets; + stl_allocate(&stl); + + std::vector points; + points.reserve(aNbNodes); + //BBS: count faces missing triangulation + Standard_Integer aNbFacesNoTri = 0; + //BBS: fill temporary triangulation + Standard_Integer aNodeOffset = 0; + Standard_Integer aTriangleOffet = 0; + for (TopExp_Explorer anExpSF(theSolid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + const TopoDS_Shape& aFace = anExpSF.Current(); + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); + if (aTriangulation.IsNull()) { + ++aNbFacesNoTri; + continue; + } + //BBS: copy nodes + gp_Trsf aTrsf = aLoc.Transformation(); + for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { + gp_Pnt aPnt = aTriangulation->Node(aNodeIter); + aPnt.Transform(aTrsf); + points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + } + //BBS: copy triangles + const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); + for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { + Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); + + Standard_Integer anId[3]; + aTri.Get(anId[0], anId[1], anId[2]); + if (anOrientation == TopAbs_REVERSED) { + //BBS: swap 1, 2. + Standard_Integer aTmpIdx = anId[1]; + anId[1] = anId[2]; + anId[2] = aTmpIdx; + } + //BBS: Update nodes according to the offset. + anId[0] += aNodeOffset; + anId[1] += aNodeOffset; + anId[2] += aNodeOffset; + //BBS: save triangles facets + stl_facet facet; + facet.vertex[0] = points[anId[0] - 1].cast(); + facet.vertex[1] = points[anId[1] - 1].cast(); + facet.vertex[2] = points[anId[2] - 1].cast(); + facet.extra[0] = 0; + facet.extra[1] = 0; + stl_normal normal; + stl_calculate_normal(normal, &facet); + stl_normalize_vector(normal); + facet.normal = normal; + stl.facet_start[aTriangleOffet + aTriIter - 1] = facet; + } + + aNodeOffset += aTriangulation->NbNodes(); + aTriangleOffet += aTriangulation->NbTriangles(); + } + + theMesh.from_stl(stl); +} + +void load_text_shape(const char*text, const char* font, const float text_height, const float thickness, bool is_bold, bool is_italic, TriangleMesh& text_mesh) +{ + Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance(); + if (aFontMgr->GetAvailableFonts().IsEmpty()) + aFontMgr->InitFontDataBase(); + + TopoDS_Shape aTextBase; + Font_FontAspect aFontAspect = Font_FontAspect_UNDEFINED; + if (is_bold && is_italic) + aFontAspect = Font_FontAspect_BoldItalic; + else if (is_bold) + aFontAspect = Font_FontAspect_Bold; + else if (is_italic) + aFontAspect = Font_FontAspect_Italic; + else + aFontAspect = Font_FontAspect_Regular; + + if (!TextToBRep(text, font, text_height, aFontAspect, aTextBase)) + return; + + TopoDS_Shape aTextShape; + if (!Prism(aTextBase, thickness, aTextShape)) + return; + + MakeMesh(aTextShape, text_mesh); +} + +}; // namespace Slic3r diff --git a/src/libslic3r/Shape/TextShape.hpp b/src/libslic3r/Shape/TextShape.hpp new file mode 100644 index 0000000000..0da84bb957 --- /dev/null +++ b/src/libslic3r/Shape/TextShape.hpp @@ -0,0 +1,12 @@ +#ifndef slic3r_Text_Shape_hpp_ +#define slic3r_Text_Shape_hpp_ + +namespace Slic3r { +class TriangleMesh; + +extern std::vector init_occt_fonts(); +extern void load_text_shape(const char* text, const char* font, const float text_height, const float thickness, bool is_bold, bool is_italic, TriangleMesh& text_mesh); + +}; // namespace Slic3r + +#endif // slic3r_Text_Shape_hpp_ \ No newline at end of file diff --git a/src/libslic3r/ShortEdgeCollapse.cpp b/src/libslic3r/ShortEdgeCollapse.cpp new file mode 100644 index 0000000000..b36278c37f --- /dev/null +++ b/src/libslic3r/ShortEdgeCollapse.cpp @@ -0,0 +1,183 @@ +#include "ShortEdgeCollapse.hpp" +#include "libslic3r/NormalUtils.hpp" + +#include +#include +#include +#include + +namespace Slic3r { + +void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_count) { + // whenever vertex is removed, its mapping is update to the index of vertex with wich it merged + std::vector vertices_index_mapping(mesh.vertices.size()); + for (size_t idx = 0; idx < vertices_index_mapping.size(); ++idx) { + vertices_index_mapping[idx] = idx; + } + // Algorithm uses get_final_index query to get the actual vertex index. The query also updates all mappings on the way, essentially flattening the mapping + std::vector flatten_queue; + auto get_final_index = [&vertices_index_mapping, &flatten_queue](const size_t &orig_index) { + flatten_queue.clear(); + size_t idx = orig_index; + while (vertices_index_mapping[idx] != idx) { + flatten_queue.push_back(idx); + idx = vertices_index_mapping[idx]; + } + for (size_t i : flatten_queue) { + vertices_index_mapping[i] = idx; + } + return idx; + + }; + + // if face is removed, mark it here + std::vector face_removal_flags(mesh.indices.size(), false); + + std::vector triangles_neighbors = its_face_neighbors_par(mesh); + + // now compute vertices dot product - this is used during edge collapse, + // to determine which vertex to remove and which to keep; We try to keep the one with larger angle, because it defines the shape "more". + // The min vertex dot product is lowest dot product of its normal with the normals of faces around it. + // the lower the dot product, the more we want to keep the vertex + // NOTE: This score is not updated, even though the decimation does change the mesh. It saves computation time, and there are no strong reasons to update. + std::vector min_vertex_dot_product(mesh.vertices.size(), 1); + { + std::vector face_normals = its_face_normals(mesh); + std::vector vertex_normals = NormalUtils::create_normals(mesh); + + for (size_t face_idx = 0; face_idx < mesh.indices.size(); ++face_idx) { + Vec3i t = mesh.indices[face_idx]; + Vec3f n = face_normals[face_idx]; + min_vertex_dot_product[t[0]] = std::min(min_vertex_dot_product[t[0]], n.dot(vertex_normals[t[0]])); + min_vertex_dot_product[t[1]] = std::min(min_vertex_dot_product[t[1]], n.dot(vertex_normals[t[1]])); + min_vertex_dot_product[t[2]] = std::min(min_vertex_dot_product[t[2]], n.dot(vertex_normals[t[2]])); + } + } + + // lambda to remove face. It flags the face as removed, and updates neighbourhood info + auto remove_face = [&triangles_neighbors, &face_removal_flags](int face_idx, int other_face_idx) { + if (face_idx < 0) { + return; + } + face_removal_flags[face_idx] = true; + Vec3i neighbors = triangles_neighbors[face_idx]; + int n_a = neighbors[0] != other_face_idx ? neighbors[0] : neighbors[1]; + int n_b = neighbors[2] != other_face_idx ? neighbors[2] : neighbors[1]; + if (n_a > 0) + for (int &n : triangles_neighbors[n_a]) { + if (n == face_idx) { + n = n_b; + break; + } + } + if (n_b > 0) + for (int &n : triangles_neighbors[n_b]) { + if (n == face_idx) { + n = n_a; + break; + } + } + }; + + std::mt19937_64 generator { 27644437 };// default constant seed! so that results are deterministic + std::vector face_indices(mesh.indices.size()); + for (size_t idx = 0; idx < face_indices.size(); ++idx) { + face_indices[idx] = idx; + } + //tmp face indices used only for swapping + std::vector tmp_face_indices(mesh.indices.size()); + + float decimation_ratio = 1.0f; // decimation ratio updated in each iteration. it is number of removed triangles / number of all + float edge_len = 0.2f; // Allowed collapsible edge size. Starts low, but is gradually increased + + while (face_indices.size() > target_triangle_count) { + // simpple func to increase the edge len - if decimation ratio is low, it increases the len up to twice, if decimation ratio is high, increments are low + edge_len = edge_len * (1.0f + 1.0 - decimation_ratio); + float max_edge_len_squared = edge_len * edge_len; + + //shuffle the faces and traverse in random order, this MASSIVELY improves the quality of the result + std::shuffle(face_indices.begin(), face_indices.end(), generator); + + for (const size_t &face_idx : face_indices) { + if (face_removal_flags[face_idx]) { + // if face already removed from previous collapses, skip (each collapse removes two triangles [at least] ) + continue; + } + + // look at each edge if it is good candidate for collapse + for (size_t edge_idx = 0; edge_idx < 3; ++edge_idx) { + size_t vertex_index_keep = get_final_index(mesh.indices[face_idx][edge_idx]); + size_t vertex_index_remove = get_final_index(mesh.indices[face_idx][(edge_idx + 1) % 3]); + //check distance, skip long edges + if ((mesh.vertices[vertex_index_keep] - mesh.vertices[vertex_index_remove]).squaredNorm() + > max_edge_len_squared) { + continue; + } + // swap indexes if vertex_index_keep has higher dot product (we want to keep low dot product vertices) + if (min_vertex_dot_product[vertex_index_remove] < min_vertex_dot_product[vertex_index_keep]) { + size_t tmp = vertex_index_keep; + vertex_index_keep = vertex_index_remove; + vertex_index_remove = tmp; + } + + //remove vertex + { + // map its index to the index of the kept vertex + vertices_index_mapping[vertex_index_remove] = vertices_index_mapping[vertex_index_keep]; + } + + int neighbor_to_remove_face_idx = triangles_neighbors[face_idx][edge_idx]; + // remove faces + remove_face(face_idx, neighbor_to_remove_face_idx); + remove_face(neighbor_to_remove_face_idx, face_idx); + + // break. this triangle is done + break; + } + } + + // filter face_indices, remove those that have been collapsed + size_t prev_size = face_indices.size(); + tmp_face_indices.clear(); + for (size_t face_idx : face_indices) { + if (!face_removal_flags[face_idx]){ + tmp_face_indices.push_back(face_idx); + } + } + face_indices.swap(tmp_face_indices); + + decimation_ratio = float(prev_size - face_indices.size()) / float(prev_size); + //std::cout << " DECIMATION RATIO: " << decimation_ratio << std::endl; + } + + //Extract the result mesh + std::unordered_map final_vertices_mapping; + std::vector final_vertices; + std::vector final_indices; + final_indices.reserve(face_indices.size()); + for (size_t idx : face_indices) { + Vec3i final_face; + for (size_t i = 0; i < 3; ++i) { + final_face[i] = get_final_index(mesh.indices[idx][i]); + } + if (final_face[0] == final_face[1] || final_face[1] == final_face[2] || final_face[2] == final_face[0]) { + continue; // discard degenerate triangles + } + + for (size_t i = 0; i < 3; ++i) { + if (final_vertices_mapping.find(final_face[i]) == final_vertices_mapping.end()) { + final_vertices_mapping[final_face[i]] = final_vertices.size(); + final_vertices.push_back(mesh.vertices[final_face[i]]); + } + final_face[i] = final_vertices_mapping[final_face[i]]; + } + + final_indices.push_back(final_face); + } + + mesh.vertices = final_vertices; + mesh.indices = final_indices; +} + +} //namespace Slic3r + diff --git a/src/libslic3r/ShortEdgeCollapse.hpp b/src/libslic3r/ShortEdgeCollapse.hpp new file mode 100644 index 0000000000..e6f1822c89 --- /dev/null +++ b/src/libslic3r/ShortEdgeCollapse.hpp @@ -0,0 +1,16 @@ +#ifndef SRC_LIBSLIC3R_SHORTEDGECOLLAPSE_HPP_ +#define SRC_LIBSLIC3R_SHORTEDGECOLLAPSE_HPP_ + +#include "libslic3r/TriangleMesh.hpp" + +namespace Slic3r{ + +// Decimates the model by collapsing short edges. It starts with very small edges and gradually increases the collapsible length, +// until the target triangle count is reached (the algorithm will certainly undershoot the target count, result will have less triangles than target count) +// The algorithm does not check for triangle flipping, disconnections, self intersections or any other degeneration that can appear during mesh processing. +void its_short_edge_collpase(indexed_triangle_set &mesh, size_t target_triangle_count); + +} + + +#endif /* SRC_LIBSLIC3R_SHORTEDGECOLLAPSE_HPP_ */ diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index bbd641f0ae..69b250be22 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -1421,6 +1421,15 @@ void TreeSupport::generate_toolpaths() bool obj_is_vertical = obj_size.x() < obj_size.y(); int num_layers_to_change_infill_direction = int(HEIGHT_TO_SWITCH_INFILL_DIRECTION / object_config.layer_height.value); // change direction every 30mm + std::shared_ptr filler_interface = std::shared_ptr(Fill::new_from_type(m_support_params.contact_fill_pattern)); + std::shared_ptr filler_Roof1stLayer = std::shared_ptr(Fill::new_from_type(ipRectilinear)); + std::shared_ptr filler_support = std::shared_ptr(Fill::new_from_type(m_support_params.base_fill_pattern)); + filler_interface->set_bounding_box(bbox_object); + filler_Roof1stLayer->set_bounding_box(bbox_object); + filler_support->set_bounding_box(bbox_object); + filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value + 90.);//(1 - obj_is_vertical) * M_PI_2;//((1-obj_is_vertical) + int(layer_id / num_layers_to_change_infill_direction)) * M_PI_2;;//layer_id % 2 ? 0 : M_PI_2; + filler_Roof1stLayer->angle = Geometry::deg2rad(object_config.support_angle.value + 90.); + // generate tree support tool paths tbb::parallel_for( tbb::blocked_range(m_raft_layers, m_object->tree_support_layer_count()), @@ -1434,12 +1443,7 @@ void TreeSupport::generate_toolpaths() TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_id); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); - std::unique_ptr filler_interface = std::unique_ptr(Fill::new_from_type(m_support_params.contact_fill_pattern)); - std::unique_ptr filler_support = std::unique_ptr(Fill::new_from_type(m_support_params.base_fill_pattern)); - filler_interface->set_bounding_box(bbox_object); - filler_support->set_bounding_box(bbox_object); - filler_interface->angle = Geometry::deg2rad(object_config.support_angle.value + 90.);//(1 - obj_is_vertical) * M_PI_2;//((1-obj_is_vertical) + int(layer_id / num_layers_to_change_infill_direction)) * M_PI_2;;//layer_id % 2 ? 0 : M_PI_2; for (auto& area_group : ts_layer->area_groups) { ExPolygon& poly = *area_group.first; @@ -1465,9 +1469,9 @@ void TreeSupport::generate_toolpaths() // roof_1st_layer fill_params.density = interface_density; // Note: spacing means the separation between two lines as if they are tightly extruded - filler_interface->spacing = m_support_material_interface_flow.spacing(); - fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(polys), filler_interface.get(), fill_params, erSupportMaterial, - m_support_material_interface_flow); + filler_Roof1stLayer->spacing = m_support_material_interface_flow.spacing(); + fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(polys), filler_Roof1stLayer.get(), fill_params, erSupportMaterial, + m_support_material_interface_flow); } else if (area_group.second == TreeSupportLayer::FloorType) { // floor_areas fill_params.density = bottom_interface_density; @@ -2670,7 +2674,7 @@ void TreeSupport::adjust_layer_heights(std::vector>& contact_ for (int layer_nr = 1; layer_nr < contact_nodes.size(); layer_nr++) { std::vector& curr_layer_nodes = contact_nodes[layer_nr]; for (Node* node : curr_layer_nodes) { - if (node->support_roof_layers_below == top_intf_layers || node->support_floor_layers_above == bot_intf_layers) { + if (node->support_roof_layers_below >0 || node->support_floor_layers_above == bot_intf_layers) { extremes.push_back(layer_nr); break; } diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index e732cc177f..5fa3611192 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -9,7 +9,7 @@ #include "Execution/ExecutionTBB.hpp" #include "Execution/ExecutionSeq.hpp" #include "Utils.hpp" - +#include "Format/STL.hpp" #include #include #include @@ -208,10 +208,10 @@ bool TriangleMesh::from_stl(stl_file& stl, bool repair) return true; } -bool TriangleMesh::ReadSTLFile(const char* input_file, bool repair) +bool TriangleMesh::ReadSTLFile(const char* input_file, bool repair, ImportstlProgressFn stlFn) { stl_file stl; - if (! stl_open(&stl, input_file)) + if (! stl_open(&stl, input_file, stlFn)) return false; return from_stl(stl, repair); } diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 3ebd3105c8..79aac12cc6 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -10,7 +10,7 @@ #include "Point.hpp" #include "Polygon.hpp" #include "ExPolygon.hpp" - +#include "Format/STL.hpp" namespace Slic3r { class TriangleMesh; @@ -94,7 +94,7 @@ public: explicit TriangleMesh(indexed_triangle_set &&M, const RepairedMeshErrors& repaired_errors = RepairedMeshErrors()); void clear() { this->its.clear(); this->m_stats.clear(); } bool from_stl(stl_file& stl, bool repair = true); - bool ReadSTLFile(const char* input_file, bool repair = true); + bool ReadSTLFile(const char* input_file, bool repair = true, ImportstlProgressFn stlFn = nullptr); bool write_ascii(const char* output_file); bool write_binary(const char* output_file); float volume(); @@ -152,10 +152,14 @@ public: const TriangleMeshStats& stats() const { return m_stats; } + void set_init_shift(const Vec3d &offset) { m_init_shift = offset; } + Vec3d get_init_shift() const { return m_init_shift; } + indexed_triangle_set its; private: TriangleMeshStats m_stats; + Vec3d m_init_shift {0.0, 0.0, 0.0}; }; // Index of face indices incident with a vertex index. diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index 0e31d9b2ef..0ac985fdf4 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -1427,7 +1427,7 @@ void TriangleSelector::get_facets(std::vector& facets_per_ { facets_per_type.clear(); - for (int type = (int)EnforcerBlockerType::NONE; type < (int)EnforcerBlockerType::Extruder15; type++) { + for (int type = (int)EnforcerBlockerType::NONE; type <= (int)EnforcerBlockerType::ExtruderMax; type++) { facets_per_type.emplace_back(); indexed_triangle_set& its = facets_per_type.back(); std::vector vertex_map(m_vertices.size(), -1); diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 645a63aefe..39ede77b35 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -7,12 +7,10 @@ #include #include "Point.hpp" #include "TriangleMesh.hpp" +#include "libslic3r/Model.hpp" namespace Slic3r { -enum class EnforcerBlockerType : int8_t; - - // Following class holds information about selected triangles. It also has power // to recursively subdivide the triangles and make the selection finer. class TriangleSelector @@ -275,7 +273,7 @@ public: std::pair>, std::vector> serialize() const; // Load serialized data. Assumes that correct mesh is loaded. - void deserialize(const std::pair>, std::vector>& data, bool needs_reset = true, EnforcerBlockerType max_ebt = (EnforcerBlockerType)std::numeric_limits::max()); + void deserialize(const std::pair>, std::vector>& data, bool needs_reset = true, EnforcerBlockerType max_ebt = EnforcerBlockerType::ExtruderMax); // For all triangles, remove the flag indicating that the triangle was selected by seed fill. void seed_fill_unselect_all_triangles(); @@ -312,7 +310,7 @@ protected: void set_division(int sides_to_split, int special_side_idx); // Get/set current state. - void set_state(EnforcerBlockerType type) { assert(! is_split()); state = type; } + void set_state(EnforcerBlockerType type) { assert(!is_split()); state = type; } EnforcerBlockerType get_state() const { assert(! is_split()); return state; } // Set if the triangle has been selected or unselected by seed fill. diff --git a/src/libslic3r/TriangleSetSampling.cpp b/src/libslic3r/TriangleSetSampling.cpp new file mode 100644 index 0000000000..bb03ff6d75 --- /dev/null +++ b/src/libslic3r/TriangleSetSampling.cpp @@ -0,0 +1,71 @@ +#include "TriangleSetSampling.hpp" +#include +#include +#include +#include + +namespace Slic3r { + +TriangleSetSamples sample_its_uniform_parallel(size_t samples_count, const indexed_triangle_set &triangle_set) { + std::vector triangles_area(triangle_set.indices.size()); + + tbb::parallel_for(tbb::blocked_range(0, triangle_set.indices.size()), + [&triangle_set, &triangles_area]( + tbb::blocked_range r) { + for (size_t t_idx = r.begin(); t_idx < r.end(); ++t_idx) { + const Vec3f &a = triangle_set.vertices[triangle_set.indices[t_idx].x()]; + const Vec3f &b = triangle_set.vertices[triangle_set.indices[t_idx].y()]; + const Vec3f &c = triangle_set.vertices[triangle_set.indices[t_idx].z()]; + double area = double(0.5 * (b - a).cross(c - a).norm()); + triangles_area[t_idx] = area; + } + }); + + std::map area_sum_to_triangle_idx; + float area_sum = 0; + for (size_t t_idx = 0; t_idx < triangles_area.size(); ++t_idx) { + area_sum += triangles_area[t_idx]; + area_sum_to_triangle_idx[area_sum] = t_idx; + } + + std::mt19937_64 mersenne_engine { 27644437 }; + // random numbers on interval [0, 1) + std::uniform_real_distribution fdistribution; + + auto get_random = [&fdistribution, &mersenne_engine]() { + return Vec3d { fdistribution(mersenne_engine), fdistribution(mersenne_engine), fdistribution(mersenne_engine) }; + }; + + std::vector random_samples(samples_count); + std::generate(random_samples.begin(), random_samples.end(), get_random); + + TriangleSetSamples result; + result.total_area = area_sum; + result.positions.resize(samples_count); + result.normals.resize(samples_count); + result.triangle_indices.resize(samples_count); + + tbb::parallel_for(tbb::blocked_range(0, samples_count), + [&triangle_set, &area_sum_to_triangle_idx, &area_sum, &random_samples, &result]( + tbb::blocked_range r) { + for (size_t s_idx = r.begin(); s_idx < r.end(); ++s_idx) { + double t_sample = random_samples[s_idx].x() * area_sum; + size_t t_idx = area_sum_to_triangle_idx.upper_bound(t_sample)->second; + + double sq_u = std::sqrt(random_samples[s_idx].y()); + double v = random_samples[s_idx].z(); + + Vec3f A = triangle_set.vertices[triangle_set.indices[t_idx].x()]; + Vec3f B = triangle_set.vertices[triangle_set.indices[t_idx].y()]; + Vec3f C = triangle_set.vertices[triangle_set.indices[t_idx].z()]; + + result.positions[s_idx] = A * (1 - sq_u) + B * (sq_u * (1 - v)) + C * (v * sq_u); + result.normals[s_idx] = ((B - A).cross(C - B)).normalized(); + result.triangle_indices[s_idx] = t_idx; + } + }); + + return result; +} + +} diff --git a/src/libslic3r/TriangleSetSampling.hpp b/src/libslic3r/TriangleSetSampling.hpp new file mode 100644 index 0000000000..28a661d76f --- /dev/null +++ b/src/libslic3r/TriangleSetSampling.hpp @@ -0,0 +1,20 @@ +#ifndef SRC_LIBSLIC3R_TRIANGLESETSAMPLING_HPP_ +#define SRC_LIBSLIC3R_TRIANGLESETSAMPLING_HPP_ + +#include +#include "libslic3r/Point.hpp" + +namespace Slic3r { + +struct TriangleSetSamples { + float total_area; + std::vector positions; + std::vector normals; + std::vector triangle_indices; +}; + +TriangleSetSamples sample_its_uniform_parallel(size_t samples_count, const indexed_triangle_set &triangle_set); + +} + +#endif /* SRC_LIBSLIC3R_TRIANGLESETSAMPLING_HPP_ */ diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 485cd0a05a..44281c5920 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -283,6 +283,7 @@ inline typename CONTAINER_TYPE::value_type& next_value_modulo(typename CONTAINER } extern std::string xml_escape(std::string text, bool is_marked = false); +extern std::string xml_unescape(std::string text); #if defined __GNUC__ && __GNUC__ < 5 && !defined __clang__ diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h index 63b0422907..44d5de1305 100644 --- a/src/libslic3r/libslic3r.h +++ b/src/libslic3r/libslic3r.h @@ -24,6 +24,13 @@ #include #include +#ifdef _WIN32 +// On MSVC, std::deque degenerates to a list of pointers, which defeats its purpose of reducing allocator load and memory fragmentation. +// https://github.com/microsoft/STL/issues/147#issuecomment-1090148740 +// Thus it is recommended to use boost::container::deque instead. +#include +#endif // _WIN32 + #include "Technologies.hpp" #include "Semver.hpp" @@ -96,6 +103,16 @@ namespace Slic3r { extern Semver SEMVER; +// On MSVC, std::deque degenerates to a list of pointers, which defeats its purpose of reducing allocator load and memory fragmentation. +template> +using deque = +#ifdef _WIN32 + // Use boost implementation, which allocates blocks of 512 bytes instead of blocks of 8 bytes. + boost::container::deque; +#else // _WIN32 + std::deque; +#endif // _WIN32 + template inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); } @@ -341,6 +358,12 @@ public: inline bool empty() const { return size() == 0; } }; +template> +constexpr T NaN = std::numeric_limits::quiet_NaN(); + +constexpr float NaNf = NaN; +constexpr double NaNd = NaN; + } // namespace Slic3r #endif diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 6cf8b1265a..0e1565117e 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -1182,6 +1182,42 @@ std::string xml_escape(std::string text, bool is_marked/* = false*/) return text; } +std::string xml_unescape(std::string s) +{ + std::string ret; + std::string::size_type i = 0; + std::string::size_type pos = 0; + while (i < s.size()) { + std::string rep; + if (s[i] == '&') { + if (s.substr(i, 4) == "<") { + ret += s.substr(pos, i - pos) + "<"; + i += 4; + pos = i; + } + else if (s.substr(i, 4) == ">") { + ret += s.substr(pos, i - pos) + ">"; + i += 4; + pos = i; + } + else if (s.substr(i, 5) == "&") { + ret += s.substr(pos, i - pos) + "&"; + i += 5; + pos = i; + } + else { + ++i; + } + } + else { + ++i; + } + } + + ret += s.substr(pos); + return ret; +} + std::string format_memsize_MB(size_t n) { std::string out; diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index b112e58924..e16d83172f 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -68,8 +68,8 @@ set(SLIC3R_GUI_SOURCES GUI/Widgets/SideTools.hpp GUI/Widgets/WebView.cpp GUI/Widgets/WebView.hpp - GUI/Widgets/wxStaticText2.cpp - GUI/Widgets/wxStaticText2.hpp + GUI/Widgets/ErrorMsgStaticText.cpp + GUI/Widgets/ErrorMsgStaticText.hpp GUI/AboutDialog.cpp GUI/AboutDialog.hpp GUI/NetworkTestDialog.cpp @@ -129,6 +129,8 @@ set(SLIC3R_GUI_SOURCES GUI/Gizmos/GLGizmoFaceDetector.hpp GUI/Gizmos/GLGizmoSeam.cpp GUI/Gizmos/GLGizmoSeam.hpp + GUI/Gizmos/GLGizmoText.cpp + GUI/Gizmos/GLGizmoText.hpp GUI/GLSelectionRectangle.cpp GUI/GLSelectionRectangle.hpp GUI/Gizmos/GizmoObjectManipulation.cpp diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e5d9cc2467..8f48579a45 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -434,6 +434,7 @@ GLVolume::GLVolume(float r, float g, float b, float a) , zoom_to_volumes(true) , shader_outside_printer_detection_enabled(false) , is_outside(false) + , partly_inside(false) , hover(HS_None) , is_modifier(false) , is_wipe_tower(false) @@ -679,7 +680,7 @@ void GLVolume::render(bool with_outline) const bool color_volume = false; ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects; do { - if (object_idx() >= model_objects.size()) + if ((!printable) || object_idx() >= model_objects.size()) break; ModelObject* mo = model_objects[object_idx()]; @@ -907,7 +908,7 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj ModelObject* model_object = nullptr; ModelVolume* model_volume = nullptr; do { - if (object_idx() >= model_objects.size()) + if ((!printable) || object_idx() >= model_objects.size()) break; model_object = model_objects[object_idx()]; @@ -1290,9 +1291,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab //shader->set_uniform("print_volume.xy_data", m_render_volume.data); //shader->set_uniform("print_volume.z_data", m_render_volume.zs); - /*shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); - shader->set_uniform("print_volume.xy_data", m_print_volume.data); - shader->set_uniform("print_volume.z_data", m_print_volume.zs);*/ + if (volume.first->partly_inside) { + //only partly inside volume need to be painted with boundary check + shader->set_uniform("print_volume.type", static_cast(m_print_volume.type)); + shader->set_uniform("print_volume.xy_data", m_print_volume.data); + shader->set_uniform("print_volume.z_data", m_print_volume.zs); + } + else { + //use -1 ad a invalid type + shader->set_uniform("print_volume.type", -1); + } shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.active && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); @@ -1378,6 +1386,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo const std::vector& exclude_areas = curr_plate->get_exclude_areas(); for (GLVolume* volume : this->volumes) + { if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) { BuildVolume::ObjectState state; const BoundingBoxf3& bb = volume_bbox(*volume); @@ -1405,6 +1414,7 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id); volume->is_outside = state != BuildVolume::ObjectState::Inside; + //volume->partly_inside = (state == BuildVolume::ObjectState::Colliding); if (volume->printable) { if (overall_state == ModelInstancePVS_Inside && volume->is_outside) { overall_state = ModelInstancePVS_Fully_Outside; @@ -1448,6 +1458,23 @@ bool GLVolumeCollection::check_outside_state(const BuildVolume &build_volume, Mo BOOST_LOG_TRIVIAL(debug) << "instance includes " << volume->name << " is partially outside of bed"; } } + } + + for (GLVolume* volume : this->volumes) + { + if (! volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (! volume->is_wipe_tower && volume->composite_id.volume_id >= 0))) + { + int64_t comp_id = ((int64_t)volume->composite_id.object_id << 32) | ((int64_t)volume->composite_id.instance_id); + if (model_state.find(comp_id) != model_state.end()) + { + if (model_state[comp_id] == ModelInstancePVS_Partly_Outside) { + volume->partly_inside = true; + } + else + volume->partly_inside = false; + } + } + } if (out_state != nullptr) *out_state = overall_state; @@ -1459,8 +1486,10 @@ void GLVolumeCollection::reset_outside_state() { for (GLVolume* volume : this->volumes) { - if (volume != nullptr) + if (volume != nullptr) { volume->is_outside = false; + volume->partly_inside = false; + } } } diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 2eaf09ed83..b1ad7671de 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -371,6 +371,7 @@ public: bool shader_outside_printer_detection_enabled : 1; // Wheter or not this volume is outside print volume. bool is_outside : 1; + bool partly_inside : 1; // Wheter or not this volume has been generated from a modifier bool is_modifier : 1; // Wheter or not this volume has been generated from the wipe tower diff --git a/src/slic3r/GUI/AMSSetting.cpp b/src/slic3r/GUI/AMSSetting.cpp index 15d8deefd7..28f7624e60 100644 --- a/src/slic3r/GUI/AMSSetting.cpp +++ b/src/slic3r/GUI/AMSSetting.cpp @@ -188,10 +188,6 @@ void AMSSetting::create() m_sizer_main->Fit(this); this->Centre(wxBOTH); - - // set mode - update_insert_material_read_mode(true); - update_starting_read_mode(false); } void AMSSetting::update_insert_material_read_mode(bool selected) diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp index 13886fb9ee..d24338c9d0 100644 --- a/src/slic3r/GUI/AmsMappingPopup.cpp +++ b/src/slic3r/GUI/AmsMappingPopup.cpp @@ -393,7 +393,7 @@ void AmsMapingPopup::add_ams_mapping(std::vector tray_data) sizer_mapping_item->Add(number, 0, wxALIGN_CENTER_HORIZONTAL, 0); sizer_mapping_item->Add(m_filament_name, 0, wxALIGN_CENTER_HORIZONTAL, 0); - sizer_mapping_list->Add(sizer_mapping_item, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(5)); + sizer_mapping_list->Add(sizer_mapping_item, 0, wxALL, FromDIP(5)); m_amsmapping_sizer_list.push_back(sizer_mapping_list); } m_sizer_list->Add(sizer_mapping_list, 0, wxALIGN_CENTER_HORIZONTAL, 0); @@ -514,4 +514,101 @@ void MappingItem::doRender(wxDC &dc) } } +AmsMapingTipPopup::AmsMapingTipPopup(wxWindow *parent) + :wxPopupTransientWindow(parent, wxBORDER_NONE) +{ + SetBackgroundColour(*wxWHITE); + wxBoxSizer *m_sizer_main = new wxBoxSizer(wxVERTICAL); + + m_sizer_main->Add(0, 0, 1, wxTOP, FromDIP(28)); + + wxBoxSizer *m_sizer_body = new wxBoxSizer(wxHORIZONTAL); + + m_sizer_body->Add(0, 0, 0, wxEXPAND | wxLEFT, FromDIP(20)); + + m_panel_enable_ams = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(200, -1), wxTAB_TRAVERSAL); + m_panel_enable_ams->SetBackgroundColour(*wxWHITE); + wxBoxSizer *sizer_enable_ams = new wxBoxSizer(wxVERTICAL); + + m_title_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Enable AMS"), wxDefaultPosition, wxDefaultSize, 0); + m_title_enable_ams->SetBackgroundColour(*wxWHITE); + m_title_enable_ams->Wrap(-1); + sizer_enable_ams->Add(m_title_enable_ams, 0, 0, 0); + + m_tip_enable_ams = new wxStaticText(m_panel_enable_ams, wxID_ANY, _L("Print with filaments in the AMS"), wxDefaultPosition, wxDefaultSize, 0); + m_tip_enable_ams->SetBackgroundColour(*wxWHITE); + m_tip_enable_ams->Wrap(-1); + sizer_enable_ams->Add(m_tip_enable_ams, 0, wxTOP, 8); + + wxBoxSizer *sizer_enable_ams_img; + sizer_enable_ams_img = new wxBoxSizer(wxVERTICAL); + + auto img_enable_ams = new wxStaticBitmap(m_panel_enable_ams, wxID_ANY, create_scaled_bitmap("monitor_upgrade_ams", this, 108), wxDefaultPosition, + wxSize(FromDIP(118), FromDIP(108)), 0); + sizer_enable_ams_img->Add(img_enable_ams, 0, wxALIGN_CENTER_HORIZONTAL, 0); + + sizer_enable_ams->Add(sizer_enable_ams_img, 1, wxEXPAND | wxTOP, FromDIP(20)); + + m_panel_enable_ams->SetSizer(sizer_enable_ams); + m_panel_enable_ams->Layout(); + m_sizer_body->Add(m_panel_enable_ams, 0, 0, 0); + + m_split_lines = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1, FromDIP(150)), wxTAB_TRAVERSAL); + m_split_lines->SetBackgroundColour(wxColour(238, 238, 238)); + + m_sizer_body->Add(m_split_lines, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, FromDIP(10)); + + m_panel_disable_ams = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(200, -1), wxTAB_TRAVERSAL); + m_panel_disable_ams->SetBackgroundColour(*wxWHITE); + wxBoxSizer *sizer_disable_ams; + sizer_disable_ams = new wxBoxSizer(wxVERTICAL); + + m_title_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Disable AMS"), wxDefaultPosition, wxDefaultSize, 0); + m_title_disable_ams->SetBackgroundColour(*wxWHITE); + m_title_disable_ams->Wrap(-1); + sizer_disable_ams->Add(m_title_disable_ams, 0, 0, 0); + + m_tip_disable_ams = new wxStaticText(m_panel_disable_ams, wxID_ANY, _L("Print with the filament mounted on the back of chassis"), wxDefaultPosition, wxDefaultSize, 0); + m_tip_disable_ams->SetBackgroundColour(*wxWHITE); + m_tip_disable_ams->Wrap(-1); + sizer_disable_ams->Add(m_tip_disable_ams, 0, wxTOP, FromDIP(8)); + + wxBoxSizer *sizer_disable_ams_img; + sizer_disable_ams_img = new wxBoxSizer(wxVERTICAL); + + auto img_disable_ams = new wxStaticBitmap(m_panel_disable_ams, wxID_ANY, create_scaled_bitmap("disable_ams_demo_icon", this, 95), wxDefaultPosition, + wxSize(FromDIP(95), FromDIP(109)), 0); + sizer_disable_ams_img->Add(img_disable_ams, 0, wxALIGN_CENTER_HORIZONTAL, 0); + + sizer_disable_ams->Add(sizer_disable_ams_img, 1, wxEXPAND | wxTOP, FromDIP(20)); + + m_panel_disable_ams->SetSizer(sizer_disable_ams); + m_panel_disable_ams->Layout(); + m_sizer_body->Add(m_panel_disable_ams, 0, 0, 0); + + m_sizer_body->Add(0, 0, 0, wxEXPAND | wxRIGHT, FromDIP(20)); + + m_sizer_main->Add(m_sizer_body, 0, wxEXPAND, 0); + + m_sizer_main->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(28)); + + this->SetSizer(m_sizer_main); + this->Layout(); + this->Fit(); + Bind(wxEVT_PAINT, &AmsMapingTipPopup::paintEvent, this); +} + +void AmsMapingTipPopup::paintEvent(wxPaintEvent &evt) +{ + wxPaintDC dc(this); + dc.SetPen(wxColour(0xAC, 0xAC, 0xAC)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); +} + +void AmsMapingTipPopup::OnDismiss() {} + +bool AmsMapingTipPopup::ProcessLeftDown(wxMouseEvent &event) { + return wxPopupTransientWindow::ProcessLeftDown(event); } + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/AmsMappingPopup.hpp b/src/slic3r/GUI/AmsMappingPopup.hpp index 450b1bf9eb..a81883d193 100644 --- a/src/slic3r/GUI/AmsMappingPopup.hpp +++ b/src/slic3r/GUI/AmsMappingPopup.hpp @@ -137,6 +137,27 @@ public: void paintEvent(wxPaintEvent &evt); }; +class AmsMapingTipPopup : public wxPopupTransientWindow +{ +public: + AmsMapingTipPopup(wxWindow *parent); + ~AmsMapingTipPopup(){}; + void paintEvent(wxPaintEvent &evt); + + virtual void OnDismiss() wxOVERRIDE; + virtual bool ProcessLeftDown(wxMouseEvent &event) wxOVERRIDE; + +public: + wxPanel * m_panel_enable_ams; + wxStaticText * m_title_enable_ams; + wxStaticText * m_tip_enable_ams; + wxPanel * m_split_lines; + wxPanel * m_panel_disable_ams; + wxStaticText * m_title_disable_ams; + wxStaticText * m_tip_disable_ams; +}; + + wxDECLARE_EVENT(EVT_SET_FINISH_MAPPING, wxCommandEvent); }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Auxiliary.cpp b/src/slic3r/GUI/Auxiliary.cpp index 73d5baa94b..e7756fd350 100644 --- a/src/slic3r/GUI/Auxiliary.cpp +++ b/src/slic3r/GUI/Auxiliary.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include "wxExtensions.hpp" @@ -44,18 +46,17 @@ const std::vector license_list = { AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) { - wxPanel::Create(parent, id, pos, wxSize(FromDIP(300), FromDIP(340)), style); - SetBackgroundColour(AUFILE_GREY300); - wxBoxSizer *sizer_body = new wxBoxSizer(wxVERTICAL); - - SetSize(wxSize(FromDIP(300), FromDIP(340))); - SetMinSize(wxSize(FromDIP(300), FromDIP(340))); - SetMaxSize(wxSize(FromDIP(300), FromDIP(340))); - m_type = type; m_file_path = file_path; m_file_name = file_name; + wxSize panel_size = m_type == MODEL_PICTURE ? AUFILE_PICTURES_PANEL_SIZE : AUFILE_PANEL_SIZE; + wxPanel::Create(parent, id, pos, panel_size, style); + SetBackgroundColour(AUFILE_GREY300); + wxBoxSizer *sizer_body = new wxBoxSizer(wxVERTICAL); + + SetSize(panel_size); + if (m_type == MODEL_PICTURE) { if (m_file_path.empty()) { return; } auto image = new wxImage(encode_path(m_file_path.string().c_str())); @@ -64,19 +65,19 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia auto size = wxSize(0, 0); float proportion = float(image->GetSize().x) / float(image->GetSize().y); if (proportion >= 1) { - size.x = FromDIP(300); - size.y = FromDIP(300) / proportion; + size.x = AUFILE_PICTURES_SIZE.x; + size.y = AUFILE_PICTURES_SIZE.x / proportion; } else { - size.y = FromDIP(300); - size.x = FromDIP(300) * proportion; + size.y = AUFILE_PICTURES_SIZE.y; + size.x = AUFILE_PICTURES_SIZE.y * proportion; } image->Rescale(size.x, size.y); - m_file_bitmap = wxBitmap(*image); + m_file_bitmap.bmp() = wxBitmap(*image); } else { - m_bitmap_excel = create_scaled_bitmap("placeholder_excel", nullptr, 300); - m_bitmap_pdf = create_scaled_bitmap("placeholder_pdf", nullptr, 300); - m_bitmap_txt = create_scaled_bitmap("placeholder_txt", nullptr, 300); + m_bitmap_excel = ScalableBitmap(this, "placeholder_excel", 168); + m_bitmap_pdf = ScalableBitmap(this, "placeholder_pdf", 168); + m_bitmap_txt = ScalableBitmap(this, "placeholder_txt", 168); if (m_type == OTHERS) {m_file_bitmap = m_bitmap_txt;} if (m_type == BILL_OF_MATERIALS) { @@ -90,6 +91,7 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia if (m_type == ASSEMBLY_GUIDE) {m_file_bitmap = m_bitmap_pdf;} } + m_add_file = _L("Add File"); cover_text_left = _L("Set as cover"); cover_text_right = _L("Rename"); cover_text_cover = _L("Cover"); @@ -98,15 +100,15 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia m_file_edit_mask = ScalableBitmap(this, "auxiliary_edit_mask", 43); m_file_delete = ScalableBitmap(this, "auxiliary_delete", 28); - auto m_text_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(40)), wxTAB_TRAVERSAL); + auto m_text_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(panel_size.x, AUFILE_TEXT_HEIGHT), wxTAB_TRAVERSAL); m_text_panel->SetBackgroundColour(AUFILE_GREY300); wxBoxSizer *m_text_sizer = new wxBoxSizer(wxVERTICAL); - m_text_name = new wxStaticText(m_text_panel, wxID_ANY, m_file_name, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(20)), 0); - m_text_name->Wrap(FromDIP(290)); + m_text_name = new wxStaticText(m_text_panel, wxID_ANY, m_file_name, wxDefaultPosition, wxSize(panel_size.x, -1), wxST_ELLIPSIZE_END); + m_text_name->Wrap(panel_size.x - FromDIP(10)); m_text_name->SetFont(::Label::Body_14); - m_input_name = new ::TextInput(m_text_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(35)), wxTE_PROCESS_ENTER); + m_input_name = new ::TextInput(m_text_panel, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(panel_size.x, FromDIP(35)), wxTE_PROCESS_ENTER); m_input_name->GetTextCtrl()->SetFont(::Label::Body_13); m_input_name->SetFont(::Label::Body_14); m_input_name->Hide(); @@ -117,7 +119,7 @@ AuFile::AuFile(wxWindow *parent, fs::path file_path, wxString file_name, Auxilia m_text_panel->SetSizer(m_text_sizer); m_text_panel->Layout(); - sizer_body->Add(0, 0, 0, wxTOP, FromDIP(300)); + sizer_body->Add(0, 0, 0, wxTOP, panel_size.y - AUFILE_TEXT_HEIGHT); sizer_body->Add(m_text_panel, 0, wxALIGN_CENTER, 0); SetSizer(sizer_body); @@ -149,12 +151,26 @@ void AuFile::exit_rename_mode() void AuFile::OnPaint(wxPaintEvent &event) { - //wxPaintDC dc(this); - //render(dc); - wxBufferedPaintDC dc(this); - PrepareDC(dc); + wxPaintDC dc(this); +#ifdef __WXMSW__ + wxSize size = GetSize(); + wxMemoryDC memdc; + wxBitmap bmp(size.x, size.y); + memdc.SelectObject(bmp); + memdc.Blit({ 0, 0 }, size, &dc, { 0, 0 }); + + { + wxGCDC dc2(memdc); + PaintBackground(dc2); + PaintForeground(dc2); + } + + memdc.SelectObject(wxNullBitmap); + dc.DrawBitmap(bmp, 0, 0); +#else PaintBackground(dc); PaintForeground(dc); +#endif } void AuFile::PaintBackground(wxDC &dc) @@ -169,21 +185,66 @@ void AuFile::PaintBackground(wxDC &dc) dc.DrawRectangle(windowRect); - wxSize size = wxSize(FromDIP(300), FromDIP(300)); - dc.SetPen(AUFILE_GREY200); - dc.SetBrush(AUFILE_GREY200); - dc.DrawRectangle(0,0,size.x,size.y); - dc.DrawBitmap(m_file_bitmap, (size.x - m_file_bitmap.GetSize().x) / 2, (size.y - m_file_bitmap.GetSize().y) / 2); + wxSize size = m_type == MODEL_PICTURE ? AUFILE_PICTURES_SIZE : AUFILE_SIZE; + + if (m_type == AddFileButton) + { + auto pen_width = FromDIP(2); + dc.SetPen(wxPen(AUFILE_GREY500, pen_width)); + dc.SetBrush(AUFILE_GREY200); + dc.DrawRoundedRectangle(pen_width / 2, pen_width / 2, size.x - pen_width / 2, size.y - pen_width / 2, AUFILE_ROUNDING); + + auto line_length = FromDIP(50); + dc.DrawLine(wxPoint((size.x - line_length) / 2, size.y / 2), wxPoint((size.x + line_length) / 2, size.y / 2)); + dc.DrawLine(wxPoint(size.x / 2, (size.y - line_length) / 2), wxPoint(size.x / 2, (size.y + line_length) / 2)); + + dc.SetFont(Label::Body_16); + auto sizet = dc.GetTextExtent(m_add_file); + auto pos = wxPoint(0, 0); + pos.x = (size.x - sizet.x) / 2; + pos.y = (size.y - 40); // to modify + dc.SetTextForeground(AUFILE_GREY500); + dc.DrawText(m_add_file, pos); + } + else { + dc.SetPen(AUFILE_GREY200); + dc.SetBrush(AUFILE_GREY200); + dc.DrawRoundedRectangle(0, 0, size.x, size.y, AUFILE_ROUNDING); + dc.DrawBitmap(m_file_bitmap.bmp(), (size.x - m_file_bitmap.GetBmpWidth()) / 2, (size.y - m_file_bitmap.GetBmpHeight()) / 2); + } } void AuFile::OnEraseBackground(wxEraseEvent &evt) {} void AuFile::PaintForeground(wxDC &dc) { - wxSize size = wxSize(FromDIP(300), FromDIP(300)); + wxSize size = m_type == MODEL_PICTURE ? AUFILE_PICTURES_SIZE : AUFILE_SIZE; if (m_hover) { - dc.DrawBitmap(m_file_edit_mask.bmp(), 0, size.y - m_file_edit_mask.GetBmpSize().y); + if (m_type == AddFileButton) { + auto pen_width = FromDIP(2); + dc.SetPen(wxPen(AUFILE_BRAND, pen_width)); + dc.SetBrush(AUFILE_BRAND_TRANSPARENT); + dc.DrawRoundedRectangle(pen_width / 2, pen_width / 2, size.x - pen_width / 2, size.y - pen_width / 2, AUFILE_ROUNDING); + + auto line_length = FromDIP(50); + dc.DrawLine(wxPoint((size.x - line_length) / 2, size.y / 2), wxPoint((size.x + line_length) / 2, size.y / 2)); + dc.DrawLine(wxPoint(size.x / 2, (size.y - line_length) / 2), wxPoint(size.x / 2, (size.y + line_length) / 2)); + + auto sizet = dc.GetTextExtent(m_add_file); + auto pos = wxPoint(0, 0); + pos.x = (size.x - sizet.x) / 2; + pos.y = (size.y - 40); // to modify + dc.SetTextForeground(AUFILE_BRAND); + dc.DrawText(m_add_file, pos); + return; + } + + if (m_type == MODEL_PICTURE) { + dc.DrawBitmap(m_file_edit_mask.bmp(), 0, size.y - m_file_edit_mask.GetBmpSize().y); + } + + dc.SetFont(Label::Body_14); dc.SetTextForeground(*wxWHITE); if (m_type == MODEL_PICTURE) { @@ -210,11 +271,11 @@ void AuFile::PaintForeground(wxDC &dc) dc.DrawRectangle(pos.x, pos.y, 2, FromDIP(30)); } else { // right text - auto sizet = dc.GetTextExtent(cover_text_right); + /* auto sizet = dc.GetTextExtent(cover_text_right); auto pos = wxPoint(0, 0); - pos.x = (size.x - sizet.x) / 2; - pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2); - dc.DrawText(cover_text_right, pos); + pos.x = (size.x - sizet.x) / 2; + pos.y = (size.y - (m_file_edit_mask.GetBmpSize().y + sizet.y) / 2); + dc.DrawText(cover_text_right, pos);*/ } } @@ -246,7 +307,7 @@ void AuFile::on_mouse_leave(wxMouseEvent &evt) void AuFile::on_input_enter(wxCommandEvent &evt) { - auto new_file_name = into_u8(m_input_name->GetTextCtrl()->GetValue()); + auto new_file_name = m_input_name->GetTextCtrl()->GetValue(); auto m_valid_type = Valid; wxString info_line; @@ -271,7 +332,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt) auto new_fullname = new_file_name + m_file_path.extension().string(); - auto new_fullname_path = dir.string() + "/" + new_fullname; + wxString new_fullname_path = dir.wstring() + "/" + new_fullname; fs::path new_dir_path(new_fullname_path.c_str()); @@ -314,7 +375,7 @@ void AuFile::on_input_enter(wxCommandEvent &evt) // post event auto event = wxCommandEvent(EVT_AUXILIARY_UPDATE_RENAME); - event.SetString(wxString::Format("%s|%s|%s", s_default_folders[m_type], m_file_path.string(), new_dir_path.string())); + event.SetString(wxString::Format("%s|%s|%s", s_default_folders[m_type], m_file_path.wstring(), new_dir_path.wstring())); event.SetEventObject(m_parent); wxPostEvent(m_parent, event); @@ -328,12 +389,19 @@ void AuFile::on_input_enter(wxCommandEvent &evt) void AuFile::on_dclick(wxMouseEvent &evt) { - wxLaunchDefaultApplication(m_file_path.wstring(), 0); + if (m_type == AddFileButton) + return; + else + wxLaunchDefaultApplication(m_file_path.wstring(), 0); } void AuFile::on_mouse_left_up(wxMouseEvent &evt) { - wxSize size = wxSize(FromDIP(300), FromDIP(300)); + if (m_type == AddFileButton) { + return; + } + + wxSize size = m_type == MODEL_PICTURE ? AUFILE_PICTURES_SIZE : AUFILE_SIZE; auto pos = evt.GetPosition(); // set cover @@ -343,28 +411,36 @@ void AuFile::on_mouse_left_up(wxMouseEvent &evt) auto cover_right = mask_size.x / 2; auto cover_bottom = size.y; - if (pos.x > cover_left && pos.x < cover_right && pos.y > cover_top && pos.y < cover_bottom) { on_set_cover(); } + if (pos.x > cover_left && pos.x < cover_right && pos.y > cover_top && pos.y < cover_bottom) { + if(m_type == MODEL_PICTURE) + on_set_cover(); + /* else + on_set_rename();*/ + return; + } // rename auto rename_left = mask_size.x / 2; auto rename_top = size.y - mask_size.y; auto rename_right = mask_size.x; auto rename_bottom = size.y; - if (pos.x > rename_left && pos.x < rename_right && pos.y > rename_top && pos.y < rename_bottom) { on_set_rename(); } + if (pos.x > rename_left && pos.x < rename_right && pos.y > rename_top && pos.y < rename_bottom) { on_set_rename(); return; } // close auto close_left = size.x - m_file_delete.GetBmpSize().x - FromDIP(15); auto close_top = FromDIP(15); auto close_right = size.x - FromDIP(15); auto close_bottom = m_file_delete.GetBmpSize().y + FromDIP(15); - if (pos.x > close_left && pos.x < close_right && pos.y > close_top && pos.y < close_bottom) { on_set_delete(); } + if (pos.x > close_left && pos.x < close_right && pos.y > close_top && pos.y < close_bottom) { on_set_delete(); return; } + + exit_rename_mode(); } void AuFile::on_set_cover() { if (wxGetApp().plater()->model().model_info == nullptr) { wxGetApp().plater()->model().model_info = std::make_shared(); } - wxGetApp().plater()->model().model_info->cover_file = m_file_name.ToStdString(); + wxGetApp().plater()->model().model_info->cover_file = std::string(m_file_name.ToUTF8().data()); auto full_path = m_file_path.branch_path(); auto full_root_path = full_path.branch_path(); @@ -378,14 +454,15 @@ void AuFile::on_set_cover() } bool result = true; - wxImage thumbnail_img;; + wxImage thumbnail_img; + result = generate_image(m_file_path.string(), thumbnail_img, _3MF_COVER_SIZE); if (result) { auto cover_img_path = dir_path.string() + "/thumbnail_3mf.png"; thumbnail_img.SaveFile(encode_path(cover_img_path.c_str())); } - result = generate_image(m_file_path.string(), thumbnail_img, PRINTER_THUMBNAIL_SMALL_SIZE, GERNERATE_IMAGE_CROP_VERTICAL); + result = generate_image(m_file_path.string(), thumbnail_img, PRINTER_THUMBNAIL_SMALL_SIZE); if (result) { auto small_img_path = dir_path.string() + "/thumbnail_small.png"; thumbnail_img.SaveFile(encode_path(small_img_path.c_str())); @@ -429,7 +506,7 @@ void AuFile::on_set_delete() if (is_fine) { auto evt = wxCommandEvent(EVT_AUXILIARY_UPDATE_DELETE); - evt.SetString(wxString::Format("%s|%s", s_default_folders[m_type], m_file_path.string())); + evt.SetString(wxString::Format("%s|%s", s_default_folders[m_type], m_file_path.wstring())); evt.SetEventObject(m_parent); wxPostEvent(m_parent, evt); } @@ -468,11 +545,11 @@ void AuFile::msw_rescale() } image->Rescale(size.x, size.y); - m_file_bitmap = wxBitmap(*image); + m_file_bitmap.bmp() = wxBitmap(*image); } else { - m_bitmap_excel = create_scaled_bitmap("placeholder_excel", nullptr, 300); - m_bitmap_pdf = create_scaled_bitmap("placeholder_pdf", nullptr, 300); - m_bitmap_txt = create_scaled_bitmap("placeholder_txt", nullptr, 300); + m_bitmap_excel = ScalableBitmap(this, "placeholder_excel", 168); + m_bitmap_pdf = ScalableBitmap(this, "placeholder_pdf", 168); + m_bitmap_txt = ScalableBitmap(this, "placeholder_txt", 168); if (m_type == OTHERS) { m_file_bitmap = m_bitmap_txt; } if (m_type == BILL_OF_MATERIALS) { m_file_bitmap = m_bitmap_excel; } @@ -504,7 +581,8 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo m_button_add->SetMinSize(wxSize(-1, FromDIP(24))); m_button_add->SetCornerRadius(FromDIP(12)); m_button_add->SetFont(Label::Body_14); - // m_button_add->Bind(wxEVT_LEFT_UP, &AuxiliaryPanel::on_add, this); + + m_big_button_add = new AuFile(m_scrolledWindow, fs::path(), "", AddFileButton, -1); /*m_button_del = new Button(m_scrolledWindow, _L("Delete"), "auxiliary_delete_file", 12, 12); m_button_del->SetBackgroundColor(btn_bg_white); @@ -515,12 +593,18 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo // m_button_del->Bind(wxEVT_LEFT_UP, &AuxiliaryPanel::on_delete, this); sizer_top->Add(0, 0, 0, wxLEFT, FromDIP(10)); - sizer_top->Add(m_button_add, 0, wxALL, 0); + m_gsizer_content = new wxWrapSizer(wxHORIZONTAL, wxWRAPSIZER_DEFAULT_FLAGS); + if (m_type == MODEL_PICTURE) { + sizer_top->Add(m_button_add, 0, wxALL, 0); + m_big_button_add->Hide(); + } + else { + m_gsizer_content->Add(m_big_button_add, 0, wxALL, FromDIP(8)); + m_button_add->Hide(); + } // sizer_top->Add(m_button_del, 0, wxALL, 0); - - m_gsizer_content = new wxGridSizer(0, 3, FromDIP(18), FromDIP(18)); sizer_body->Add(sizer_top, 0, wxEXPAND | wxTOP, FromDIP(35)); - sizer_body->Add(0, 0, 0, wxEXPAND | wxTOP, FromDIP(30)); + sizer_body->AddSpacer(FromDIP(14)); sizer_body->Add(m_gsizer_content, 0, 0, 0); m_scrolledWindow->SetSizer(sizer_body); m_scrolledWindow->Layout(); @@ -529,18 +613,25 @@ AuFolderPanel::AuFolderPanel(wxWindow *parent, AuxiliaryFolderType type, wxWindo this->SetSizer(sizer_main); this->Layout(); - m_button_add->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AuFolderPanel::on_add), NULL, this); - // m_button_del->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AuFolderPanel::on_delete), NULL, this); + m_big_button_add->Bind(wxEVT_LEFT_DOWN, [this](auto& e) + { + auto evt = wxCommandEvent(EVT_AUXILIARY_IMPORT); + evt.SetString(s_default_folders[m_type]); + evt.SetEventObject(m_parent); + wxPostEvent(m_parent, evt); + }); + m_button_add->Bind(wxEVT_BUTTON, &AuFolderPanel::on_add, this); } void AuFolderPanel::clear() { for (auto i = 0; i < m_aufiles_list.GetCount(); i++) { AuFiles *aufile = m_aufiles_list[i]; - if (aufile->file != NULL) { aufile->file->Destroy(); } + if (aufile->file) { aufile->file->Destroy(); } } m_aufiles_list.clear(); - m_gsizer_content->Layout(); + Layout(); + Refresh(); } void AuFolderPanel::update(std::vector paths) @@ -551,7 +642,7 @@ void AuFolderPanel::update(std::vector paths) auto name = encode_path(temp_name.c_str()); auto aufile = new AuFile(m_scrolledWindow, paths[i], name, m_type, wxID_ANY); - m_gsizer_content->Add(aufile, 0, 0, 0); + m_gsizer_content->Add(aufile, 0, wxALL, FromDIP(8)); auto af = new AuFiles; af->path = paths[i].string(); af->file = aufile; @@ -570,7 +661,7 @@ void AuFolderPanel::msw_rescale() } } -void AuFolderPanel::on_add(wxCommandEvent &event) +void AuFolderPanel::on_add(wxCommandEvent& event) { auto evt = wxCommandEvent(EVT_AUXILIARY_IMPORT); evt.SetString(s_default_folders[m_type]); @@ -582,8 +673,6 @@ void AuFolderPanel::on_delete(wxCommandEvent &event) { clear(); } AuFolderPanel::~AuFolderPanel() { - m_button_add->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AuFolderPanel::on_add), NULL, this); - // m_button_del->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AuFolderPanel::on_delete), NULL, this); } void AuFolderPanel::update_cover() @@ -617,22 +706,29 @@ AuxiliaryPanel::AuxiliaryPanel(wxWindow *parent, wxWindowID id, const wxPoint &p // delete event Bind(EVT_AUXILIARY_UPDATE_DELETE, [this](wxCommandEvent &e) { auto info_str = e.GetString(); - auto parems = std::vector{}; - Split(info_str.ToStdString(), "|", parems); + + wxArrayString parems; + wxStringTokenizer tokenizer(info_str, "|"); + while (tokenizer.HasMoreTokens()) { + wxString token = tokenizer.GetNextToken(); + parems.Add(token); + } + + auto model = parems[0]; auto name = parems[1]; - auto iter = m_paths_list.find(model); + auto iter = m_paths_list.find(model.ToStdString()); if (iter != m_paths_list.end()) { auto list = iter->second; for (auto i = 0; i < list.size(); i++) { - if (list[i] == name) { + if (list[i].wstring() == name) { list.erase(std::begin(list) + i); break; } } - m_paths_list[model] = list; + m_paths_list[model.ToStdString()] = list; update_all_panel(); update_all_cover(); } @@ -642,24 +738,28 @@ AuxiliaryPanel::AuxiliaryPanel(wxWindow *parent, wxWindowID id, const wxPoint &p Bind(EVT_AUXILIARY_UPDATE_RENAME, [this](wxCommandEvent &e) { auto info_str = e.GetString(); - auto parems = std::vector{}; - Split(info_str.ToStdString(), "|", parems); + wxArrayString parems; + wxStringTokenizer tokenizer(info_str, "|"); + while (tokenizer.HasMoreTokens()) { + wxString token = tokenizer.GetNextToken(); + parems.Add(token); + } auto model = parems[0]; auto old_name = parems[1]; auto new_name = parems[2]; - auto iter = m_paths_list.find(model); + auto iter = m_paths_list.find(model.ToStdString()); if (iter != m_paths_list.end()) { auto list = iter->second; for (auto i = 0; i < list.size(); i++) { - if (list[i] == old_name) { - list[i] = new_name; + if (list[i].wstring() == old_name) { + list[i] = fs::path(new_name.c_str()); break; } } - m_paths_list[model] = list; + m_paths_list[model.ToStdString()] = list; } }); } @@ -943,6 +1043,7 @@ void AuxiliaryPanel::update_all_panel() { std::map>::iterator mit; + Freeze(); m_pictures_panel->clear(); m_bill_of_materials_panel->clear(); m_assembly_panel->clear(); @@ -954,6 +1055,7 @@ void AuxiliaryPanel::update_all_panel() if (mit->first == "Assembly Guide") { m_assembly_panel->update(mit->second); } if (mit->first == "Others") { m_others_panel->update(mit->second); } } + Thaw(); } void AuxiliaryPanel::update_all_cover() @@ -977,7 +1079,7 @@ void AuxiliaryPanel::update_all_cover() wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL); wxBoxSizer *m_sizer_designer = new wxBoxSizer(wxHORIZONTAL); - auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Designer"), wxDefaultPosition, wxSize(120, -1), 0); + auto m_text_designer = new wxStaticText(this, wxID_ANY, _L("Author"), wxDefaultPosition, wxSize(120, -1), 0); m_text_designer->Wrap(-1); m_sizer_designer->Add(m_text_designer, 0, wxALIGN_CENTER, 0); diff --git a/src/slic3r/GUI/Auxiliary.hpp b/src/slic3r/GUI/Auxiliary.hpp index fd61637e44..b9ef3332dd 100644 --- a/src/slic3r/GUI/Auxiliary.hpp +++ b/src/slic3r/GUI/Auxiliary.hpp @@ -48,8 +48,17 @@ #include "Widgets/SideTools.hpp" #define AUFILE_GREY700 wxColour(107, 107, 107) +#define AUFILE_GREY500 wxColour(158, 158, 158) #define AUFILE_GREY300 wxColour(238, 238, 238) #define AUFILE_GREY200 wxColour(248, 248, 248) +#define AUFILE_BRAND wxColour(0, 174, 66) +#define AUFILE_BRAND_TRANSPARENT wxColour(215, 232, 222) +#define AUFILE_PICTURES_SIZE wxSize(FromDIP(300), FromDIP(300)) +#define AUFILE_PICTURES_PANEL_SIZE wxSize(FromDIP(300), FromDIP(340)) +#define AUFILE_SIZE wxSize(FromDIP(168), FromDIP(168)) +#define AUFILE_PANEL_SIZE wxSize(FromDIP(168), FromDIP(208)) +#define AUFILE_TEXT_HEIGHT FromDIP(40) +#define AUFILE_ROUNDING FromDIP(5) enum AuxiliaryFolderType { MODEL_PICTURE, @@ -58,6 +67,7 @@ enum AuxiliaryFolderType { OTHERS, THUMBNAILS, DESIGNER, + AddFileButton, }; const static std::array s_default_folders = {("Model Pictures"), ("Bill of Materials"), ("Assembly Guide"), ("Others"), (".thumbnails")}; @@ -76,18 +86,19 @@ public: wxStaticText* m_text_name {nullptr}; ::TextInput* m_input_name {nullptr}; fs::path m_file_path; + wxString m_add_file; wxString m_file_name; wxString cover_text_left; wxString cover_text_right; wxString cover_text_cover; - wxBitmap m_file_bitmap; + ScalableBitmap m_file_bitmap; ScalableBitmap m_file_cover; ScalableBitmap m_file_edit_mask; ScalableBitmap m_file_delete; - wxBitmap m_bitmap_excel; - wxBitmap m_bitmap_pdf; - wxBitmap m_bitmap_txt; + ScalableBitmap m_bitmap_excel; + ScalableBitmap m_bitmap_pdf; + ScalableBitmap m_bitmap_txt; public: AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL); @@ -144,12 +155,13 @@ public: public: AuxiliaryFolderType m_type; wxScrolledWindow * m_scrolledWindow{nullptr}; - wxGridSizer * m_gsizer_content{nullptr}; + wxWrapSizer * m_gsizer_content{nullptr}; Button * m_button_add{nullptr}; Button * m_button_del{nullptr}; + AuFile * m_big_button_add{ nullptr }; AuFilesHash m_aufiles_list; - void on_add(wxCommandEvent &event); + void on_add(wxCommandEvent& event); void on_delete(wxCommandEvent &event); }; diff --git a/src/slic3r/GUI/BBLStatusBarSend.cpp b/src/slic3r/GUI/BBLStatusBarSend.cpp index 5d9eab1370..4694d11e88 100644 --- a/src/slic3r/GUI/BBLStatusBarSend.cpp +++ b/src/slic3r/GUI/BBLStatusBarSend.cpp @@ -93,7 +93,7 @@ void BBLStatusBarSend::set_progress(int val) return; //add the logic for arrange/orient jobs, which don't call stop_busy - if (!m_sizer->IsShown(m_prog)) { + if (!m_prog->IsShown()) { m_sizer->Show(m_prog); m_sizer->Show(m_cancelbutton); } diff --git a/src/slic3r/GUI/BindDialog.cpp b/src/slic3r/GUI/BindDialog.cpp index 630ced8e91..1b43b5dc9e 100644 --- a/src/slic3r/GUI/BindDialog.cpp +++ b/src/slic3r/GUI/BindDialog.cpp @@ -15,7 +15,7 @@ namespace Slic3r { namespace GUI { - BindMachineDilaog::BindMachineDilaog(Plater *plater /*= nullptr*/) + BindMachineDialog::BindMachineDialog(Plater *plater /*= nullptr*/) : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Log in printer"), wxDefaultPosition, wxDefaultSize, wxCAPTION) { std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str(); @@ -92,12 +92,12 @@ namespace GUI { m_avatar = new wxStaticBitmap(m_panel_right, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(60), FromDIP(60)), 0); - wxWebRequest request = wxWebSession::GetDefault().CreateRequest(this, wxGetApp().getAgent()->get_user_avatar()); - if (!request.IsOk()) { + web_request = wxWebSession::GetDefault().CreateRequest(this, wxGetApp().getAgent()->get_user_avatar()); + if (!web_request.IsOk()) { // todo request fail } // Start the request - request.Start(); + web_request.Start(); } m_sizer_right_v->Add(m_avatar, 0, wxALIGN_CENTER, 0); @@ -172,23 +172,25 @@ namespace GUI { Fit(); Centre(wxBOTH); - Bind(wxEVT_SHOW, &BindMachineDilaog::on_show, this); + Bind(wxEVT_SHOW, &BindMachineDialog::on_show, this); - m_button_bind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDilaog::on_bind_printer), NULL, this); - m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDilaog::on_cancel), NULL, this); - this->Connect(EVT_BIND_MACHINE_FAIL, wxCommandEventHandler(BindMachineDilaog::on_bind_fail), NULL, this); - this->Connect(EVT_BIND_MACHINE_SUCCESS, wxCommandEventHandler(BindMachineDilaog::on_bind_success), NULL, this); - this->Connect(EVT_BIND_UPDATE_MESSAGE, wxCommandEventHandler(BindMachineDilaog::on_update_message), NULL, this); + Bind(wxEVT_CLOSE_WINDOW, &BindMachineDialog::on_close, this); + + m_button_bind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDialog::on_bind_printer), NULL, this); + m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDialog::on_cancel), NULL, this); + this->Connect(EVT_BIND_MACHINE_FAIL, wxCommandEventHandler(BindMachineDialog::on_bind_fail), NULL, this); + this->Connect(EVT_BIND_MACHINE_SUCCESS, wxCommandEventHandler(BindMachineDialog::on_bind_success), NULL, this); + this->Connect(EVT_BIND_UPDATE_MESSAGE, wxCommandEventHandler(BindMachineDialog::on_update_message), NULL, this); m_simplebook->SetSelection(1); } - BindMachineDilaog::~BindMachineDilaog() + BindMachineDialog::~BindMachineDialog() { - m_button_bind->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDilaog::on_bind_printer), NULL, this); - m_button_cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDilaog::on_cancel), NULL, this); - this->Disconnect(EVT_BIND_MACHINE_FAIL, wxCommandEventHandler(BindMachineDilaog::on_bind_fail), NULL, this); - this->Disconnect(EVT_BIND_MACHINE_SUCCESS, wxCommandEventHandler(BindMachineDilaog::on_bind_success), NULL, this); - this->Disconnect(EVT_BIND_UPDATE_MESSAGE, wxCommandEventHandler(BindMachineDilaog::on_update_message), NULL, this); + m_button_bind->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDialog::on_bind_printer), NULL, this); + m_button_cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BindMachineDialog::on_cancel), NULL, this); + this->Disconnect(EVT_BIND_MACHINE_FAIL, wxCommandEventHandler(BindMachineDialog::on_bind_fail), NULL, this); + this->Disconnect(EVT_BIND_MACHINE_SUCCESS, wxCommandEventHandler(BindMachineDialog::on_bind_success), NULL, this); + this->Disconnect(EVT_BIND_UPDATE_MESSAGE, wxCommandEventHandler(BindMachineDialog::on_update_message), NULL, this); } //static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) @@ -205,30 +207,49 @@ namespace GUI { //} - void BindMachineDilaog::on_cancel(wxCommandEvent &event) + void BindMachineDialog::on_cancel(wxCommandEvent &event) { - EndModal(wxID_CANCEL); + on_destroy(); + EndModal(wxID_CANCEL); } - void BindMachineDilaog::on_bind_fail(wxCommandEvent &event) + void BindMachineDialog::on_destroy() + { + if (m_bind_job) { + m_bind_job->cancel(); + m_bind_job->join(); + } + + if (web_request.IsOk()) { + web_request.Cancel(); + } + } + + void BindMachineDialog::on_close(wxCloseEvent &event) + { + on_destroy(); + event.Skip(); + } + + void BindMachineDialog::on_bind_fail(wxCommandEvent &event) { //m_status_text->SetLabel(_L("Would you like to log in this printer with current account?")); m_simplebook->SetSelection(1); } - void BindMachineDilaog::on_update_message(wxCommandEvent &event) + void BindMachineDialog::on_update_message(wxCommandEvent &event) { m_status_text->SetLabelText(event.GetString()); } - void BindMachineDilaog::on_bind_success(wxCommandEvent &event) + void BindMachineDialog::on_bind_success(wxCommandEvent &event) { EndModal(wxID_OK); MessageDialog msg_wingow(nullptr, _L("Log in successful."), "", wxAPPLY | wxOK); if (msg_wingow.ShowModal() == wxOK) { return; } } - void BindMachineDilaog::on_bind_printer(wxCommandEvent &event) + void BindMachineDialog::on_bind_printer(wxCommandEvent &event) { //check isset info if (m_machine_info == nullptr || m_machine_info == NULL) return; @@ -242,13 +263,13 @@ namespace GUI { m_bind_job->start(); } -void BindMachineDilaog::on_dpi_changed(const wxRect &suggested_rect) +void BindMachineDialog::on_dpi_changed(const wxRect &suggested_rect) { m_button_bind->SetMinSize(BIND_DIALOG_BUTTON_SIZE); m_button_cancel->SetMinSize(BIND_DIALOG_BUTTON_SIZE); } -void BindMachineDilaog::on_show(wxShowEvent &event) +void BindMachineDialog::on_show(wxShowEvent &event) { //m_printer_name->SetLabelText(m_machine_info->get_printer_type_string()); m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name)); @@ -256,7 +277,7 @@ void BindMachineDilaog::on_show(wxShowEvent &event) } -UnBindMachineDilaog::UnBindMachineDilaog(Plater *plater /*= nullptr*/) +UnBindMachineDialog::UnBindMachineDialog(Plater *plater /*= nullptr*/) : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, _L("Log out printer"), wxDefaultPosition, wxDefaultSize, wxCAPTION) { std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str(); @@ -402,24 +423,24 @@ UnBindMachineDilaog::UnBindMachineDilaog(Plater *plater /*= nullptr*/) Fit(); Centre(wxBOTH); - Bind(wxEVT_SHOW, &UnBindMachineDilaog::on_show, this); - m_button_unbind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDilaog::on_unbind_printer), NULL, this); - m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDilaog::on_cancel), NULL, this); + Bind(wxEVT_SHOW, &UnBindMachineDialog::on_show, this); + m_button_unbind->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_unbind_printer), NULL, this); + m_button_cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_cancel), NULL, this); } - UnBindMachineDilaog::~UnBindMachineDilaog() + UnBindMachineDialog::~UnBindMachineDialog() { - m_button_unbind->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDilaog::on_unbind_printer), NULL, this); - m_button_cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDilaog::on_cancel), NULL, this); + m_button_unbind->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_unbind_printer), NULL, this); + m_button_cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(UnBindMachineDialog::on_cancel), NULL, this); } -void UnBindMachineDilaog::on_cancel(wxCommandEvent &event) +void UnBindMachineDialog::on_cancel(wxCommandEvent &event) { EndModal(wxID_CANCEL); } -void UnBindMachineDilaog::on_unbind_printer(wxCommandEvent &event) +void UnBindMachineDialog::on_unbind_printer(wxCommandEvent &event) { if (!wxGetApp().is_user_login()) { m_status_text->SetLabelText(_L("Please log in first.")); @@ -455,13 +476,13 @@ void UnBindMachineDilaog::on_unbind_printer(wxCommandEvent &event) } } - void UnBindMachineDilaog::on_dpi_changed(const wxRect &suggested_rect) + void UnBindMachineDialog::on_dpi_changed(const wxRect &suggested_rect) { m_button_unbind->SetMinSize(BIND_DIALOG_BUTTON_SIZE); m_button_cancel->SetMinSize(BIND_DIALOG_BUTTON_SIZE); } -void UnBindMachineDilaog::on_show(wxShowEvent &event) +void UnBindMachineDialog::on_show(wxShowEvent &event) { //m_printer_name->SetLabelText(m_machine_info->get_printer_type_string()); m_printer_name->SetLabelText(from_u8(m_machine_info->dev_name)); diff --git a/src/slic3r/GUI/BindDialog.hpp b/src/slic3r/GUI/BindDialog.hpp index 6320e3dfb3..f7ed5debf3 100644 --- a/src/slic3r/GUI/BindDialog.hpp +++ b/src/slic3r/GUI/BindDialog.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "wxExtensions.hpp" #include "Plater.hpp" #include "Widgets/StepCtrl.hpp" @@ -42,7 +43,7 @@ struct MemoryStruct size_t size; }; -class BindMachineDilaog : public DPIDialog +class BindMachineDialog : public DPIDialog { private: wxStaticText * m_printer_name; @@ -54,14 +55,15 @@ private: Button * m_button_cancel; wxSimplebook *m_simplebook; wxStaticBitmap *m_avatar; + wxWebRequest web_request; MachineObject * m_machine_info{nullptr}; std::shared_ptr m_bind_job; std::shared_ptr m_status_bar; public: - BindMachineDilaog(Plater *plater = nullptr); - ~BindMachineDilaog(); + BindMachineDialog(Plater *plater = nullptr); + ~BindMachineDialog(); void on_cancel(wxCommandEvent &event); void on_bind_fail(wxCommandEvent &event); void on_update_message(wxCommandEvent &event); @@ -70,9 +72,11 @@ public: void on_dpi_changed(const wxRect &suggested_rect) override; void update_machine_info(MachineObject *info) { m_machine_info = info; }; void on_show(wxShowEvent &event); + void on_close(wxCloseEvent& event); + void on_destroy(); }; -class UnBindMachineDilaog : public DPIDialog +class UnBindMachineDialog : public DPIDialog { protected: wxStaticText * m_printer_name; @@ -84,8 +88,8 @@ protected: wxStaticBitmap *m_avatar; public: - UnBindMachineDilaog(Plater *plater = nullptr); - ~UnBindMachineDilaog(); + UnBindMachineDialog(Plater *plater = nullptr); + ~UnBindMachineDialog(); void on_cancel(wxCommandEvent &event); void on_unbind_printer(wxCommandEvent &event); diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index 3a56d52a8f..ca37795489 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -93,6 +93,9 @@ void Camera::select_view(const std::string& direction) look_at(m_target + m_distance * Vec3d::UnitY(), m_target, Vec3d::UnitZ()); else if (direction == "topfront") look_at(m_target - 0.707 * m_distance * Vec3d::UnitY() + 0.707 * m_distance * Vec3d::UnitZ(), m_target, Vec3d::UnitY() + Vec3d::UnitZ()); + else if (direction == "plate") { + look_at(m_target - 0.707 * m_distance * Vec3d::UnitY() + 0.707 * m_distance * Vec3d::UnitZ(), m_target, Vec3d::UnitY() + Vec3d::UnitZ()); + } } double Camera::get_fov() const diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 467755c4e3..18d23148f8 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -11,7 +11,6 @@ #include "MsgDialog.hpp" #include "Plater.hpp" #include "GUI_App.hpp" -#include "nlohmann/json.hpp" #include #include #include @@ -21,7 +20,6 @@ #include #include -using namespace nlohmann; namespace pt = boost::property_tree; @@ -259,63 +257,34 @@ wxString HMSItem::get_hms_msg_level_str(HMSMessageLevel level) return ""; } -PRINTER_TYPE MachineObject::parse_printer_type(std::string type_str) +std::string MachineObject::parse_printer_type(std::string type_str) { - if (type_str.compare("3DPrinter-P1") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_P1; - } else if (type_str.compare("3DPrinter-X1") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_X1; + if (type_str.compare("3DPrinter-X1") == 0) { + return "BL-P002"; } else if (type_str.compare("3DPrinter-X1-Carbon") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_X1_Carbon; - } - - BOOST_LOG_TRIVIAL(trace) << "unknown printer type: " << type_str; - return PRINTER_TYPE::PRINTER_3DPrinter_UKNOWN; -} - -PRINTER_TYPE MachineObject::parse_iot_printer_type(std::string type_str) -{ - if (type_str.compare("BL-P003") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_P1; - } else if (type_str.compare("BL-P002") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_X1; + return "BL-P001"; } else if (type_str.compare("BL-P001") == 0) { - return PRINTER_TYPE::PRINTER_3DPrinter_X1_Carbon; - } - - BOOST_LOG_TRIVIAL(trace) << "unknown printer type: " << type_str; - return PRINTER_TYPE::PRINTER_3DPrinter_UKNOWN; -} - -PRINTER_TYPE MachineObject::parse_preset_printer_type(std::string type_str) -{ - return parse_iot_printer_type(type_str); -} - -std::string MachineObject::get_preset_printer_model_name(PRINTER_TYPE printer_type) -{ - if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_P1) { - return "Bambu Lab P1"; - } else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1) { - return "Bambu Lab X1"; - } else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1_Carbon) { - return "Bambu Lab X1 Carbon"; + return type_str; + } else if (type_str.compare("BL-P003") == 0) { + return type_str; } else { - return ""; + return DeviceManager::parse_printer_type(type_str); } + return ""; } - +std::string MachineObject::get_preset_printer_model_name(std::string printer_type) +{ + return DeviceManager::get_printer_display_name(printer_type); +} wxString MachineObject::get_printer_type_display_str() { - if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_P1) - return "Bambu Lab P1"; - else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1) - return "Bambu Lab X1"; - else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1_Carbon) - return "Bambu Lab X1 Carbon"; - return _L("Unknown"); + std::string display_name = get_preset_printer_model_name(printer_type); + if (!display_name.empty()) + return display_name; + else + return _L("Unknown"); } void MachineObject::set_access_code(std::string code) @@ -335,17 +304,6 @@ bool MachineObject::is_lan_mode_printer() return result; } -std::string MachineObject::get_printer_type_string() -{ - if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_P1) - return "3DPrinter-P1"; - else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1) - return "3DPrinter-X1"; - else if (printer_type == PRINTER_TYPE::PRINTER_3DPrinter_X1_Carbon) - return "3DPrinter-X1-Carbon"; - return "3DPrinter"; -} - MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string id, std::string ip) :dev_name(name), dev_id(id), @@ -370,7 +328,11 @@ MachineObject::MachineObject(NetworkAgent* agent, std::string name, std::string ams_exist_bits = 0; tray_exist_bits = 0; tray_is_bbl_bits = 0; + ams_rfid_status = 0; is_ams_need_update = false; + ams_insert_flag = false; + ams_power_on_flag = false; + ams_support_use_ams = false; /* signals */ wifi_signal = ""; @@ -1454,22 +1416,39 @@ int MachineObject::command_axis_control(std::string axis, double unit, double va int MachineObject::command_start_calibration() { - // fixed gcode file - json j; - j["print"]["command"] = "gcode_file"; - j["print"]["param"] = "/usr/etc/print/auto_cali_for_user.gcode"; - j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); - return this->publish_json(j.dump()); + if (printer_type == "BL-P001" + || printer_type == "BL-P002") { + // fixed gcode file + json j; + j["print"]["command"] = "gcode_file"; + j["print"]["param"] = "/usr/etc/print/auto_cali_for_user.gcode"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + return this->publish_json(j.dump()); + } else { + json j; + j["print"]["command"] = "calibration"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + return this->publish_json(j.dump()); + } } int MachineObject::command_unload_filament() { - // fixed gcode file - json j; - j["print"]["command"] = "gcode_file"; - j["print"]["param"] = "/usr/etc/print/filament_unload.gcode"; - j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); - return this->publish_json(j.dump()); + if (printer_type == "BL-P001" + || printer_type == "BL-P002") { + // fixed gcode file + json j; + j["print"]["command"] = "gcode_file"; + j["print"]["param"] = "/usr/etc/print/filament_unload.gcode"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + return this->publish_json(j.dump()); + } + else { + json j; + j["print"]["command"] = "unload_filament"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + return this->publish_json(j.dump()); + } } @@ -1617,6 +1596,7 @@ void MachineObject::reset() iot_print_status = ""; print_status = ""; last_mc_print_stage = -1; + m_new_ver_list_exist = false; subtask_ = nullptr; @@ -1694,6 +1674,40 @@ bool MachineObject::is_info_ready() return false; } +bool MachineObject::is_function_supported(PrinterFunction func) +{ + std::string func_name; + switch (func) { + case FUNC_MONITORING: + func_name = "FUNC_MONITORING"; + break; + case FUNC_TIMELAPSE: + func_name = "FUNC_TIMELAPSE"; + break; + case FUNC_RECORDING: + func_name = "FUNC_RECORDING"; + break; + case FUNC_FIRSTLAYER_INSPECT: + func_name = "FUNC_FIRSTLAYER_INSPECT"; + break; + case FUNC_SPAGHETTI: + func_name = "FUNC_SPAGHETTI"; + break; + case FUNC_FLOW_CALIBRATION: + func_name = "FUNC_FLOW_CALIBRATION"; + break; + case FUNC_AUTO_LEVELING: + func_name = "FUNC_AUTO_LEVELING"; + break; + case FUNC_CHAMBER_TEMP: + func_name = "FUNC_CHAMBER_TEMP"; + break; + default: + return true; + } + return DeviceManager::is_function_supported(printer_type, func_name); +} + int MachineObject::publish_json(std::string json_str, int qos) { if (is_lan_mode_printer()) { @@ -1824,6 +1838,30 @@ int MachineObject::parse_json(std::string payload) #pragma endregion +#pragma region online + // parse online info + try { + if (jj.contains("online")) { + if (jj["online"].contains("ahb")) { + if (jj["online"]["ahb"].get()) { + online_ahb = true; + } else { + online_ahb = false; + } + } + if (jj["online"].contains("rfid")) { + if (jj["online"]["rfid"].get()) { + online_rfid = true; + } else { + online_rfid = false; + } + } + } + } catch (...) { + ; + } +#pragma endregion + #pragma region print_task if (jj.contains("printer_type")) { printer_type = parse_printer_type(jj["printer_type"].get()); @@ -2069,6 +2107,31 @@ int MachineObject::parse_json(std::string payload) } } } + // new ver list + if (jj["upgrade_state"].contains("new_ver_list")) { + m_new_ver_list_exist = true; + new_ver_list.clear(); + for (auto ver_item = jj["upgrade_state"]["new_ver_list"].begin(); ver_item != jj["upgrade_state"]["new_ver_list"].end(); ver_item++) { + ModuleVersionInfo ver_info; + if (ver_item->contains("name")) + ver_info.name = (*ver_item)["name"].get(); + else + continue; + + if (ver_item->contains("cur_ver")) + ver_info.sw_ver = (*ver_item)["cur_ver"].get(); + if (ver_item->contains("new_ver")) + ver_info.sw_new_ver = (*ver_item)["new_ver"].get(); + + if (ver_info.name == "ota") { + ota_new_version_number = ver_info.sw_new_ver; + } + + new_ver_list.insert(std::make_pair(ver_info.name, ver_info)); + } + } else { + new_ver_list.clear(); + } } } catch (...) { @@ -2181,6 +2244,10 @@ int MachineObject::parse_json(std::string payload) if (jj["ams"].contains("tray_read_done_bits")) { tray_read_done_bits = stol(jj["ams"]["tray_read_done_bits"].get(), nullptr, 16); } + if (jj["ams"].contains("tray_reading_bits")) { + tray_reading_bits = stol(jj["ams"]["tray_reading_bits"].get(), nullptr, 16); + ams_support_use_ams = true; + } if (jj["ams"].contains("tray_is_bbl_bits")) { tray_is_bbl_bits = stol(jj["ams"]["tray_is_bbl_bits"].get(), nullptr, 16); } @@ -2194,6 +2261,15 @@ int MachineObject::parse_json(std::string payload) if (jj["ams"].contains("tray_tar")) { m_tray_tar = jj["ams"]["tray_tar"].get(); } + if (jj["ams"].contains("insert_flag")) { + ams_insert_flag = jj["ams"]["insert_flag"].get(); + } + if (jj["ams"].contains("ams_rfid_status")) + ams_rfid_status = jj["ams"]["ams_rfid_status"].get(); + + if (jj["ams"].contains("power_on_flag")) { + ams_power_on_flag = jj["ams"]["power_on_flag"].get(); + } if (ams_exist_bits != last_ams_exist_bits || last_tray_exist_bits != last_tray_exist_bits @@ -2931,11 +3007,15 @@ std::map DeviceManager::get_my_machine_list() std::map result; for (auto it = userMachineList.begin(); it != userMachineList.end(); it++) { + if (!it->second) + continue; if (!it->second->is_lan_mode_printer()) result.insert(std::make_pair(it->first, it->second)); } for (auto it = localMachineList.begin(); it != localMachineList.end(); it++) { + if (!it->second) + continue; if (it->second->has_access_right() && it->second->is_avaliable() && it->second->is_lan_mode_printer()) { // remove redundant in userMachineList if (result.find(it->first) == result.end()) { @@ -3004,7 +3084,7 @@ void DeviceManager::parse_user_print_info(std::string body) if (!elem["dev_online"].is_null()) obj->m_is_online = elem["dev_online"].get(); if (elem.contains("dev_model_name") && !elem["dev_model_name"].is_null()) - obj->printer_type = MachineObject::parse_iot_printer_type(elem["dev_model_name"].get()); + obj->printer_type = elem["dev_model_name"].get(); if (!elem["task_status"].is_null()) obj->iot_print_status = elem["task_status"].get(); if (elem.contains("dev_product_name") && !elem["dev_product_name"].is_null()) @@ -3083,4 +3163,67 @@ void DeviceManager::load_last_machine() } } +json DeviceManager::function_table = json::object(); + +std::string DeviceManager::parse_printer_type(std::string type_str) +{ + if (DeviceManager::function_table.contains("printers")) { + for (auto printer : DeviceManager::function_table["printers"]) { + if (printer.contains("model_id") && printer["model_id"].get() == type_str) { + if (printer.contains("printer_type")) { + return printer["printer_type"].get(); + } + } + } + } + return ""; +} + +std::string DeviceManager::get_printer_display_name(std::string type_str) +{ + if (DeviceManager::function_table.contains("printers")) { + for (auto printer : DeviceManager::function_table["printers"]) { + if (printer.contains("model_id") && printer["model_id"].get() == type_str) { + if (printer.contains("display_name")) { + return printer["display_name"].get(); + } + } + } + } + return ""; +} + +bool DeviceManager::is_function_supported(std::string type_str, std::string function_name) +{ + if (DeviceManager::function_table.contains("printers")) { + for (auto printer : DeviceManager::function_table["printers"]) { + if (printer.contains("model_id") && printer["model_id"].get() == type_str) { + if (printer.contains("func")) { + if (printer["func"].contains(function_name)) + return printer["func"][function_name].get(); + } + } + } + } + return true; +} + +bool DeviceManager::load_functional_config(std::string config_file) +{ + std::ifstream json_file(config_file.c_str()); + try { + if (json_file.is_open()) { + json_file >> DeviceManager::function_table; + return true; + } else { + BOOST_LOG_TRIVIAL(error) << "load functional config failed, file = " << config_file; + } + } + catch(...) { + BOOST_LOG_TRIVIAL(error) << "load functional config failed, file = " << config_file; + return false; + } + return true; +} + } // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 241e8424fb..8b769791c2 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -7,6 +7,7 @@ #include #include #include +#include "nlohmann/json.hpp" #include "libslic3r/ProjectTask.hpp" #include "slic3r/Utils/json_diff.hpp" #include "slic3r/Utils/NetworkAgent.hpp" @@ -32,17 +33,10 @@ inline int correct_filament_temperature(int filament_temp) wxString get_stage_string(int stage); +using namespace nlohmann; namespace Slic3r { -enum PRINTER_TYPE { - PRINTER_3DPrinter_UKNOWN, - PRINTER_3DPrinter_NONE, - PRINTER_3DPrinter_X1_Carbon, // BL-P001 - PRINTER_3DPrinter_X1, // BL-P002 - PRINTER_3DPrinter_P1, // BL-P003 -}; - enum PRINTING_STAGE { PRINTING_STAGE_PRINTING = 0, PRINTING_STAGE_BED_LEVELING, @@ -62,6 +56,18 @@ enum PRINTING_STAGE { PRINTING_STAGE_COUNT }; +enum PrinterFunction { + FUNC_MONITORING = 0, + FUNC_TIMELAPSE, + FUNC_RECORDING, + FUNC_FIRSTLAYER_INSPECT, + FUNC_SPAGHETTI, + FUNC_FLOW_CALIBRATION, + FUNC_AUTO_LEVELING, + FUNC_CHAMBER_TEMP, + FUNC_MAX +}; + enum PrintingSpeedLevel { SPEED_LEVEL_INVALID = 0, @@ -105,6 +111,16 @@ enum AmsStatusMain { AMS_STATUS_MAIN_UNKNOWN = 0xFF, }; +enum AmsRfidStatus { + AMS_RFID_IDLE = 0, + AMS_RFID_READING = 1, + AMS_RFID_GCODE_TRANS = 2, + AMS_RFID_GCODE_RUNNING = 3, + AMS_RFID_ASSITANT = 4, + AMS_RFID_SWITCH_FILAMENT= 5, + AMS_RFID_HAS_FILAMENT = 6 +}; + class AmsTray { public: AmsTray(std::string tray_id) { @@ -296,14 +312,13 @@ public: std::string sn; std::string hw_ver; std::string sw_ver; + std::string sw_new_ver; }; /* static members and functions */ static inline int m_sequence_id = 20000; - static PRINTER_TYPE parse_printer_type(std::string type_str); - static PRINTER_TYPE parse_iot_printer_type(std::string type_str); - static PRINTER_TYPE parse_preset_printer_type(std::string type_str); - static std::string get_preset_printer_model_name(PRINTER_TYPE printer_type); + static std::string parse_printer_type(std::string type_str); + static std::string get_preset_printer_model_name(std::string printer_type); static bool is_bbl_filament(std::string tag_uid); typedef std::function UploadedFn; @@ -321,8 +336,8 @@ public: bool has_access_right() { return !access_code.empty(); } void set_access_code(std::string code); bool is_lan_mode_printer(); - PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN; - std::string get_printer_type_string(); + //PRINTER_TYPE printer_type = PRINTER_3DPrinter_UKNOWN; + std::string printer_type; /* model_id */ wxString get_printer_type_display_str(); std::string product_name; // set by iot service, get /user/print @@ -344,6 +359,11 @@ public: long tray_exist_bits = 0; long tray_is_bbl_bits = 0; long tray_read_done_bits = 0; + long tray_reading_bits = 0; + int ams_rfid_status = 0; + bool ams_insert_flag { false }; + bool ams_power_on_flag { false }; + bool ams_support_use_ams { false }; AmsStatusMain ams_status_main; int ams_status_sub; int ams_version = 0; @@ -373,6 +393,9 @@ public: bool is_mapping_exceed_filament(std::vector& result, int &exceed_index); void reset_mapping_result(std::vector& result); + /*online*/ + bool online_rfid; + bool online_ahb; /* temperature */ float nozzle_temp; @@ -413,6 +436,8 @@ public: std::string ota_new_version_number; std::string ahb_new_version_number; std::map module_vers; + std::map new_ver_list; + bool m_new_ver_list_exist = false; int upgrade_err_code = 0; std::vector firmware_list; @@ -568,6 +593,7 @@ public: void set_online_state(bool on_off); bool is_online() { return m_is_online; } bool is_info_ready(); + bool is_function_supported(PrinterFunction func); /* Msg for display MsgFn */ @@ -630,6 +656,13 @@ public: // get alive machine std::map get_local_machine_list(); void load_last_machine(); + + static json function_table; + static std::string parse_printer_type(std::string type_str); + static std::string get_printer_display_name(std::string type_str); + static bool is_function_supported(std::string type_str, std::string function_name); + + static bool load_functional_config(std::string config_file); }; } // namespace Slic3r diff --git a/src/slic3r/GUI/DownloadProgressDialog.cpp b/src/slic3r/GUI/DownloadProgressDialog.cpp index f1af5269d1..1f2fbe7ecb 100644 --- a/src/slic3r/GUI/DownloadProgressDialog.cpp +++ b/src/slic3r/GUI/DownloadProgressDialog.cpp @@ -51,6 +51,8 @@ DownloadProgressDialog::DownloadProgressDialog(wxString title) Layout(); Fit(); CentreOnParent(); + + Bind(wxEVT_CLOSE_WINDOW, &DownloadProgressDialog::on_close, this); } bool DownloadProgressDialog::Show(bool show) @@ -91,6 +93,15 @@ bool DownloadProgressDialog::Show(bool show) return DPIDialog::Show(show); } +void DownloadProgressDialog::on_close(wxCloseEvent& event) +{ + if (m_upgrade_job) { + m_upgrade_job->cancel(); + m_upgrade_job->join(); + } + event.Skip(); +} + DownloadProgressDialog::~DownloadProgressDialog() {} void DownloadProgressDialog::on_dpi_changed(const wxRect &suggested_rect) {} diff --git a/src/slic3r/GUI/DownloadProgressDialog.hpp b/src/slic3r/GUI/DownloadProgressDialog.hpp index fcb44a208d..b35d206d11 100644 --- a/src/slic3r/GUI/DownloadProgressDialog.hpp +++ b/src/slic3r/GUI/DownloadProgressDialog.hpp @@ -33,6 +33,7 @@ class DownloadProgressDialog : public DPIDialog { protected: bool Show(bool show) override; + void on_close(wxCloseEvent& event); public: DownloadProgressDialog(wxString title); @@ -42,7 +43,7 @@ public: void update_release_note(std::string release_note, std::string version); std::shared_ptr m_status_bar; - std::shared_ptr m_upgrade_job; + std::shared_ptr m_upgrade_job { nullptr }; wxPanel * m_panel_download; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index d9d8ef59da..7c49f18ef4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -4385,7 +4385,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv { case EViewType::FeatureType: { - append_headers({_u8L("Line type"), _u8L("Time"), _u8L("Percent"), "", _u8L("Display")}, offsets); + append_headers({_u8L("Line Type"), _u8L("Time"), _u8L("Percent"), "", _u8L("Display")}, offsets); break; } case EViewType::Height: { imgui.title(_u8L("Layer Height (mm)")); break; } @@ -4998,6 +4998,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ImGui::SameLine(); imgui.title(time_title); std::string filament_str = _u8L("Filament"); + std::string cost_str = _u8L("Cost"); std::string prepare_str = _u8L("Prepare time"); std::string print_str = _u8L("Model printing time"); std::string total_str = _u8L("Total"); @@ -5006,7 +5007,10 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv if (time_mode.layers_times.empty()) max_len += ImGui::CalcTextSize(total_str.c_str()).x; else { - max_len += std::max(ImGui::CalcTextSize(print_str.c_str()).x ,std::max(std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x), ImGui::CalcTextSize(filament_str.c_str()).x)); + max_len += std::max(ImGui::CalcTextSize(cost_str.c_str()).x, + std::max(ImGui::CalcTextSize(print_str.c_str()).x, + std::max(std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x), + ImGui::CalcTextSize(filament_str.c_str()).x))); } //BBS display filament cost @@ -5031,6 +5035,17 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair& item) { return role == item.first; }); return (it != time_mode.roles_times.end()) ? it->second : 0.0f; }; + + //BBS: display cost of filaments + ImGui::Dummy({window_padding, window_padding}); + ImGui::SameLine(); + imgui.text(cost_str + ":"); + ImGui::SameLine(max_len); + + //char buf[64]; + ::sprintf(buf, "%.2f", ps.total_cost); + imgui.text(buf); + //BBS: start gcode is prepeare time if (role_time(erCustom) != 0.0f) { ImGui::Dummy({ window_padding, window_padding }); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e8fe125247..6334d6edb1 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -595,6 +595,7 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed) #endif , m_in_render(false) , m_main_toolbar(GLToolbar::Normal, "Main") + , m_separator_toolbar(GLToolbar::Normal, "Separator") , m_assemble_view_toolbar(GLToolbar::Normal, "Assembly_View") , m_return_toolbar() , m_canvas_type(ECanvasType::CanvasView3D) @@ -1021,6 +1022,11 @@ void GLCanvas3D::enable_return_toolbar(bool enable) m_return_toolbar.set_enabled(enable); } +void GLCanvas3D::enable_separator_toolbar(bool enable) +{ + m_separator_toolbar.set_enabled(enable); +} + void GLCanvas3D::enable_dynamic_background(bool enable) { m_dynamic_background_enabled = enable; @@ -2147,7 +2153,7 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); m_event_handlers_bound = true; - + m_canvas->Bind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); m_canvas->Bind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); m_canvas->Bind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); @@ -2184,7 +2190,7 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); m_event_handlers_bound = false; - + m_canvas->Unbind(wxEVT_GESTURE_PAN, &GLCanvas3D::on_gesture, this); m_canvas->Unbind(wxEVT_GESTURE_ZOOM, &GLCanvas3D::on_gesture, this); m_canvas->Unbind(wxEVT_GESTURE_ROTATE, &GLCanvas3D::on_gesture, this); @@ -2292,30 +2298,25 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) case WXK_CONTROL_M: #endif /* __APPLE__ */ { -//#ifdef _WIN32 -// if (wxGetApp().app_config->get("use_legacy_3DConnexion") == "1") { -//#endif //_WIN32 -//#ifdef __APPLE__ -// // On OSX use Cmd+Shift+M to "Show/Hide 3Dconnexion devices settings dialog" -// if ((evt.GetModifiers() & shiftMask) != 0) { -//#endif // __APPLE__ -// -//#ifdef SUPPORT_3D_CONNEXION -// Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller(); -// controller.show_settings_dialog(!controller.is_settings_dialog_shown()); -// m_dirty = true; -//#endif - -//#ifdef __APPLE__ -// } -// else -// // and Cmd+M to minimize application -// wxGetApp().mainframe->Iconize(); -//#endif // __APPLE__ -//#ifdef _WIN32 -// } -//#endif //_WIN32 - post_event(SimpleEvent(EVT_GLTOOLBAR_CLONE)); +#ifdef _WIN32 + if (wxGetApp().app_config->get("use_legacy_3DConnexion") == "true") { +#endif //_WIN32 +#ifdef __APPLE__ + // On OSX use Cmd+Shift+M to "Show/Hide 3Dconnexion devices settings dialog" + if ((evt.GetModifiers() & shiftMask) != 0) { +#endif // __APPLE__ + Mouse3DController& controller = wxGetApp().plater()->get_mouse3d_controller(); + controller.show_settings_dialog(!controller.is_settings_dialog_shown()); + m_dirty = true; +#ifdef __APPLE__ + } + else + // and Cmd+M to minimize application + wxGetApp().mainframe->Iconize(); +#endif // __APPLE__ +#ifdef _WIN32 + } +#endif //_WIN32 break; } #ifdef __APPLE__ @@ -2368,7 +2369,10 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) break; // BBS - case '0': { select_view("topfront"); break; } + case '0': { + select_view("plate"); + zoom_to_bed(); + break; } case '1': { select_view("top"); break; } case '2': { select_view("bottom"); break; } case '3': { select_view("front"); break; } @@ -2711,7 +2715,10 @@ void GLCanvas3D::on_key(wxKeyEvent& evt) switch (keyCode) { case '0': case WXK_NUMPAD0: //0 on numpad - { select_view("topfront"); break; } + { select_view("plate"); + zoom_to_bed(); + break; + } case '1': case WXK_NUMPAD1: //1 on numpad { select_view("top"); break; } @@ -3332,8 +3339,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else rotate_target = volumes_bounding_box().center(); //BBS do not limit rotate in assemble view - //camera.rotate_local_with_target(Vec3d(rot.y(), rot.x(), 0.), rotate_target); - camera.rotate_on_sphere_with_target(rot.x(), rot.y(), true, rotate_target); + camera.rotate_local_with_target(Vec3d(rot.y(), rot.x(), 0.), rotate_target); + //camera.rotate_on_sphere_with_target(rot.x(), rot.y(), false, rotate_target); } else { #ifdef SUPPORT_FEEE_CAMERA @@ -4994,6 +5001,9 @@ bool GLCanvas3D::_init_toolbars() if (!_init_return_toolbar()) return false; + if (!_init_separator_toolbar()) + return false; + #if 0 if (!_init_view_toolbar()) return false; @@ -5134,16 +5144,6 @@ bool GLCanvas3D::_init_main_toolbar() if (!m_main_toolbar.add_item(item)) return false; - GLToolbarItem::Data sperate_item; - sperate_item.name = "seperatetag"; - sperate_item.icon_filename = "seperator.svg"; - sperate_item.sprite_id = ++item.sprite_id; - sperate_item.left.action_callback = [this]() { }; - sperate_item.visibility_callback = []()->bool { return true; }; - sperate_item.enabling_callback = []()->bool { return false; }; - if (!m_main_toolbar.add_item(sperate_item)) - return false; - return true; } @@ -5207,16 +5207,6 @@ bool GLCanvas3D::_init_assemble_view_toolbar() m_assemble_view_toolbar.set_separator_size(10); m_assemble_view_toolbar.set_gap_size(4); - GLToolbarItem::Data sperate_item; - sperate_item.name = "start_seperator"; - sperate_item.icon_filename = "seperator.svg"; - sperate_item.sprite_id = 0; - sperate_item.left.action_callback = [this]() {}; - sperate_item.visibility_callback = []()->bool { return true; }; - sperate_item.enabling_callback = []()->bool { return false; }; - if (!m_assemble_view_toolbar.add_item(sperate_item)) - return false; - GLToolbarItem::Data item; item.name = "assembly_view"; item.icon_filename = "toolbar_assemble.svg"; @@ -5245,6 +5235,45 @@ bool GLCanvas3D::_init_return_toolbar() return m_return_toolbar.init(); } +bool GLCanvas3D::_init_separator_toolbar() +{ + if (!m_separator_toolbar.is_enabled()) + return true; + + + BackgroundTexture::Metadata background_data; + background_data.filename = "toolbar_background.png"; + background_data.left = 0; + background_data.top = 0; + background_data.right = 0; + background_data.bottom = 0; + + if (!m_separator_toolbar.init(background_data)) + { + // unable to init the toolbar texture, disable it + m_separator_toolbar.set_enabled(false); + return true; + } + + m_separator_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); + //BBS: assemble toolbar is at the top and right, we don't need the rounded-corner effect at the left side and the top side + m_separator_toolbar.set_horizontal_orientation(GLToolbar::Layout::HO_Left); + m_separator_toolbar.set_vertical_orientation(GLToolbar::Layout::VO_Top); + m_separator_toolbar.set_border(5.0f); + + GLToolbarItem::Data sperate_item; + sperate_item.name = "start_seperator"; + sperate_item.icon_filename = "seperator.svg"; + sperate_item.sprite_id = 0; + sperate_item.left.action_callback = [this]() {}; + sperate_item.visibility_callback = []()->bool { return true; }; + sperate_item.enabling_callback = []()->bool { return false; }; + if (!m_separator_toolbar.add_item(sperate_item)) + return false; + + return true; +} + // BBS #if 0 @@ -5647,13 +5676,13 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with switch (build_volume.type()) { case BuildVolume::Type::Rectangle: { const BoundingBox3Base bed_bb = build_volume.bounding_volume().inflated(BuildVolume::SceneEpsilon); - m_volumes.set_print_volume({ 0, // circle + m_volumes.set_print_volume({ 0, // Rectangle { float(bed_bb.min.x()), float(bed_bb.min.y()), float(bed_bb.max.x()), float(bed_bb.max.y()) }, { 0.0f, float(build_volume.printable_height()) } }); break; } case BuildVolume::Type::Circle: { - m_volumes.set_print_volume({ 1, // rectangle + m_volumes.set_print_volume({ 1, // Circle { unscaled(build_volume.circle().center.x()), unscaled(build_volume.circle().center.y()), unscaled(build_volume.circle().radius + BuildVolume::SceneEpsilon), 0.0f }, { 0.0f, float(build_volume.printable_height() + BuildVolume::SceneEpsilon) } }); break; @@ -5844,6 +5873,7 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() //BBS: GUI refactor: GLToolbar m_main_toolbar.set_scale(sc); m_assemble_view_toolbar.set_scale(sc); + m_separator_toolbar.set_scale(sc); collapse_toolbar.set_scale(sc); size *= m_retina_helper->get_scale_factor(); @@ -5853,15 +5883,16 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale() //BBS: GUI refactor: GLToolbar m_main_toolbar.set_icons_size(GLGizmosManager::Default_Icons_Size * scale); m_assemble_view_toolbar.set_icons_size(size); + m_separator_toolbar.set_icons_size(size); collapse_toolbar.set_icons_size(size); #endif // ENABLE_RETINA_GL //BBS: GUI refactor: GLToolbar #if BBS_TOOLBAR_ON_TOP - float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : GLToolbar::Default_Icons_Size; - float top_tb_width = m_main_toolbar.get_width() + m_gizmos.get_scaled_total_width() + m_assemble_view_toolbar.get_width() + collapse_toolbar_width; - int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_gizmos.get_selectable_icons_cnt() + m_assemble_view_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt(); + float top_tb_width = m_main_toolbar.get_width() + m_gizmos.get_scaled_total_width() + m_assemble_view_toolbar.get_width() + m_separator_toolbar.get_width() + collapse_toolbar_width; + int items_cnt = m_main_toolbar.get_visible_items_cnt() + m_gizmos.get_selectable_icons_cnt() + m_assemble_view_toolbar.get_visible_items_cnt() + m_separator_toolbar.get_visible_items_cnt() + collapse_toolbar.get_visible_items_cnt(); float noitems_width = top_tb_width - size * items_cnt; // width of separators and borders in top toolbars // calculate scale needed for items in all top toolbars @@ -5917,6 +5948,7 @@ void GLCanvas3D::_render_overlays() //BBS: GUI refactor: GLToolbar m_main_toolbar.set_scale(scale); m_assemble_view_toolbar.set_scale(scale); + m_separator_toolbar.set_scale(scale); wxGetApp().plater()->get_collapse_toolbar().set_scale(scale); m_gizmos.set_overlay_scale(scale); #else @@ -5929,10 +5961,13 @@ void GLCanvas3D::_render_overlays() //BBS: GUI refactor: GLToolbar m_main_toolbar.set_icons_size(gizmo_size); m_assemble_view_toolbar.set_icons_size(gizmo_size); + m_separator_toolbar.set_icons_size(gizmo_size); wxGetApp().plater()->get_collapse_toolbar().set_icons_size(size); m_gizmos.set_overlay_icon_size(gizmo_size); #endif // ENABLE_RETINA_GL + _render_separator_toolbar_right(); + _render_separator_toolbar_left(); _render_main_toolbar(); //BBS: GUI refactor: GLToolbar _render_imgui_select_plate_toolbar(); @@ -6135,8 +6170,9 @@ void GLCanvas3D::_render_main_toolbar() float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; float gizmo_width = m_gizmos.get_scaled_total_width(); float assemble_width = m_assemble_view_toolbar.get_width(); + float separator_width = m_separator_toolbar.get_width(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; + float left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + separator_width + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; #else float gizmo_height = m_gizmos.get_scaled_total_height(); float space_height = GLGizmosManager::Default_Icons_Size * wxGetApp().toolbar_icon_scale(); @@ -6327,8 +6363,9 @@ void GLCanvas3D::_render_assemble_view_toolbar() const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; float gizmo_width = m_gizmos.get_scaled_total_width(); float assemble_width = m_assemble_view_toolbar.get_width(); + float separator_width = m_separator_toolbar.get_width(); float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; - float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; + float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - separator_width - collapse_toolbar_width)) * inv_zoom; float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom; //float left = 0.5f * (m_main_toolbar.get_width() + gizmo_width - m_assemble_view_toolbar.get_width() + collapse_toolbar_width) * inv_zoom; #else @@ -6397,6 +6434,48 @@ void GLCanvas3D::_render_return_toolbar() const imgui.end(); } +void GLCanvas3D::_render_separator_toolbar_right() const +{ + if (!m_separator_toolbar.is_enabled()) + return; + + Size cnv_size = get_canvas_size(); + float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + + GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); + float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + float gizmo_width = m_gizmos.get_scaled_total_width(); + float assemble_width = m_assemble_view_toolbar.get_width(); + float separator_width = m_separator_toolbar.get_width(); + float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width - collapse_toolbar_width)) * inv_zoom; + float left = main_toolbar_left + (m_main_toolbar.get_width() + gizmo_width) * inv_zoom; + + m_separator_toolbar.set_position(top, left); + m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine); +} + +void GLCanvas3D::_render_separator_toolbar_left() const +{ + if (!m_separator_toolbar.is_enabled()) + return; + + Size cnv_size = get_canvas_size(); + float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); + + GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); + float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f; + float gizmo_width = m_gizmos.get_scaled_total_width(); + float assemble_width = m_assemble_view_toolbar.get_width(); + float separator_width = m_separator_toolbar.get_width(); + float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + float main_toolbar_left = std::max(-0.5f * cnv_size.get_width(), -0.5f * (m_main_toolbar.get_width() + gizmo_width + assemble_width + separator_width - collapse_toolbar_width)) * inv_zoom; + float left = main_toolbar_left + (m_main_toolbar.get_width()) * inv_zoom; + + m_separator_toolbar.set_position(top, left); + m_separator_toolbar.render(*this,GLToolbarItem::SeparatorLine); +} + void GLCanvas3D::_render_collapse_toolbar() const { GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar(); @@ -6554,10 +6633,10 @@ void GLCanvas3D::_render_paint_toolbar() const float gray = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]; if (gray < 80){ - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str()); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str()); } else{ ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str()); - } + } } ImGui::AlignTextToFramePadding(); imgui.end(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2d26513d63..a09f4333b6 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -399,6 +399,7 @@ private: GLGizmosManager m_gizmos; //BBS: GUI refactor: GLToolbar mutable GLToolbar m_main_toolbar; + mutable GLToolbar m_separator_toolbar; mutable IMToolbar m_sel_plate_toolbar; mutable GLToolbar m_assemble_view_toolbar; mutable IMReturnToolbar m_return_toolbar; @@ -667,6 +668,7 @@ public: void enable_select_plate_toolbar(bool enable); void enable_assemble_view_toolbar(bool enable); void enable_return_toolbar(bool enable); + void enable_separator_toolbar(bool enable); void enable_dynamic_background(bool enable); void enable_labels(bool enable) { m_labels.enable(enable); } void enable_slope(bool enable) { m_slope.enable(enable); } @@ -686,6 +688,8 @@ public: float get_main_toolbar_width() { return m_main_toolbar.get_width();} float get_assemble_view_toolbar_width() { return m_assemble_view_toolbar.get_width(); } float get_assemble_view_toolbar_height() { return m_assemble_view_toolbar.get_height(); } + float get_separator_toolbar_width() { return m_separator_toolbar.get_width(); } + float get_separator_toolbar_height() { return m_separator_toolbar.get_height(); } float get_collapse_toolbar_width(); float get_collapse_toolbar_height(); @@ -923,6 +927,7 @@ private: bool _update_imgui_select_plate_toolbar(); bool _init_assemble_view_toolbar(); bool _init_return_toolbar(); + bool _init_separator_toolbar(); // BBS //bool _init_view_toolbar(); bool _init_collapse_toolbar(); @@ -967,6 +972,8 @@ private: void _render_imgui_select_plate_toolbar() const; void _render_assemble_view_toolbar() const; void _render_return_toolbar() const; + void _render_separator_toolbar_right() const; + void _render_separator_toolbar_left() const; void _render_collapse_toolbar() const; // BBS //void _render_view_toolbar() const; diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index e0827c9180..c5583c8233 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -538,7 +538,7 @@ bool GLToolbar::update_items_state() return ret; } -void GLToolbar::render(const GLCanvas3D& parent) +void GLToolbar::render(const GLCanvas3D& parent,GLToolbarItem::EType type) { if (!m_enabled || m_items.empty()) return; @@ -549,7 +549,7 @@ void GLToolbar::render(const GLCanvas3D& parent) switch (m_layout.type) { default: - case Layout::Horizontal: { render_horizontal(parent); break; } + case Layout::Horizontal: { render_horizontal(parent,type); break; } case Layout::Vertical: { render_vertical(parent); break; } } } @@ -1386,7 +1386,7 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte } } -void GLToolbar::render_horizontal(const GLCanvas3D& parent) +void GLToolbar::render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType type) { float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom(); float factor = inv_zoom * m_layout.scale; @@ -1404,6 +1404,8 @@ void GLToolbar::render_horizontal(const GLCanvas3D& parent) float left = m_layout.left; float top = m_layout.top; float right = left + scaled_width; + if (type == GLToolbarItem::SeparatorLine) + right = left + scaled_width * 0.5; float bottom = top - scaled_height; render_background(left, top, right, bottom, scaled_border); diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 9ca3868b7b..9fd8ff0724 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -68,6 +68,7 @@ public: //BBS: GUI refactor: GLToolbar ActionWithText, ActionWithTextImage, + SeparatorLine, Num_Types }; @@ -400,7 +401,7 @@ public: // returns true if any item changed its state bool update_items_state(); - void render(const GLCanvas3D& parent); + void render(const GLCanvas3D& parent,GLToolbarItem::EType type = GLToolbarItem::Action); void render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item); bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); @@ -429,7 +430,7 @@ private: int contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const; void render_background(float left, float top, float right, float bottom, float border) const; - void render_horizontal(const GLCanvas3D& parent); + void render_horizontal(const GLCanvas3D& parent,GLToolbarItem::EType type); void render_vertical(const GLCanvas3D& parent); bool generate_icons_texture(); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index da8814e5c6..513d1969b5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1095,6 +1095,9 @@ void GUI_App::post_init() hms_query->check_hms_info(); }); + std::string functional_config_file = Slic3r::resources_dir() + "/config.json"; + DeviceManager::load_functional_config(encode_path(functional_config_file.c_str())); + BOOST_LOG_TRIVIAL(info) << "finished post_init"; //BBS: remove the single instance currently /*#ifdef _WIN32 @@ -1481,6 +1484,19 @@ void GUI_App::restart_networking() BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(" exit, m_agent=%1%")%m_agent; } +void GUI_App::remove_old_networking_plugins() +{ + auto plugin_folder = boost::filesystem::path(wxStandardPaths::Get().GetUserDataDir().ToUTF8().data()) / "plugins"; + if (boost::filesystem::exists(plugin_folder)) { + BOOST_LOG_TRIVIAL(info) << "[remove_old_networking_plugins] remove the directory "<GetEventHandler()->ProcessEvent(e2); + if (e2.GetVeto()) { + e.Veto(); + return; + } + } + for (auto d : dialogStack) + d->EndModal(wxID_CANCEL); + }); + std::map extra_headers = get_extra_header(); Slic3r::Http::set_extra_headers(extra_headers); @@ -1896,10 +1926,20 @@ bool GUI_App::on_init_inner() init_fonts(); if (m_last_config_version) { - if (*m_last_config_version < *Semver::parse(SLIC3R_VERSION)) - check_older_app_config(*m_last_config_version, true); - } else { - check_older_app_config(Semver(), false); + int last_major = m_last_config_version->maj(); + int last_minor = m_last_config_version->min(); + int last_patch = m_last_config_version->patch()/100; + std::string studio_ver = SLIC3R_VERSION; + int cur_major = atoi(studio_ver.substr(0,2).c_str()); + int cur_minor = atoi(studio_ver.substr(3,2).c_str()); + int cur_patch = atoi(studio_ver.substr(6,2).c_str()); + BOOST_LOG_TRIVIAL(info) << boost::format("last app version {%1%.%2%.%3%}, current version {%4%.%5%.%6%}") + %last_major%last_minor%last_patch%cur_major%cur_minor%cur_patch; + if ((last_major != cur_major) + ||(last_minor != cur_minor) + ||(last_patch != cur_patch)) { + remove_old_networking_plugins(); + } } app_config->set("version", SLIC3R_VERSION); @@ -2538,21 +2578,21 @@ float GUI_App::toolbar_icon_scale(const bool is_limited/* = false*/) const const float icon_sc = m_em_unit * 0.1f; #endif // __APPLE__ - return icon_sc; + //return icon_sc; - //const std::string& auto_val = app_config->get("toolkit_size"); + const std::string& auto_val = app_config->get("toolkit_size"); - //if (auto_val.empty()) - // return icon_sc; + if (auto_val.empty()) + return icon_sc; - //int int_val = 100; - //// correct value in respect to toolkit_size - //int_val = std::min(atoi(auto_val.c_str()), int_val); + int int_val = 100; + // correct value in respect to toolkit_size + int_val = std::min(atoi(auto_val.c_str()), int_val); - //if (is_limited && int_val < 50) - // int_val = 50; + if (is_limited && int_val < 50) + int_val = 50; - //return 0.01f * int_val * icon_sc; + return 0.01f * int_val * icon_sc; } void GUI_App::set_auto_toolbar_icon_scale(float scale) const @@ -2911,6 +2951,7 @@ void GUI_App::request_user_logout() m_agent->set_user_selected_machine(""); /* delete old user settings */ m_device_manager->clean_user_info(); + GUI::wxGetApp().sidebar().load_ams_list({}); GUI::wxGetApp().remove_user_presets(); GUI::wxGetApp().stop_sync_user_preset(); } @@ -2920,7 +2961,9 @@ int GUI_App::request_user_unbind(std::string dev_id) { int result = -1; if (m_agent) { - return m_agent->unbind(dev_id); + result = m_agent->unbind(dev_id); + BOOST_LOG_TRIVIAL(info) << "request_user_unbind, dev_id = " << dev_id << ", result = " << result; + return result; } return result; } @@ -3008,6 +3051,31 @@ std::string GUI_App::handle_web_request(std::string cmd) } } } + else if (command_str.compare("homepage_delete_recentfile") == 0) { + if (root.get_child_optional("data") != boost::none) { + pt::ptree data_node = root.get_child("data"); + boost::optional path = data_node.get_optional("path"); + if (path.has_value()) { + this->request_remove_project(path.value()); + } + } + } + else if (command_str.compare("homepage_delete_all_recentfile") == 0) { + this->request_remove_project(""); + } + else if (command_str.compare("homepage_explore_recentfile") == 0) { + if (root.get_child_optional("data") != boost::none) { + pt::ptree data_node = root.get_child("data"); + boost::optional path = data_node.get_optional("path"); + if (path.has_value()) + { + boost::filesystem::path NowFile(path.value()); + + std::string FolderPath = NowFile.parent_path().make_preferred().string(); + desktop_open_any_folder(FolderPath); + } + } + } else if (command_str.compare("homepage_open_hotspot") == 0) { if (root.get_child_optional("data") != boost::none) { pt::ptree data_node = root.get_child("data"); @@ -3042,6 +3110,16 @@ std::string GUI_App::handle_web_request(std::string cmd) wxPostEvent(mainframe, e); } } + else if (command_str.compare("userguide_wiki_open") == 0) { + if (root.get_child_optional("data") != boost::none) { + pt::ptree data_node = root.get_child("data"); + boost::optional path = data_node.get_optional("url"); + if (path.has_value()) { + wxLaunchDefaultBrowser(path.value()); + } + } + } + } } catch (...) { @@ -3116,6 +3194,11 @@ void GUI_App::request_open_project(std::string project_id) CallAfter([this, project_id] { mainframe->open_recent_project(-1, wxString::FromUTF8(project_id)); }); } +void GUI_App::request_remove_project(std::string project_id) +{ + mainframe->remove_recent_project(-1, wxString::FromUTF8(project_id)); +} + void GUI_App::handle_http_error(unsigned int status, std::string body) { // tips body size must less than 1024 @@ -3335,6 +3418,10 @@ void GUI_App::remove_user_presets() { if (preset_bundle && m_agent) { preset_bundle->remove_users_preset(*app_config); + + std::string user_id = m_agent->get_user_id(); + preset_bundle->remove_user_presets_directory(user_id); + //update ui mainframe->update_side_preset_ui(); } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 3f0470e9e0..8a159dfba4 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -376,6 +376,7 @@ public: void download_project(std::string project_id); void request_project_download(std::string project_id); void request_open_project(std::string project_id); + void request_remove_project(std::string project_id); void handle_http_error(unsigned int status, std::string body); void on_http_error(wxCommandEvent &evt); @@ -532,6 +533,7 @@ private: bool on_init_network(bool try_backup = false); void init_networking_callbacks(); void init_app_config(); + void remove_old_networking_plugins(); //BBS set extra header for http request std::map get_extra_header(); void init_http_extra_header(); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 4f1bf04917..38c54f5c31 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -991,6 +991,7 @@ void MenuFactory::create_bbl_part_menu() []() { return plater()->can_split(true); }, m_parent); menu->AppendSeparator(); append_menu_item_per_object_settings(menu); + append_menu_item_change_type(menu); } void MenuFactory::create_bbl_assemble_part_menu() @@ -1320,7 +1321,9 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu) for (int i = 1; i <= filaments_cnt; i++) { - bool is_active_extruder = i == initial_extruder; + // BBS + //bool is_active_extruder = i == initial_extruder; + bool is_active_extruder = false; int icon_idx = i == 0 ? 0 : i - 1; const wxString& item_name = wxString::Format(_L("Filament %d"), i) + diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index b93c0de6a3..944a8b8ecc 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -1842,7 +1842,10 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo new_volume->name = boost::filesystem::path(input_file).filename().string(); // set a default extruder value, since user can't add it manually // BBS - new_volume->config.set_key_value("extruder", new ConfigOptionInt(1)); + int extruder_id = 0; + if (model_object.config.has("extruder")) + extruder_id = model_object.config.opt_int("extruder"); + new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id)); // update source data new_volume->source.input_file = input_file; new_volume->source.object_idx = obj_idx; @@ -1945,7 +1948,10 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode new_volume->name = into_u8(name); // set a default extruder value, since user can't add it manually // BBS - new_volume->config.set_key_value("extruder", new ConfigOptionInt(1)); + int extruder_id = 0; + if (model_object.config.has("extruder")) + extruder_id = model_object.config.opt_int("extruder"); + new_volume->config.set_key_value("extruder", new ConfigOptionInt(extruder_id)); new_volume->source.is_from_builtin_objects = true; select_item([this, obj_idx, new_volume]() { @@ -1962,28 +1968,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx); // apply the instance transform to all volumes and reset instance transform except the offset - { - const Geometry::Transformation &instance_transformation = model_object.instances[0]->get_transformation(); - Vec3d original_instance_center = instance_transformation.get_offset(); - - const Transform3d &transformation_matrix = instance_transformation.get_matrix(); - for (ModelVolume *volume : model_object.volumes) { - const Transform3d &volume_matrix = volume->get_matrix(); - Transform3d new_matrix = transformation_matrix * volume_matrix; - volume->set_transformation(new_matrix); - } - model_object.instances[0]->set_transformation(Geometry::Transformation()); - - model_object.ensure_on_bed(); - // keep new instance center the same as the original center - model_object.translate(-original_instance_center); - model_object.origin_translation += original_instance_center; - model_object.translate_instances(model_object.origin_translation); - model_object.origin_translation = Vec3d::Zero(); - - // update the cache data in selection to keep the data of ModelVolume and GLVolume are consistent - wxGetApp().plater()->update(); - } + apply_object_instance_transfrom_to_all_volumes(&model_object); selection_changed(); @@ -2069,6 +2054,52 @@ void ObjectList::load_mesh_object(const TriangleMesh &mesh, const wxString &name #endif /* _DEBUG */ } +void ObjectList::load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center) +{ + wxDataViewItem item = GetSelection(); + // we can add volumes for Object or Instance + if (!item || !(m_objects_model->GetItemType(item) & (itObject | itInstance))) + return; + const int obj_idx = m_objects_model->GetObjectIdByItem(item); + + if (obj_idx < 0) return; + + // Get object item, if Instance is selected + if (m_objects_model->GetItemType(item) & itInstance) + item = m_objects_model->GetItemById(obj_idx); + + take_snapshot("Load Mesh Part"); + + ModelObject* mo = (*m_objects)[obj_idx]; + + // apply the instance transform to all volumes and reset instance transform except the offset + apply_object_instance_transfrom_to_all_volumes(mo); + + ModelVolume* mv = mo->add_volume(mesh); + Vec3d instance_bbox = mo->mesh().bounding_box().size(); + Vec3d offset = mv->get_offset() + Vec3d(0, 0, instance_bbox[2] / 2); + mv->set_offset(offset); + mv->name = name.ToStdString(); + + std::vector volumes; + volumes.push_back(mv); + wxDataViewItemArray items = reorder_volumes_and_get_selection(obj_idx, [volumes](const ModelVolume* volume) { + return std::find(volumes.begin(), volumes.end(), volume) != volumes.end(); }); + + wxGetApp().plater()->canvas3D()->update_instance_printable_state_for_object((size_t)obj_idx); + + if (items.size() > 1) { + m_selection_mode = smVolume; + m_last_selected_item = wxDataViewItem(nullptr); + } + select_items(items); + + selection_changed(); + + //BBS: notify partplate the modify + notify_instance_updated(obj_idx); +} + //BBS void ObjectList::del_object(const int obj_idx, bool refresh_immediately) { @@ -5006,5 +5037,28 @@ bool ObjectList::has_paint_on_segmentation() return m_objects_model->HasInfoItem(InfoItemType::MmuSegmentation); } +void ObjectList::apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object) { + const Geometry::Transformation &instance_transformation = model_object->instances[0]->get_transformation(); + Vec3d original_instance_center = instance_transformation.get_offset(); + + const Transform3d &transformation_matrix = instance_transformation.get_matrix(); + for (ModelVolume *volume : model_object->volumes) { + const Transform3d &volume_matrix = volume->get_matrix(); + Transform3d new_matrix = transformation_matrix * volume_matrix; + volume->set_transformation(new_matrix); + } + model_object->instances[0]->set_transformation(Geometry::Transformation()); + + model_object->ensure_on_bed(); + // keep new instance center the same as the original center + model_object->translate(-original_instance_center); + model_object->origin_translation += original_instance_center; + model_object->translate_instances(model_object->origin_translation); + model_object->origin_translation = Vec3d::Zero(); + + // update the cache data in selection to keep the data of ModelVolume and GLVolume are consistent + wxGetApp().plater()->update(); +} + } //namespace GUI } //namespace Slic3r diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index dac2698469..0192983ff7 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -281,6 +281,8 @@ public: void load_generic_subobject(const std::string& type_name, const ModelVolumeType type); void load_shape_object(const std::string &type_name); void load_mesh_object(const TriangleMesh &mesh, const wxString &name, bool center = true); + // BBS + void load_mesh_part(const TriangleMesh& mesh, const wxString& name, bool center = true); void del_object(const int obj_idx, bool refresh_immediately = true); void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(const wxDataViewItem& parent_item); @@ -450,6 +452,9 @@ private: void OnEditingStarted(wxDataViewEvent &event); void OnEditingDone(wxDataViewEvent &event); + // apply the instance transform to all volumes and reset instance transform except the offset + void apply_object_instance_transfrom_to_all_volumes(ModelObject *model_object); + std::vector m_columns_width; }; diff --git a/src/slic3r/GUI/GUI_ObjectTable.cpp b/src/slic3r/GUI/GUI_ObjectTable.cpp index 0f07a6d576..9ea452e2d8 100644 --- a/src/slic3r/GUI/GUI_ObjectTable.cpp +++ b/src/slic3r/GUI/GUI_ObjectTable.cpp @@ -73,16 +73,26 @@ void GridCellIconRenderer::Draw(wxGrid& grid, //not changed return; } - if (!table->m_icon_col_width) { + //if (!table->m_icon_col_width) { table->m_icon_row_height = grid.GetRowSize(row); table->m_icon_col_width = grid.GetColSize(col); - } + //} wxBitmap& bitmap = table->get_undo_bitmap(); int bitmap_width = bitmap.GetWidth(); int bitmap_height = bitmap.GetHeight(); int offset_x = (table->m_icon_col_width - bitmap_width)/2; int offset_y = (table->m_icon_row_height - bitmap_height)/2; + + #ifdef __WXOSX_COCOA__ + auto lock_pos = wxPoint(rect.x + offset_x, rect.y + offset_y); + auto left = (28 - 12) / 2; + auto top = (32 - 12) / 2; + lock_pos.x += left; + lock_pos.y += top; + dc.DrawBitmap(bitmap, lock_pos); + #else dc.DrawBitmap(bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y)); + #endif //dc.SetPen(*wxGREEN_PEN); //dc.SetBrush(*wxTRANSPARENT_BRUSH); @@ -148,17 +158,15 @@ void GridCellFilamentsEditor::Create(wxWindow* parent, if ( !m_allowOthers ) style |= wxCB_READONLY; - wxBitmapComboBox *bitmap_combo = new wxBitmapComboBox(parent, id, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - m_choices, - style); + ::ComboBox *bitmap_combo = new ComboBox(parent, id, wxEmptyString, + wxDefaultPosition, wxSize(((*m_icons)[0])->GetWidth() + 10, -1), 0, nullptr, CB_NO_DROP_ICON | CB_NO_TEXT | wxCB_READONLY); if (m_icons) { int array_count = m_choices.GetCount(); int icon_count = m_icons->size(); for (int i = 0; i < array_count; i++) { wxBitmap* bitmap = (i < icon_count) ? (*m_icons)[i] : (*m_icons)[0]; - bitmap_combo->SetItemBitmap(i, *bitmap); + bitmap_combo->Append(m_choices[i], *bitmap); } } m_control = bitmap_combo; @@ -214,7 +222,10 @@ void GridCellFilamentsEditor::BeginEdit(int row, int col, wxGrid* grid) } //m_value = grid->GetTable()->GetValue(row, col); - Reset(); // this updates combo box to correspond to m_value + //Reset(); // this updates combo box to correspond to m_value + int pos = Combo()->FindString(m_value); + if (pos == wxNOT_FOUND) pos = 0; + Combo()->SetSelection(pos); Combo()->SetFocus(); @@ -223,7 +234,7 @@ void GridCellFilamentsEditor::BeginEdit(int row, int col, wxGrid* grid) // choice is made in it under OS X. The bug is almost certainly due to a // problem in focus events generation logic but it's not obvious to fix and // for now this at least allows to use wxGrid. - Combo()->Popup(); + //Combo()->Popup(); #endif if (evtHandler) @@ -254,7 +265,6 @@ bool GridCellFilamentsEditor::EndEdit(int WXUNUSED(row), return true; } - wxGridActivationResult GridCellFilamentsEditor::TryActivate(int row, int col, wxGrid* grid, const wxGridActivationSource& actSource) { ObjectGridTable *table = dynamic_cast(grid->GetTable()); @@ -305,55 +315,222 @@ void GridCellFilamentsEditor::DoActivate(int row, int col, wxGrid* grid) } } -// ---------------------------------------------------------------------------- -// GridCellFilamentsRenderer -// ---------------------------------------------------------------------------- -void GridCellFilamentsRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected) +void GridCellFilamentsRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected) { - ObjectGridTable *table = dynamic_cast(grid.GetTable()); - wxRect text_rect = rect; + ObjectGridTable *table = dynamic_cast(grid.GetTable()); + wxRect text_rect = rect; if (table) { - ObjectGridTable::ObjectGridCol* grid_col = table->get_grid_col(col); - ObjectGridTable::ObjectGridRow* grid_row = table->get_grid_row(row - 1); - ConfigOptionInt& cur_option = dynamic_cast((*grid_row)[(ObjectGridTable::GridColType)col]); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + ConfigOptionInt & cur_option = dynamic_cast((*grid_row)[(ObjectGridTable::GridColType) col]); - wxBitmap* bitmap = table->get_color_bitmap((cur_option.value >= 1)?cur_option.value-1:cur_option.value); - int bitmap_width = bitmap->GetWidth(); - int bitmap_height = bitmap->GetHeight(); - int offset_x = grid_cell_border_width; - int offset_y = (rect.height > bitmap_height)?(rect.height - bitmap_height)/2 : grid_cell_border_height; + wxBitmap *bitmap = table->get_color_bitmap((cur_option.value >= 1) ? cur_option.value - 1 : cur_option.value); + int bitmap_width = bitmap->GetWidth(); + int bitmap_height = bitmap->GetHeight(); + int offset_x = grid_cell_border_width; + int offset_y = (rect.height > bitmap_height) ? (rect.height - bitmap_height) / 2 : grid_cell_border_height; dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(wxBrush(attr.GetBackgroundColour())); dc.DrawRectangle(rect); dc.DrawBitmap(*bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y)); - text_rect.x += bitmap_width + grid_cell_border_width *2; - text_rect.width -= (bitmap_width + grid_cell_border_width *2); + text_rect.x += bitmap_width + grid_cell_border_width * 2; + text_rect.width -= (bitmap_width + grid_cell_border_width * 2); + } + + //wxGridCellChoiceRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); +} + +wxSize GridCellFilamentsRenderer::GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int WXUNUSED(row), int WXUNUSED(col)) +{ + wxSize size{48, -1}; + return size; +} + +GridCellFilamentsRenderer *GridCellFilamentsRenderer::Clone() const { return new GridCellFilamentsRenderer(); } + +// ---------------------------------------------------------------------------- +// GridCellFilamentsRenderer +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// GridCellChoiceEditor +// ---------------------------------------------------------------------------- + +GridCellChoiceEditor::GridCellChoiceEditor(const wxArrayString &choices) + : wxGridCellChoiceEditor(choices) +{} + +GridCellChoiceEditor::GridCellChoiceEditor(size_t count, const wxString choices[]) + : wxGridCellChoiceEditor(count, choices) +{} + +wxGridCellEditor *GridCellChoiceEditor::Clone() const +{ + GridCellChoiceEditor *editor = new GridCellChoiceEditor; + editor->m_allowOthers = m_allowOthers; + editor->m_choices = m_choices; + + return editor; +} + +void GridCellChoiceEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + int style = wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxBORDER_NONE; + + if (!m_allowOthers) style |= wxCB_READONLY; + ::ComboBox *bitmap_combo = new ComboBox(parent, id, wxEmptyString, wxDefaultPosition, wxSize(100, -1), 0, nullptr, wxCB_READONLY); + bitmap_combo->SetFont(::Label::Body_12); + int array_count = m_choices.GetCount(); + for (int i = 0; i < array_count; i++) { + bitmap_combo->Append(m_choices[i]); + } + m_control = bitmap_combo; + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void GridCellChoiceEditor::SetSize(const wxRect &rect) +{ + wxGridCellChoiceEditor::SetSize(rect); +} + +void GridCellChoiceEditor::OnComboCloseUp(wxCommandEvent &evt) { wxGridCellChoiceEditor::OnComboCloseUp(evt); } + +void GridCellChoiceEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + wxGridCellEditorEvtHandler *evtHandler = NULL; + if (m_control) { + // This event handler is needed to properly dismiss the editor when the popup is closed + m_control->Bind(wxEVT_COMBOBOX_CLOSEUP, &GridCellChoiceEditor::OnComboCloseUp, this); + evtHandler = wxDynamicCast(m_control->GetEventHandler(), wxGridCellEditorEvtHandler); + } + + // Don't immediately end if we get a kill focus event within BeginEdit + if (evtHandler) evtHandler->SetInSetFocus(true); + + m_value = grid->GetTable()->GetValue(row, col); + + // Reset(); // this updates combo box to correspond to m_value + int pos = Combo()->FindString(m_value); + if (pos == wxNOT_FOUND) pos = 0; + Combo()->SetSelection(pos); + + Combo()->SetFocus(); + +#ifdef __WXOSX_COCOA__ + // This is a work around for the combobox being simply dismissed when a + // choice is made in it under OS X. The bug is almost certainly due to a + // problem in focus events generation logic but it's not obvious to fix and + // for now this at least allows to use wxGrid. + //Combo()->Popup(); +#endif + + if (evtHandler) { + // When dropping down the menu, a kill focus event + // happens after this point, so we can't reset the flag yet. +#if !defined(__WXGTK20__) + evtHandler->SetInSetFocus(false); +#endif + } +} + +bool GridCellChoiceEditor::EndEdit(int WXUNUSED(row), int WXUNUSED(col), const wxGrid *WXUNUSED(grid), const wxString &WXUNUSED(oldval), wxString *newval) +{ + const wxString value = Combo()->GetValue(); + if (value == m_value) return false; + + m_value = value; + + if (newval) *newval = value; + + return true; +} + +wxGridActivationResult GridCellChoiceEditor::TryActivate(int row, int col, wxGrid *grid, const wxGridActivationSource &actSource) +{ + ObjectGridTable * table = dynamic_cast(grid->GetTable()); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + + if (actSource.GetOrigin() == wxGridActivationSource::Key) { + const wxKeyEvent &key_event = actSource.GetKeyEvent(); + int keyCode = key_event.GetKeyCode(); + wxString choice; + + int digital_value = keyCode - '0'; + if ((digital_value >= 1) && (digital_value <= 9)) + m_cached_value = digital_value; + else + m_cached_value = -1; + + if (m_cached_value != -1) { + if (m_cached_value <= grid_col->choice_count) { + choice = grid_col->choices[m_cached_value - 1]; + return wxGridActivationResult::DoChange(choice); + } else { + return wxGridActivationResult::DoNothing(); + } + } else + return wxGridActivationResult::DoNothing(); + } else { + m_cached_value = -1; + return wxGridActivationResult::DoEdit(); + } +} + +void GridCellChoiceEditor::DoActivate(int row, int col, wxGrid *grid) +{ + if (m_cached_value != -1) { + ObjectGridTable * table = dynamic_cast(grid->GetTable()); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + if (m_cached_value <= grid_col->choice_count) { + wxString choice = grid_col->choices[m_cached_value - 1]; + table->SetValue(row, col, choice); + // Combo()->SetValue(choice); + } + m_cached_value = -1; + } +} + +void GridCellComboBoxRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected) +{ + ObjectGridTable *table = dynamic_cast(grid.GetTable()); + wxRect text_rect = rect; + + if (table) { + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + ConfigOptionInt & cur_option = dynamic_cast((*grid_row)[(ObjectGridTable::GridColType) col]); + + wxBitmap *bitmap = table->get_color_bitmap((cur_option.value >= 1) ? cur_option.value - 1 : cur_option.value); + int bitmap_width = bitmap->GetWidth(); + int bitmap_height = bitmap->GetHeight(); + int offset_x = grid_cell_border_width; + int offset_y = (rect.height > bitmap_height) ? (rect.height - bitmap_height) / 2 : grid_cell_border_height; + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(wxBrush(attr.GetBackgroundColour())); + dc.DrawRectangle(rect); + dc.DrawBitmap(*bitmap, wxPoint(rect.x + offset_x, rect.y + offset_y)); + text_rect.x += bitmap_width + grid_cell_border_width * 2; + text_rect.width -= (bitmap_width + grid_cell_border_width * 2); } wxGridCellChoiceRenderer::Draw(grid, attr, dc, text_rect, row, col, isSelected); } -wxSize GridCellFilamentsRenderer::GetBestSize(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - int WXUNUSED(row), - int WXUNUSED(col)) +wxSize GridCellComboBoxRenderer::GetBestSize(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, int WXUNUSED(row), int WXUNUSED(col)) { - wxSize size{128, -1}; + wxSize size{48, -1}; return size; } -GridCellFilamentsRenderer *GridCellFilamentsRenderer::Clone() const -{ - return new GridCellFilamentsRenderer(); -} +GridCellComboBoxRenderer *GridCellComboBoxRenderer::Clone() const { return new GridCellComboBoxRenderer(); } + + + // ---------------------------------------------------------------------------- // wxGridCellSupportEditor @@ -466,7 +643,58 @@ void GridCellSupportRenderer::Draw(wxGrid& grid, wxRendererNative::Get().DrawCheckBox( &grid, dc, text_rect, flags ); }*/ - wxGridCellBoolRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + + //wxGridCellBoolRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + + ObjectGridTable * table = dynamic_cast(grid.GetTable()); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + ConfigOptionBool & cur_option = dynamic_cast((*grid_row)[(ObjectGridTable::GridColType) col]); + + auto height = grid.GetRowSize(row); + auto width = grid.GetColSize(col); + + wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + if (cur_option.value) { + + auto check_on = create_scaled_bitmap("check_on", nullptr, 18); + dc.SetPen(*wxTRANSPARENT_PEN); + + auto offsetx = 0; + auto offsety = 0; + + #ifdef __WXOSX_MAC__ + offsetx = (width - 18) / 2; + offsety = (height - 18) / 2; + #else + offsetx = (width - check_on.GetSize().x) / 2; + offsety = (height - check_on.GetSize().y) / 2; + #endif // __WXOSX_MAC__ + + dc.DrawBitmap(check_on, rect.x + offsetx, rect.y + offsety); + //dc.SetBrush(wxBrush(wxColour(0x00, 0xAE, 0x42))); + //dc.DrawBitmap(check_on, (width - check_on.GetSize().x) / 2, (height - check_on.GetSize().y) / 2); + } else { + auto check_off = create_scaled_bitmap("check_off_focused", nullptr, 18); + dc.SetPen(*wxTRANSPARENT_PEN); + + auto offsetx = 0; + auto offsety = 0; + + #ifdef __WXOSX_MAC__ + offsetx = (width - 18) / 2; + offsety = (height - 18) / 2; + #else + offsetx = (width - check_off.GetSize().x) / 2; + offsety = (height - check_off.GetSize().y) / 2; + #endif // __WXOSX_MAC__ + + + + dc.DrawBitmap(check_off, rect.x + offsetx, rect.y + offsety); + //dc.SetBrush(wxBrush(wxColour(0x00, 0xAE, 0x42))); + //dc.DrawBitmap(check_off, (width - check_off.GetSize().x) / 2, (height - check_off.GetSize().y) / 2); + } } wxSize GridCellSupportRenderer::GetBestSize(wxGrid& grid, @@ -1497,6 +1725,7 @@ wxString ObjectGridTable::convert_filament_string(int index, wxString& filament_ else result_str = filament_str; + result_str = ""; return result_str; } @@ -1515,12 +1744,12 @@ void ObjectGridTable::init_cols(ObjectGrid *object_grid) // printable for object - ObjectGridCol* col = new ObjectGridCol(coBool, "printable", ObjectGridTable::category_all, true, false, true, false, wxALIGN_CENTRE); + ObjectGridCol *col = new ObjectGridCol(coBool, "printable", ObjectGridTable::category_all, true, false, true, false, wxALIGN_CENTRE); col->size = object_grid->GetTextExtent(L("Printable")).x; m_col_data.push_back(col); // reset icon for printable - col = new ObjectGridCol(coBool, "printable_reset", ObjectGridTable::category_all, true, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coBool, "printable_reset", ObjectGridTable::category_all, true, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); //first column for plate_index @@ -1532,7 +1761,7 @@ void ObjectGridTable::init_cols(ObjectGrid *object_grid) m_col_data.push_back(col);*/ //3th column: for object/volume name - col = new ObjectGridCol(coString, "name", ObjectGridTable::category_all, false, false, true, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coString, "name", ObjectGridTable::category_all, false, false, true, false, wxALIGN_LEFT); col->size = 200; m_col_data.push_back(col); @@ -1549,21 +1778,21 @@ void ObjectGridTable::init_cols(ObjectGrid *object_grid) m_col_data.push_back(col); //object layer height - col = new ObjectGridCol(coFloat, "layer_height", L("Quality"), true, false, true, true, wxALIGN_CENTRE); - col->size = object_grid->GetTextExtent(L("Layer height")).x; + col = new ObjectGridCol(coFloat, "layer_height", L("Quality"), true, false, true, true, wxALIGN_CENTRE); + col->size = object_grid->GetTextExtent(L("Layer height")).x - 28; m_col_data.push_back(col); //reset icon for extruder_id - col = new ObjectGridCol(coFloat, "layer_height_reset", L("Quality"), true, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coFloat, "layer_height_reset", L("Quality"), true, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); //object/volume perimeters - col = new ObjectGridCol(coInt, "wall_loops", L("Strength"), false, false, true, true, wxALIGN_CENTRE); + col = new ObjectGridCol(coInt, "wall_loops", L("Strength"), false, false, true, true, wxALIGN_CENTRE); col->size = object_grid->GetTextExtent(L("Wall loops")).x; m_col_data.push_back(col); //reset icon for perimeters - col = new ObjectGridCol(coInt, "wall_loops_reset", L("Strength"), false, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coInt, "wall_loops_reset", L("Strength"), false, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); //object/volume fill density @@ -1572,7 +1801,7 @@ void ObjectGridTable::init_cols(ObjectGrid *object_grid) m_col_data.push_back(col); //reset icon for fill density - col = new ObjectGridCol(coPercent, "fill_density_reset", L("Strength"), false, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coPercent, "fill_density_reset", L("Strength"), false, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); //support material @@ -1585,23 +1814,23 @@ void ObjectGridTable::init_cols(ObjectGrid *object_grid) m_col_data.push_back(col); //Bed Adhesion - col = new ObjectGridCol(coEnum, "brim_type", L("Support"), true, false, true, true, wxALIGN_CENTRE); + col = new ObjectGridCol(coEnum, "brim_type", L("Support"), true, false, true, true, wxALIGN_LEFT); col->size = object_grid->GetTextExtent(L("Auto Brim")).x + 8; //add 8 for border col->choices = brim_choices; col->choice_count = WXSIZEOF(brim_choices); m_col_data.push_back(col); //reset icon for Bed Adhesion - col = new ObjectGridCol(coEnum, "brim_type_reset", L("Support"), true, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coEnum, "brim_type_reset", L("Support"), true, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); //object/volume speed - col = new ObjectGridCol(coFloat, "inner_wall_speed", L("Speed"), false, false, true, true, wxALIGN_CENTRE); + col = new ObjectGridCol(coFloat, "inner_wall_speed", L("Speed"), false, false, true, true, wxALIGN_LEFT); col->size = object_grid->GetTextExtent(L("Inner wall speed")).x; m_col_data.push_back(col); //reset icon for speed - col = new ObjectGridCol(coFloat, "inner_wall_speed_reset", L("Speed"), false, true, false, false, wxALIGN_CENTRE); + col = new ObjectGridCol(coFloat, "inner_wall_speed_reset", L("Speed"), false, true, false, false, wxALIGN_LEFT); m_col_data.push_back(col); return; @@ -1922,17 +2151,20 @@ void ObjectGridTable::update_row_properties() switch (grid_col->type) { case coString: - grid_table->SetCellEditor(row, col, new wxGridCellAutoWrapStringEditor()); - grid_table->SetCellRenderer(row, col, new wxGridCellAutoWrapStringRenderer()); + if (col == ObjectGridTable::col_plate_index) + grid_table->SetReadOnly(row, col); + grid_table->SetCellEditor(row, col, new GridCellTextEditor()); + //grid_table->SetCellRenderer(row, col, new wxGridCellAutoWrapStringRenderer()); + grid_table->SetCellFitMode(row, col, wxGridFitMode::Ellipsize()); break; case coBool: grid_table->SetCellEditor(row, col, new GridCellSupportEditor()); //grid_table->SetCellEditor(row, col, new wxGridCellBoolEditor()); //grid_table->SetCellRenderer(row, col, new GridCellSupportRenderer()); - grid_table->SetCellRenderer(row, col, new wxGridCellBoolRenderer()); + grid_table->SetCellRenderer(row, col, new GridCellSupportRenderer()); break; case coInt: - grid_table->SetCellEditor(row, col, new wxGridCellNumberEditor()); + grid_table->SetCellEditor(row, col, new GridCellTextEditor()); grid_table->SetCellRenderer(row, col, new wxGridCellNumberRenderer()); break; case coEnum: @@ -1940,26 +2172,21 @@ void ObjectGridTable::update_row_properties() GridCellFilamentsEditor *filament_editor = new GridCellFilamentsEditor(grid_col->choice_count, grid_col->choices, false, &m_panel->m_color_bitmaps); grid_table->SetCellEditor(row, col, filament_editor); grid_table->SetCellRenderer(row, col, new GridCellFilamentsRenderer()); - } - else - grid_table->SetCellEditor(row, col, new wxGridCellChoiceEditor(grid_col->choice_count, grid_col->choices)); + } else { + GridCellChoiceEditor *combo_editor = new GridCellChoiceEditor(grid_col->choice_count, grid_col->choices); + grid_table->SetCellEditor(row, col, combo_editor); + grid_table->SetCellRenderer(row, col, new wxGridCellChoiceRenderer()); + //new wxGridCellChoiceEditor(grid_col->choice_count, grid_col->choices)); + } break; case coFloat: - grid_table->SetCellEditor(row, col, new wxGridCellFloatEditor(6,2)); - grid_table->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,2)); + grid_table->SetCellEditor(row, col, new GridCellTextEditor()); + grid_table->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,1)); break; case coPercent: { - /*wxGridCellFloatEditor *float_editor = new wxGridCellFloatEditor(6,2); - wxFloatingPointValidator *float_validator = new wxFloatingPointValidator(3, nullptr, wxNUM_VAL_ZERO_AS_BLANK); - float_validator->SetRange(0.f, 100.f); - float_editor->SetValidator(*float_validator); - - if (rows < 3) - m_object_grid->SetCellEditor(row, col, float_editor); - else*/ - grid_table->SetCellEditor(row, col, new wxGridCellFloatEditor(6,2)); - grid_table->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,2)); + grid_table->SetCellEditor(row, col, new GridCellTextEditor()); + grid_table->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,1)); break; } default: @@ -2049,7 +2276,7 @@ void ObjectGridTable::sort_row_data(compare_row_func sort_func) std::copy(new_grid_rows.begin(), new_grid_rows.end(), m_grid_data.begin()); new_grid_rows.clear(); - update_row_properties(); + //update_row_properties(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" finished, this %1%, row_data size %2%") %this % m_grid_data.size(); } @@ -2165,7 +2392,7 @@ bool ObjectGridTable::OnCellLeftClick(int row, int col, ConfigOptionType &type) if (row == 0) { sort_by_col(col); - } else if (col >= col_name) { + } else if (col >= col_printable_reset) { ObjectGridRow *grid_row = m_grid_data[row - 1]; ObjectGridCol* grid_col = m_col_data[col]; ObjectGridCol* grid_col_2 = m_col_data[col - 1]; @@ -2401,11 +2628,10 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi //m_object_grid_table->SetAttrProvider(new MyGridCellAttrProvider); //m_object_grid->AssignTable(m_object_grid_table); - - m_side_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(460),FromDIP(480)), wxVSCROLL); + m_side_window = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(440),FromDIP(480)), wxVSCROLL); m_side_window->SetScrollRate( 0, 5 ); m_page_sizer = new wxBoxSizer(wxVERTICAL); - m_page_top_sizer = new wxBoxSizer(wxHORIZONTAL); + //m_page_top_sizer = new wxBoxSizer(wxHORIZONTAL); m_side_window->SetBackgroundColour(wxColour(0xff, 0xff, 0xff)); m_side_window->SetSizer(m_page_sizer); m_side_window->SetScrollbars(1, 20, 1, 2); @@ -2444,7 +2670,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi m_side_window->SetFont(::Label::Body_12); m_object_settings = new ObjectTableSettings(m_side_window, m_object_grid_table); m_object_settings->Hide(); - m_page_sizer->Add(m_page_top_sizer, 0, wxEXPAND | wxALIGN_CENTER_HORIZONTAL, 0); + //m_page_sizer->Add(m_page_top_sizer, 0, wxALIGN_CENTER_HORIZONTAL, 0); m_page_sizer->Add(m_object_settings->get_sizer(), 1, wxEXPAND | wxALL, 2 ); auto m_line_left = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(1,-1), wxTAB_TRAVERSAL); @@ -2464,7 +2690,7 @@ ObjectTablePanel::ObjectTablePanel( wxWindow* parent, wxWindowID id, const wxPoi int ObjectTablePanel::init_bitmap() { - m_undo_bitmap = create_scaled_bitmap("lock_normal", nullptr, 24); + m_undo_bitmap = create_scaled_bitmap("lock_normal", nullptr, 18); m_color_bitmaps = get_extruder_color_icons(); return 0; @@ -2535,33 +2761,39 @@ void ObjectTablePanel::load_data() //construct tables //m_object_grid->CreateGrid(rows, cols, wxGridSelectCells); #if HAS_COL_HEADER - m_object_grid->SetColLabelValue(ObjectGridTable::col_printable, L("Printable")); + m_object_grid->SetColLabelAlignment(wxALIGN_LEFT, wxALIGN_CENTER); + + m_object_grid->SetColLabelValue(ObjectGridTable::col_printable, _L("Printable")); m_object_grid->SetColLabelValue(ObjectGridTable::col_printable_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_plate_index, L("Plate")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_plate_index, _L("Plate")); /*m_object_grid->SetColLabelValue(ObjectGridTable::col_assemble_name, L("Module"));*/ - m_object_grid->SetColLabelValue(ObjectGridTable::col_name, L("Name")); - m_object_grid->SetColLabelValue(ObjectGridTable::col_filaments, L("Filament")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_name, _L("Name")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_filaments, _L("Filament")); m_object_grid->SetColLabelValue(ObjectGridTable::col_filaments_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_layer_height, L("Layer height")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_layer_height, _L("Layer height")); m_object_grid->SetColLabelValue(ObjectGridTable::col_layer_height_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_wall_loops, L("Wall loops")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_wall_loops, _L("Wall loops")); m_object_grid->SetColLabelValue(ObjectGridTable::col_wall_loops_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_fill_density, L("Infill density(%)")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_fill_density, _L("Infill density(%)")); m_object_grid->SetColLabelValue(ObjectGridTable::col_fill_density_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_enable_support, L("Support")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_enable_support, _L("Support")); m_object_grid->SetColLabelValue(ObjectGridTable::col_enable_support_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_brim_type, L("Brim")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_brim_type, _L("Brim")); m_object_grid->SetColLabelValue(ObjectGridTable::col_brim_type_reset, ""); - m_object_grid->SetColLabelValue(ObjectGridTable::col_speed_perimeter, L("Inner wall speed")); + m_object_grid->SetColLabelValue(ObjectGridTable::col_speed_perimeter, _L("Inner wall speed")); m_object_grid->SetColLabelValue(ObjectGridTable::col_speed_perimeter_reset, ""); m_object_grid->SetLabelFont(Label::Head_13); m_object_grid->SetLabelTextColour(wxColour(0x30,0x3a,0x3c)); - m_object_grid->SetLabelBackgroundColour(wxColour(0xff,0xff,0xff)); + m_object_grid->SetLabelBackgroundColour(wxColour(0xff, 0xff, 0xff)); #else m_object_grid->HideColLabels(); #endif m_object_grid->HideRowLabels(); - m_object_grid->EnableGridLines (true); + + m_object_grid->EnableGridLines (false); + m_object_grid->EnableDragColSize(false); + m_object_grid->EnableDragGridSize(false); + m_object_grid->EnableDragRowSize(false); /*set the first row as label*/ //format @@ -2570,7 +2802,7 @@ void ObjectTablePanel::load_data() //attr->SetBackgroundColour(wxColour(191, 191, 255)); attr->SetBackgroundColour(*wxWHITE); attr->SetTextColour(*wxBLACK); - attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE); + attr->SetAlignment(wxALIGN_LEFT, wxALIGN_CENTRE); attr->SetReadOnly(true); m_object_grid->SetRowAttr (0, attr); #if HAS_COL_HEADER @@ -2580,7 +2812,7 @@ void ObjectTablePanel::load_data() m_object_grid->SetCellSize(0, ObjectGridTable::col_printable, 1, 2); //m_object_grid->SetCellSize(0, ObjectGridTable::col_assemble_name, 1, 1); m_object_grid->SetCellSize(0, ObjectGridTable::col_name, 1, 1); - m_object_grid->SetCellSize(0, ObjectGridTable::col_filaments, 1, 2); + m_object_grid->SetCellSize(0, ObjectGridTable::col_filaments, 1, 1); m_object_grid->SetCellSize(0, ObjectGridTable::col_layer_height, 1, 2); m_object_grid->SetCellSize(0, ObjectGridTable::col_wall_loops, 1, 2); m_object_grid->SetCellSize(0, ObjectGridTable::col_fill_density, 1, 2); @@ -2588,14 +2820,8 @@ void ObjectTablePanel::load_data() m_object_grid->SetCellSize(0, ObjectGridTable::col_brim_type, 1, 2); m_object_grid->SetCellSize(0, ObjectGridTable::col_speed_perimeter, 1, 2); - //m_object_grid->SetSelectionForeground(wxColour(255, 0, 0)); - //m_object_grid->SetSelectionBackground(wxColour(0, 255, 0)); - //wxGridCellAutoWrapStringEditor* string_editor = new wxGridCellAutoWrapStringEditor(); - //wxGridCellBoolEditor* bool_editor = new wxGridCellBoolEditor(); - //wxGridCellFloatEditor* float_editor = new wxGridCellFloatEditor(); - //wxGridCellNumberEditor* number_editor = new wxGridCellNumberEditor(); - //wxGridCellChoiceEditor* choice_editor = new wxGridCellChoiceEditor(); - //wxGridCellEnumEditor* enum_editor = new wxGridCellEnumEditor(); + //m_object_grid->SetSelectionForeground(wxColour(0xDB,0xFD,0xE7)); + //m_object_grid->SetSelectionBackground(*wxWHITE); for (int col = 0; col < cols; col++) { @@ -2627,45 +2853,39 @@ void ObjectTablePanel::load_data() switch (grid_col->type) { case coString: - m_object_grid->SetCellEditor(row, col, new wxGridCellAutoWrapStringEditor()); - m_object_grid->SetCellRenderer(row, col, new wxGridCellAutoWrapStringRenderer()); + m_object_grid->SetCellEditor(row, col, new GridCellTextEditor()); + //m_object_grid->SetCellRenderer(row, col, new wxGridCellAutoWrapStringRenderer()); + m_object_grid->SetCellFitMode(row, col, wxGridFitMode::Ellipsize()); break; case coBool: m_object_grid->SetCellEditor(row, col, new GridCellSupportEditor()); //m_object_grid->SetCellEditor(row, col, new wxGridCellBoolEditor()); //m_object_grid->SetCellRenderer(row, col, new GridCellSupportRenderer()); - m_object_grid->SetCellRenderer(row, col, new wxGridCellBoolRenderer()); + m_object_grid->SetCellRenderer(row, col, new GridCellSupportRenderer()); break; case coInt: - m_object_grid->SetCellEditor(row, col, new wxGridCellNumberEditor()); + m_object_grid->SetCellEditor(row, col, new GridCellTextEditor()); m_object_grid->SetCellRenderer(row, col, new wxGridCellNumberRenderer()); break; case coEnum: if (col == ObjectGridTable::col_filaments) { GridCellFilamentsEditor *filament_editor = new GridCellFilamentsEditor(grid_col->choice_count, grid_col->choices, false, &m_color_bitmaps); m_object_grid->SetCellEditor(row, col, filament_editor); - //m_object_grid->SetCellEditor(row, col, new wxGridCellChoiceEditor(grid_col->choice_count, grid_col->choices)); m_object_grid->SetCellRenderer(row, col, new GridCellFilamentsRenderer()); + } else { + GridCellChoiceEditor *combo_editor = new GridCellChoiceEditor(grid_col->choice_count, grid_col->choices); + m_object_grid->SetCellEditor(row, col, combo_editor); + m_object_grid->SetCellRenderer(row, col, new wxGridCellChoiceRenderer()); } - else - m_object_grid->SetCellEditor(row, col, new wxGridCellChoiceEditor(grid_col->choice_count, grid_col->choices)); break; case coFloat: - m_object_grid->SetCellEditor(row, col, new wxGridCellFloatEditor(6,2)); - m_object_grid->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,2)); + m_object_grid->SetCellEditor(row, col, new GridCellTextEditor()); + m_object_grid->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,1)); break; case coPercent: { - /*wxGridCellFloatEditor *float_editor = new wxGridCellFloatEditor(6,2); - wxFloatingPointValidator *float_validator = new wxFloatingPointValidator(3, nullptr, wxNUM_VAL_ZERO_AS_BLANK); - float_validator->SetRange(0.f, 100.f); - float_editor->SetValidator(*float_validator); - - if (rows < 3) - m_object_grid->SetCellEditor(row, col, float_editor); - else*/ - m_object_grid->SetCellEditor(row, col, new wxGridCellFloatEditor(6,2)); - m_object_grid->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,2)); + m_object_grid->SetCellEditor(row, col, new GridCellTextEditor()); + m_object_grid->SetCellRenderer(row, col, new wxGridCellFloatRenderer(6,1)); break; } default: @@ -2681,34 +2901,98 @@ void ObjectTablePanel::load_data() } } } - m_object_grid->Fit(); + for (int i = 0; i < ObjectGridTable::col_max; i++) { ObjectGridTable::ObjectGridCol *grid_col = m_object_grid_table->get_grid_col(i); if (grid_col->size > 0) { int fit_size1 = m_object_grid->GetColSize(i); m_object_grid->SetColSize(i, grid_col->size); - //if (grid_col->size < fit_size1) m_object_grid->SetColSize(i, grid_col->size); + } + } + m_object_grid->Fit(); + + for (int i = 0; i < ObjectGridTable::col_max; i++) { + switch (i) { + case ObjectGridTable::col_printable: { + m_object_grid->SetColSize(i, m_object_grid->GetColSize(i) - FromDIP(28)); + break; } - //else { - //adjust the left col - //int delta = grid_col->size - fit_size1; - //grid_col = m_object_grid_table->get_grid_col(i - 1); - //int fit_size2 = m_object_grid->GetColSize(i-1); - //grid_col->size = fit_size2 - delta; - //m_object_grid->SetColSize(i, grid_col->size); - //} + case ObjectGridTable::col_printable_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_name: + m_object_grid->SetColSize(i, FromDIP(100)); + break; + + case ObjectGridTable::col_filaments: + m_object_grid->SetColSize(i, FromDIP(52)); + break; + + case ObjectGridTable::col_filaments_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_layer_height: { + auto width = m_object_grid->GetColSize(i) - FromDIP(28); + if (width < m_object_grid->GetTextExtent(("000.00")).x) { + width = m_object_grid->GetTextExtent(("000.00")).x; + } + m_object_grid->SetColSize(i, width); + break; + } + + case ObjectGridTable::col_layer_height_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_wall_loops: + m_object_grid->SetColSize(i, m_object_grid->GetColSize(i) - FromDIP(28)); + break; + + case ObjectGridTable::col_wall_loops_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_fill_density: + m_object_grid->SetColSize(i, m_object_grid->GetColSize(i) - FromDIP(28)); + break; + + case ObjectGridTable::col_fill_density_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_enable_support: + m_object_grid->SetColSize(i, m_object_grid->GetColSize(i) - FromDIP(28)); + break; + + case ObjectGridTable::col_enable_support_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + + case ObjectGridTable::col_brim_type: + m_object_grid->SetColSize(i, FromDIP(56)); + break; + + case ObjectGridTable::col_brim_type_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + case ObjectGridTable::col_speed_perimeter: { + auto width = m_object_grid->GetColSize(i) - FromDIP(28); + if (width < m_object_grid->GetTextExtent(("000.00")).x) { width = m_object_grid->GetTextExtent(("000.00")).x; } + m_object_grid->SetColSize(i, width); + break; + } + case ObjectGridTable::col_speed_perimeter_reset: + m_object_grid->SetColSize(i, FromDIP(28)); + break; + } } - //set col size after fit - /* ObjectGridTable::ObjectGridCol* grid_col = m_object_grid_table->get_grid_col(ObjectGridTable::col_brim_type); - grid_col->size = m_object_grid->GetTextExtent(grid_col->choices[0]).x + 30; - m_object_grid->SetColSize(ObjectGridTable::col_brim_type, grid_col->size); - grid_col = m_object_grid_table->get_grid_col(ObjectGridTable::col_filaments); - grid_col->size = 128; - m_object_grid->SetColSize(ObjectGridTable::col_filaments, grid_col->size);*/ + m_object_grid->SetGridLineColour(*wxWHITE); BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(", finished, got %1% rows, %2% cols") %m_object_grid_table->GetNumberRows() %m_object_grid_table->GetNumberCols() ; } @@ -2794,7 +3078,6 @@ void ObjectTablePanel::OnSelectCell( wxGridEvent& ev ) m_cur_row = row; m_cur_col = col; - ev.Skip(); } @@ -2866,7 +3149,7 @@ void ObjectTablePanel::resetAllValuesInSideWindow(int row, bool is_object, Model // ObjectTableDialog // ---------------------------------------------------------------------------- ObjectTableDialog::ObjectTableDialog(wxWindow* parent, Plater* platerObj, Model *modelObj, wxSize maxSize) - : GUI::DPIDialog(parent, wxID_ANY, _L("Object/Part Setting"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER) + : GUI::DPIDialog(parent, wxID_ANY, _L("Object/Part Setting"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) , m_model(modelObj), m_plater(platerObj) { @@ -2906,6 +3189,7 @@ ObjectTableDialog::ObjectTableDialog(wxWindow* parent, Plater* platerObj, Model m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0); m_obj_panel = new ObjectTablePanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE, wxEmptyString, m_plater, m_model); + m_obj_panel->SetBackgroundColour(wxColour(0x00,0xAE,0x42)); //m_top_sizer->Add(m_obj_panel, 1, wxALL | wxEXPAND, 5); wxSize panel_size = m_obj_panel->get_init_size(); @@ -2937,19 +3221,20 @@ ObjectTableDialog::ObjectTableDialog(wxWindow* parent, Plater* platerObj, Model //this->Layout(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", created, this %1%, m_obj_panel %2%") %this % m_obj_panel; - m_main_sizer->Add(m_obj_panel, 1, wxEXPAND|wxTOP,2); + m_main_sizer->Add(m_obj_panel, 1, wxEXPAND|wxLEFT,FromDIP(10)); SetSizer(m_main_sizer); - Layout(); Fit(); + Layout(); } ObjectTableDialog::~ObjectTableDialog() { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", this %1%, m_obj_panel %2%") %this % m_obj_panel; + #ifdef __WXOSX_MAC__ if (m_obj_panel) { delete m_obj_panel; m_obj_panel = nullptr; } + #endif } void ObjectTableDialog::Popup(int obj_idx, int vol_idx, wxPoint position /*= wxDefaultPosition*/) @@ -2957,7 +3242,8 @@ void ObjectTableDialog::Popup(int obj_idx, int vol_idx, wxPoint position /*= wxD m_obj_panel->sort_by_default(); m_obj_panel->SetSelection(obj_idx, vol_idx); - this->SetPosition(position); + //this->SetPosition(position); + Centre(wxBOTH); this->ShowModal(); } @@ -2981,23 +3267,88 @@ void ObjectTableDialog::on_sys_color_changed() void ObjectTableDialog::OnClose(wxCloseEvent &evt) { this->GetSize(&g_dialog_width, &g_dialog_height); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", g_dialog_width %1%, g_dialog_height %2%") %g_dialog_width % g_dialog_height; + + #ifdef __WINDOWS__ + if (m_obj_panel) { + delete m_obj_panel; + m_obj_panel = nullptr; + } + + DestroyChildren(); + Destroy(); + #endif + + #ifdef __WXOSX_MAC__ evt.Skip(); + #endif } void ObjectTableDialog::OnSize(wxSizeEvent& event) { - SetSize(wxSize(-1, FromDIP(480))); - SetMinSize(wxSize(-1, FromDIP(480))); - SetMaxSize(wxSize(-1, FromDIP(480))); - return; - wxSize new_size = event.GetSize(); - if ((new_size.GetWidth() > g_dialog_max_width) || (new_size.GetHeight() > g_dialog_max_height)) { - int width = (new_size.GetWidth() > g_dialog_max_width)?new_size.GetWidth():g_dialog_max_width; - int height = (new_size.GetHeight() > g_dialog_max_height)?new_size.GetHeight():g_dialog_max_height; - this->SetMaxSize(wxSize(width, height)); - } - event.Skip(); + //SetSize(wxSize(-1, FromDIP(480))); + //SetMinSize(wxSize(-1, FromDIP(480))); + //SetMaxSize(wxSize(-1, FromDIP(480))); + //return; + //wxSize new_size = event.GetSize(); + //if ((new_size.GetWidth() > g_dialog_max_width) || (new_size.GetHeight() > g_dialog_max_height)) { + // int width = (new_size.GetWidth() > g_dialog_max_width)?new_size.GetWidth():g_dialog_max_width; + // int height = (new_size.GetHeight() > g_dialog_max_height)?new_size.GetHeight():g_dialog_max_height; + // this->SetMaxSize(wxSize(width, height)); + //} + //event.Skip(); +} + +// ---------------------------------------------------------------------------- +// GridCellTextEditor +// ---------------------------------------------------------------------------- + +GridCellTextEditor::GridCellTextEditor() : wxGridCellTextEditor() {} + +GridCellTextEditor::~GridCellTextEditor() {} + +void GridCellTextEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + ::TextInput *text_input = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxTE_PROCESS_ENTER); + m_control = text_input; + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void GridCellTextEditor::StartingKey(wxKeyEvent &event) {} + +void GridCellTextEditor::SetSize(const wxRect &rect) { wxGridCellTextEditor::SetSize(rect); } + +void GridCellTextEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + ObjectGridTable * table = dynamic_cast(grid->GetTable()); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + + auto val = table->GetValue(row, col); + Text()->GetTextCtrl()->SetValue(val); + Text()->SetFocus(); +} + +bool GridCellTextEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &WXUNUSED(oldval), wxString *newval) +{ + ObjectGridTable * table = dynamic_cast(grid->GetTable()); + ObjectGridTable::ObjectGridCol *grid_col = table->get_grid_col(col); + ObjectGridTable::ObjectGridRow *grid_row = table->get_grid_row(row - 1); + + wxCHECK_MSG(m_control, false, "wxGridCellTextEditor must be created first!"); + + const wxString value = Text()->GetTextCtrl()->GetValue(); + if (value == m_value) return false; + + m_value = value; + + if (newval) *newval = m_value; + return true; +} + +void GridCellTextEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + grid->GetTable()->SetValue(row, col, m_value); + m_value.clear(); } } // namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectTable.hpp b/src/slic3r/GUI/GUI_ObjectTable.hpp index ca2395d236..794ce4b876 100644 --- a/src/slic3r/GUI/GUI_ObjectTable.hpp +++ b/src/slic3r/GUI/GUI_ObjectTable.hpp @@ -23,6 +23,10 @@ #include "OptionsGroup.hpp" #include "GUI_Factories.hpp" #include "GUI_ObjectTableSettings.hpp" +#include "Widgets/TextInput.hpp" + +class ComboBox; +class TextInput; namespace Slic3r { @@ -50,11 +54,31 @@ public: virtual GridCellIconRenderer *Clone() const wxOVERRIDE; }; -// the editor for string data allowing to choose from the list of strings +class GridCellTextEditor : public wxGridCellTextEditor +{ +public: + GridCellTextEditor(); + ~GridCellTextEditor(); + + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) wxOVERRIDE; + void StartingKey(wxKeyEvent &event) wxOVERRIDE; + virtual void SetSize(const wxRect &rect) wxOVERRIDE; + virtual void BeginEdit(int row, int col, wxGrid *grid) wxOVERRIDE; + virtual bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval) wxOVERRIDE; + virtual void ApplyEdit(int row, int col, wxGrid *grid) wxOVERRIDE; + +protected: + ::TextInput *Text() const { return (::TextInput *) m_control; } + wxDECLARE_NO_COPY_CLASS(GridCellTextEditor); + +private: + wxString m_value; +}; + + class GridCellFilamentsEditor : public wxGridCellChoiceEditor { public: - // if !allowOthers, user can't type a string not in choices array GridCellFilamentsEditor(size_t count = 0, const wxString choices[] = NULL, bool allowOthers = false, @@ -78,7 +102,7 @@ public: virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE; protected: - wxBitmapComboBox *Combo() const { return (wxBitmapComboBox *)m_control; } + ::ComboBox *Combo() const { return (::ComboBox *)m_control; } void OnComboCloseUp(wxCommandEvent& evt); std::vector* m_icons; @@ -108,6 +132,44 @@ public: virtual GridCellFilamentsRenderer *Clone() const wxOVERRIDE; }; + +class GridCellChoiceEditor : public wxGridCellChoiceEditor +{ +public: + GridCellChoiceEditor(size_t count = 0, const wxString choices[] = NULL); + GridCellChoiceEditor(const wxArrayString &choices); + + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) wxOVERRIDE; + virtual void SetSize(const wxRect &rect) wxOVERRIDE; + + virtual wxGridCellEditor *Clone() const wxOVERRIDE; + + virtual void BeginEdit(int row, int col, wxGrid *grid) wxOVERRIDE; + virtual bool EndEdit(int row, int col, const wxGrid *grid, const wxString &oldval, wxString *newval) wxOVERRIDE; + + virtual wxGridActivationResult TryActivate(int row, int col, wxGrid *grid, const wxGridActivationSource &actSource) wxOVERRIDE; + virtual void DoActivate(int row, int col, wxGrid *grid) wxOVERRIDE; + +protected: + ::ComboBox *Combo() const { return (::ComboBox *) m_control; } + void OnComboCloseUp(wxCommandEvent &evt); + wxDECLARE_NO_COPY_CLASS(GridCellChoiceEditor); + +private: + int m_cached_value{-1}; +}; + + +class GridCellComboBoxRenderer : public wxGridCellChoiceRenderer +{ +public: + virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected) wxOVERRIDE; + + virtual wxSize GetBestSize(wxGrid &WXUNUSED(grid), wxGridCellAttr &attr, wxDC &dc, int WXUNUSED(row), int WXUNUSED(col)) wxOVERRIDE; + + virtual GridCellComboBoxRenderer *Clone() const wxOVERRIDE; +}; + class GridCellSupportEditor : public wxGridCellBoolEditor { public: @@ -115,7 +177,6 @@ public: virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE; private: - // These functions modify or use m_value. void SetValueFromGrid(int row, int col, wxGrid* grid); void SetGridFromValue(int row, int col, wxGrid* grid) const; @@ -150,6 +211,7 @@ public: virtual GridCellSupportRenderer *Clone() const wxOVERRIDE; }; + //ObjectGrid for the param setting table class ObjectGrid : public wxGrid { diff --git a/src/slic3r/GUI/GUI_ObjectTableSettings.cpp b/src/slic3r/GUI/GUI_ObjectTableSettings.cpp index 10fd7f2ddd..b2a2f77e52 100644 --- a/src/slic3r/GUI/GUI_ObjectTableSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectTableSettings.cpp @@ -22,6 +22,10 @@ namespace Slic3r namespace GUI { +wxDEFINE_EVENT(EVT_LOCK_DISABLE, wxCommandEvent); +wxDEFINE_EVENT(EVT_LOCK_ENABLE, wxCommandEvent); + + OTG_Settings::OTG_Settings(wxWindow* parent, const bool staticbox) : m_parent(parent) { @@ -162,10 +166,23 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_ auto btn = new ScalableButton(parent, wxID_ANY, m_bmp_reset); btn->SetToolTip(_(L("Reset parameter"))); + + #ifdef __WINDOWS__ btn->SetBackgroundColour(*wxWHITE); + #endif // DEBUG + + btn->SetBitmapFocus(m_bmp_reset_focus.bmp()); btn->SetBitmapHover(m_bmp_reset_focus.bmp()); + + #ifdef __WINDOWS__ btn->SetBitmapDisabled(m_bmp_reset_disable.bmp()); + #endif + + #ifdef __WXOSX_MAC__ + btn->Bind(EVT_LOCK_DISABLE, [this, btn](auto &e) { btn->SetBitmap(m_bmp_reset_disable.bmp()); }); + btn->Bind(EVT_LOCK_ENABLE, [this, btn](auto &e) { btn->SetBitmap(m_bmp_reset_focus.bmp()); }); + #endif btn->Bind(wxEVT_BUTTON, [btn, opt_key, this, is_object, object, config, group_category](wxEvent &event) { //wxGetApp().plater()->take_snapshot(from_u8((boost::format(_utf8(L("Reset Option %s"))) % opt_key).str())); @@ -185,6 +202,14 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_ m_current_config.apply(config->get(), true); update_config_values(is_object, object, config, group_category); this->m_parent->Thaw(); + + #ifdef __WXOSX_MAC__ + if (!btn->IsEnabled()) { + btn->SetBitmap(m_bmp_reset_disable.bmp()); + } else { + btn->SetBitmap(m_bmp_reset_focus.bmp()); + } + #endif }); (const_cast(line)).extra_widget_win = btn; return btn; @@ -211,7 +236,9 @@ bool ObjectTableSettings::update_settings_list(bool is_object, bool is_multiple_ ctrl->SetBitmap_(m_bmp_reset); ctrl->SetBitmapFocus(m_bmp_reset_focus.bmp()); ctrl->SetBitmapHover(m_bmp_reset_focus.bmp()); + #ifdef __WINDOWS__ ctrl->SetBitmapDisabled(m_bmp_reset_disable.bmp()); + #endif }; const bool is_extruders_cat = cat.first == "Extruders"; @@ -308,10 +335,22 @@ int ObjectTableSettings::update_extra_column_visible_status(ConfigOptionsGroup* if (line) { if ((config->has(opt.name)) && reset_window&&reset_window->IsEnabled()) { line->extra_widget_win->Enable(); + + #ifdef __WXOSX_MAC__ + wxCommandEvent event(EVT_LOCK_ENABLE); + event.SetEventObject(line->extra_widget_win); + wxPostEvent(line->extra_widget_win, event); + #endif + count++; - } - else + } else { line->extra_widget_win->Disable(); + #ifdef __WXOSX_MAC__ + wxCommandEvent event(EVT_LOCK_DISABLE); + event.SetEventObject(line->extra_widget_win); + wxPostEvent(line->extra_widget_win, event); + #endif + } } } wxGridSizer* grid_sizer = option_group->get_grid_sizer(); diff --git a/src/slic3r/GUI/GUI_ObjectTableSettings.hpp b/src/slic3r/GUI/GUI_ObjectTableSettings.hpp index 5265a376d7..534426f554 100644 --- a/src/slic3r/GUI/GUI_ObjectTableSettings.hpp +++ b/src/slic3r/GUI/GUI_ObjectTableSettings.hpp @@ -76,7 +76,8 @@ public: void resetAllValues(int row, bool is_object, ModelObject* object, ModelConfig* config, const std::string& category); void msw_rescale(); }; - +wxDECLARE_EVENT(EVT_LOCK_DISABLE, wxCommandEvent); +wxDECLARE_EVENT(EVT_LOCK_ENABLE, wxCommandEvent); }} #endif // slic3r_GUI_ObjectTableSettings_hpp_ diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index d9db9e0f31..c0dae74de6 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -78,6 +78,7 @@ bool View3D::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig //BBS: GUI refactor: GLToolbar m_canvas->enable_select_plate_toolbar(false); m_canvas->enable_assemble_view_toolbar(true); + m_canvas->enable_separator_toolbar(true); m_canvas->enable_labels(true); m_canvas->enable_slope(true); @@ -446,40 +447,45 @@ void Preview::update_layers_slider_mode() // multi-extruder printer profile , but whole model is printed by only one extruder // false -> multi-extruder printer profile , and model is printed by several extruders bool one_extruder_printed_model = true; - + bool can_change_color = true; // extruder used for whole model for multi-extruder printer profile int only_extruder = -1; // BBS if (wxGetApp().filaments_cnt() > 1) { - const ModelObjectPtrs &objects = wxGetApp().plater()->model().objects; - + //const ModelObjectPtrs& objects = wxGetApp().plater()->model().objects; + auto plate_extruders = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_extruders(); + for (auto extruder : plate_extruders) { + if (extruder != plate_extruders[0]) + can_change_color = false; + } // check if whole model uses just only one extruder - if (!objects.empty()) { - const int extruder = objects[0]->config.has("extruder") ? objects[0]->config.option("extruder")->getInt() : 0; + if (!plate_extruders.empty()) { + //const int extruder = objects[0]->config.has("extruder") ? objects[0]->config.option("extruder")->getInt() : 0; + const int extruder = plate_extruders[0]; + only_extruder = extruder; + // auto is_one_extruder_printed_model = [objects, extruder]() { + // for (ModelObject *object : objects) { + // if (object->config.has("extruder") && object->config.option("extruder")->getInt() != extruder) /*return false*/; - auto is_one_extruder_printed_model = [objects, extruder]() { - for (ModelObject *object : objects) { - if (object->config.has("extruder") && object->config.option("extruder")->getInt() != extruder) return false; + // for (ModelVolume *volume : object->volumes) + // if ((volume->config.has("extruder") && volume->config.option("extruder")->getInt() != extruder) || !volume->mmu_segmentation_facets.empty()) return false; - for (ModelVolume *volume : object->volumes) - if ((volume->config.has("extruder") && volume->config.option("extruder")->getInt() != extruder) || !volume->mmu_segmentation_facets.empty()) return false; + // for (const auto &range : object->layer_config_ranges) + // if (range.second.has("extruder") && range.second.option("extruder")->getInt() != extruder) return false; + // } + // return true; + // }; - for (const auto &range : object->layer_config_ranges) - if (range.second.has("extruder") && range.second.option("extruder")->getInt() != extruder) return false; - } - return true; - }; - - if (is_one_extruder_printed_model()) - only_extruder = extruder; - else - one_extruder_printed_model = false; + // if (is_one_extruder_printed_model()) + // only_extruder = extruder; + // else + // one_extruder_printed_model = false; } } IMSlider *m_layers_slider = m_canvas->get_gcode_viewer().get_layers_slider(); - m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder); + m_layers_slider->SetModeAndOnlyExtruder(one_extruder_printed_model, only_extruder, can_change_color); } void Preview::update_layers_slider_from_canvas(wxKeyEvent &event) @@ -763,6 +769,7 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint //BBS: GUI refactor: GLToolbar m_canvas->enable_assemble_view_toolbar(false); m_canvas->enable_return_toolbar(true); + m_canvas->enable_separator_toolbar(false); // BBS: set volume_selection_mode to Volume m_canvas->get_selection().set_volume_selection_mode(Selection::Volume); diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp index c2f6600d71..0667e164cc 100644 --- a/src/slic3r/GUI/GUI_Utils.cpp +++ b/src/slic3r/GUI/GUI_Utils.cpp @@ -450,7 +450,7 @@ bool generate_image(const std::string &filename, wxImage &image, wxSize img_size if (method == GERNERATE_IMAGE_RESIZE) { float h_factor = img.GetHeight() / (float) image.GetHeight(); float w_factor = img.GetWidth() / (float) image.GetWidth(); - float factor = std::max(h_factor, w_factor); + float factor = std::min(h_factor, w_factor); int tar_height = (int) ((float) img.GetHeight() / factor); int tar_width = (int) ((float) img.GetWidth() / factor); img = img.Rescale(tar_width, tar_height); @@ -465,9 +465,11 @@ bool generate_image(const std::string &filename, wxImage &image, wxSize img_size return false; } - image.ConvertAlphaToMask(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); + //image.ConvertAlphaToMask(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); return true; } +std::deque dialogStack; + } } diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index a3e239d1cc..a93009129f 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -104,6 +104,8 @@ struct DpiChangedEvent : public wxEvent { wxDECLARE_EVENT(EVT_DPI_CHANGED_SLICER, DpiChangedEvent); #endif // !wxVERSION_EQUAL_OR_GREATER_THAN +extern std::deque dialogStack; + template class DPIAware : public P { public: @@ -189,6 +191,19 @@ public: event.Skip(); on_sys_color_changed(); }); + + if (std::is_same::value) { + this->Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) { + if (e.GetKeyCode() == WXK_ESCAPE) { + //if (this->IsModal()) + // this->EndModal(wxID_CANCEL); + //else + this->Close(); + } + else + e.Skip(); + }); + } } virtual ~DPIAware() {} @@ -208,6 +223,14 @@ public: on_sys_color_changed(); } #endif + + int ShowModal() + { + dialogStack.push_front(this); + int r = wxDialog::ShowModal(); + dialogStack.pop_front(); + return r; + } protected: virtual void on_dpi_changed(const wxRect &suggested_rect) = 0; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 07aa30f9d1..5aa5f2c6b9 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -209,6 +209,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float space_size = m_imgui->get_style_scaling() * 8; const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f); const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f); const float gap_fill_slider_left = m_imgui->calc_text_size(m_desc.at("gap_fill")).x + m_imgui->scaled(1.5f); @@ -220,7 +221,6 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l const float tips_width = m_imgui->calc_text_size(_L("Auto support threshold angle: ") + " 90 ").x + m_imgui->scaled(1.5f); const float minimal_slider_width = m_imgui->scaled(4.f); - float slider_width_times = 1.5; float caption_max = 0.f; float total_text_max = 0.f; @@ -233,12 +233,10 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l const float sliders_left_width = std::max(std::max(cursor_slider_left, clipping_slider_left), std::max(highlight_slider_left, gap_fill_slider_left)); const float slider_icon_width = m_imgui->get_slider_icon_size().x; - float window_width = minimal_slider_width + sliders_left_width + slider_icon_width; const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, buttons_width); - window_width = std::max(window_width, tips_width); + const float sliders_width = m_imgui->scaled(7.0f); + const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_left_width + sliders_width - space_size; float drag_pos_times = 0.7; @@ -252,15 +250,22 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f)); - if (m_current_tool == tool_icons[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); // r, g, b, a - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - } ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); + if (m_current_tool == tool_icons[i]) { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); + } bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); + if (m_current_tool == tool_icons[i]) + { + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(2); + } ImGui::PopStyleVar(1); - if (m_current_tool == tool_icons[i])ImGui::PopStyleColor(3); if (btn_clicked && m_current_tool != tool_icons[i]) { m_current_tool = tool_icons[i]; @@ -287,9 +292,9 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f"); } else if (m_current_tool == ImGui::SphereButtonIcon) { @@ -299,9 +304,9 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f"); } else if (m_current_tool == ImGui::FillButtonIcon) { @@ -312,13 +317,13 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l m_imgui->text(m_desc.at("smart_fill_angle")); std::string format_str = std::string("%.f") + I18N::translate_utf8("", "Face angle threshold, placed after the number with no whitespace in between."); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); if (m_imgui->bbl_slider_float_style("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data(), 1.0f, true)) for (auto& triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); triangle_selector->request_update_render_data(); } - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##smart_fill_angle_input", &m_smart_fill_angle, 0.05f, 0.0f, 0.0f, "%.2f"); } else if (m_current_tool == ImGui::GapFillIcon) { @@ -328,10 +333,10 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc["gap_area"] + ":"); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold"); m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, format_str.data(), 1.0f, true); - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f"); } @@ -349,7 +354,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SetCursorPosY(slider_start_position_y); std::string format_str = std::string("%.f"); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); wxString tooltip = _L("Highlight faces according to overhang angle."); if (m_imgui->bbl_slider_float_style("##angle_threshold_deg", &m_highlight_by_angle_threshold_deg, 0.f, 90.f, format_str.data(), 1.0f, true, tooltip)) { m_parent.set_slope_normal_angle(90.f - m_highlight_by_angle_threshold_deg); @@ -369,7 +374,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l } ImGui::EndTooltip(); } - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##angle_threshold_deg_input", &m_highlight_by_angle_threshold_deg, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -380,10 +385,10 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool b_bbl_slider_float = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - drag_pos_times * slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_drag_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index d63feb4e79..ed717f0cdb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -328,16 +328,16 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott // BBS ImGuiWrapper::push_toolbar_style(m_parent.get_scale()); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.0f, 16.0f)); GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: - const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.f); - const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); + const float space_size = m_imgui->get_style_scaling() * 8; + const float clipping_slider_left = m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x + m_imgui->scaled(1.5f); + const float cursor_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.5f); const float smart_fill_slider_left = m_imgui->calc_text_size(m_desc.at("smart_fill_angle")).x + m_imgui->scaled(1.5f); const float edge_detect_slider_left = m_imgui->calc_text_size(m_desc.at("edge_detection")).x + m_imgui->scaled(1.f); - const float gap_area_slider_left = m_imgui->calc_text_size(m_desc.at("gap_area")).x + m_imgui->scaled(1.5f); - const float height_range_slider_left = m_imgui->calc_text_size(m_desc.at("height_range")).x + m_imgui->scaled(1.5f); + const float gap_area_slider_left = m_imgui->calc_text_size(m_desc.at("gap_area")).x + m_imgui->scaled(1.5f) + space_size; + const float height_range_slider_left = m_imgui->calc_text_size(m_desc.at("height_range")).x + m_imgui->scaled(2.f); const float remove_btn_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); const float filter_btn_width = m_imgui->calc_text_size(m_desc.at("perform")).x + m_imgui->scaled(1.f); @@ -358,7 +358,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott const float height_max_width = std::max(clipping_slider_left,height_range_slider_left); const float sliders_left_width = std::max(smart_fill_slider_left, std::max(cursor_slider_left, std::max(edge_detect_slider_left, std::max(gap_area_slider_left, std::max(height_range_slider_left, - clipping_slider_left))))); + clipping_slider_left))))) + space_size; const float slider_icon_width = m_imgui->get_slider_icon_size().x; float window_width = minimal_slider_width + sliders_left_width + slider_icon_width; const int max_filament_items_per_line = 8; @@ -369,8 +369,10 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott window_width = std::max(window_width, buttons_width); window_width = std::max(window_width, max_filament_items_per_line * filament_item_width + +m_imgui->scaled(0.5f)); + const float sliders_width = m_imgui->scaled(7.0f); + const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_width - space_size; + const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; - float slider_width_times = 1.5; ImDrawList * draw_list = ImGui::GetWindowDrawList(); ImVec2 pos = ImGui::GetCursorScreenPos(); static float color_button_high = 25.0; @@ -383,14 +385,15 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott float start_pos_x = ImGui::GetCursorPos().x; const ImVec2 max_label_size = ImGui::CalcTextSize("99", NULL, true); const float item_spacing = m_imgui->scaled(0.8f); - for (int extruder_idx = 0; extruder_idx < m_extruders_colors.size(); extruder_idx++) { + size_t n_extruder_colors = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size()); + for (int extruder_idx = 0; extruder_idx < n_extruder_colors; extruder_idx++) { const std::array &extruder_color = m_extruders_colors[extruder_idx]; ImVec4 color_vec(extruder_color[0], extruder_color[1], extruder_color[2], extruder_color[3]); std::string color_label = std::string("##extruder color ") + std::to_string(extruder_idx); std::string item_text = std::to_string(extruder_idx + 1); const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true); - const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f), 0.f); + const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f),0.f); float button_offset = start_pos_x; if (extruder_idx % max_filament_items_per_line != 0) { @@ -402,13 +405,19 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip; if (m_selected_extruder_idx != extruder_idx) flags |= ImGuiColorEditFlags_NoBorder; #ifdef __APPLE__ - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.4f, 0.4f, 0.4f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0); bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size); - ImGui::PopStyleVar(1); + ImGui::PopStyleVar(2); ImGui::PopStyleColor(1); #else + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0); bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size); + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(1); #endif color_button_high = ImGui::GetCursorPos().y - color_button - 2.0; if (color_picked) { m_selected_extruder_idx = extruder_idx; } @@ -418,12 +427,14 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott // draw filament id float gray = 0.299 * extruder_color[0] + 0.587 * extruder_color[1] + 0.114 * extruder_color[2]; ImGui::SameLine(button_offset + (button_size.x - label_size.x) / 2.f); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10.0,15.0}); if (gray * 255.f < 80.f) ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), item_text.c_str()); else ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), item_text.c_str()); - } + ImGui::PopStyleVar(); + } //ImGui::NewLine(); ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1)); @@ -432,20 +443,26 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott std::array tool_icons = { ImGui::CircleButtonIcon,ImGui::SphereButtonIcon, ImGui::TriangleButtonIcon, ImGui::HeightRangeIcon, ImGui::FillButtonIcon, ImGui::GapFillIcon }; std::array tool_tips = { _L("Circle"), _L("Sphere"), _L("Triangle"), _L("Height Range"), _L("Fill"), _L("Gap Fill") }; for (int i = 0; i < tool_icons.size(); i++) { - std::string str_label = std::string("##"); + std::string str_label = std::string(""); std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label); - if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(0.5f)); - - if (m_current_tool == tool_icons[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); // r, g, b, a - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - } + if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.5f)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); + if (m_current_tool == tool_icons[i]) { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); + } bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); + if (m_current_tool == tool_icons[i]) + { + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(2); + } ImGui::PopStyleVar(1); - if (m_current_tool == tool_icons[i]) ImGui::PopStyleColor(3); if (btn_clicked && m_current_tool != tool_icons[i]) { m_current_tool = tool_icons[i]; @@ -475,9 +492,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(circle_max_width); - ImGui::PushItemWidth(window_width - circle_max_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + circle_max_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -488,9 +505,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(circle_max_width); - ImGui::PushItemWidth(window_width - circle_max_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + circle_max_width); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -505,9 +522,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(clipping_slider_left); - ImGui::PushItemWidth(window_width - clipping_slider_left - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + clipping_slider_left); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -524,13 +541,13 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott std::string format_str = std::string("%.f") + I18N::translate_utf8("°", "Face angle threshold," "placed after the number with no whitespace in between."); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); if (m_imgui->bbl_slider_float_style("##smart_fill_angle", &m_smart_fill_angle, SmartFillAngleMin, SmartFillAngleMax, format_str.data(), 1.0f, true)) for (auto &triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); triangle_selector->request_update_render_data(); } - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + sliders_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##smart_fill_angle_input", &m_smart_fill_angle, 0.05f, 0.0f, 0.0f, "%.2f"); } else { @@ -544,9 +561,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + sliders_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -558,10 +575,10 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc["height_range"] + ":"); ImGui::SameLine(height_max_width); - ImGui::PushItemWidth(window_width - height_max_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); std::string format_str = std::string("%.2f") + I18N::translate_utf8("mm", "Heigh range," "Facet in [cursor z, cursor z + height] will be selected."); m_imgui->bbl_slider_float_style("##cursor_height", &m_cursor_height, CursorHeightMin, CursorHeightMax, format_str.data(), 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + height_max_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##cursor_height_input", &m_cursor_height, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -572,9 +589,9 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(height_max_width); - ImGui::PushItemWidth(window_width - height_max_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + height_max_width); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -586,10 +603,10 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott ImGui::AlignTextToFramePadding(); m_imgui->text(m_desc["gap_area"] + ":"); ImGui::SameLine(gap_area_slider_left); - ImGui::PushItemWidth(window_width - gap_area_slider_left - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); std::string format_str = std::string("%.2f") + I18N::translate_utf8("", "Triangle patch area threshold,""triangle patch will be merged to neighbor if its area is less than threshold"); m_imgui->bbl_slider_float_style("##gap_area", &TriangleSelectorPatch::gap_area, TriangleSelectorPatch::GapAreaMin, TriangleSelectorPatch::GapAreaMax, format_str.data(), 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width + gap_area_slider_left); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##gap_area_input", &TriangleSelectorPatch::gap_area, 0.05f, 0.0f, 0.0f, "%.2f"); } @@ -638,7 +655,6 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott GizmoImguiEnd(); // BBS - ImGui::PopStyleVar(1); ImGuiWrapper::pop_toolbar_style(); } @@ -689,7 +705,8 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors() const TriangleMesh* mesh = &mv->mesh(); m_triangle_selectors.emplace_back(std::make_unique(*mesh, ebt_colors, 0.2)); // Reset of TriangleSelector is done inside TriangleSelectorMmGUI's constructor, so we don't need it to perform it again in deserialize(). - m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data(), false); + EnforcerBlockerType max_ebt = (EnforcerBlockerType)std::min(m_extruders_colors.size(), (size_t)EnforcerBlockerType::ExtruderMax); + m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data(), false, max_ebt); m_triangle_selectors.back()->request_update_render_data(); m_volumes_extruder_idxs.push_back(mv->extruder_id()); } @@ -754,6 +771,7 @@ void GLGizmoMmuSegmentation::on_set_state() if (get_state() == Off) { ModelObject* mo = m_c->selection_info()->model_object(); if (mo) Slic3r::save_object_mesh(*mo); + m_parent.post_event(SimpleEvent(EVT_GLCANVAS_FORCE_UPDATE)); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 0d09e40368..cf1ad0e4d3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -1091,7 +1091,7 @@ void TriangleSelectorPatch::render(ImGuiWrapper* imgui) void TriangleSelectorPatch::update_triangles_per_type() { - m_triangle_patches.resize((int)EnforcerBlockerType::ExtruderMax); + m_triangle_patches.resize((int)EnforcerBlockerType::ExtruderMax + 1); for (int i = 0; i < m_triangle_patches.size(); i++) { auto& patch = m_triangle_patches[i]; patch.type = (EnforcerBlockerType)i; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 870406c1f9..a1bdd80dd4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -178,17 +178,11 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) GizmoImguiBegin(get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); // First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that: + const float space_size = m_imgui->get_style_scaling() * 8; const float clipping_slider_left = std::max(m_imgui->calc_text_size(m_desc.at("clipping_of_view")).x, m_imgui->calc_text_size(m_desc.at("reset_direction")).x) + m_imgui->scaled(1.5f); const float cursor_size_slider_left = m_imgui->calc_text_size(m_desc.at("cursor_size")).x + m_imgui->scaled(1.f); - - const float cursor_type_radio_left = m_imgui->calc_text_size(m_desc["cursor_type"]).x + m_imgui->scaled(1.f); - const float cursor_type_radio_sphere = m_imgui->calc_text_size(m_desc["sphere"]).x + m_imgui->scaled(2.5f); - const float cursor_type_radio_circle = m_imgui->calc_text_size(m_desc["circle"]).x + m_imgui->scaled(2.5f); - - const float button_width = m_imgui->calc_text_size(m_desc.at("remove_all")).x + m_imgui->scaled(1.f); - const float minimal_slider_width = m_imgui->scaled(4.f); const float empty_button_width = m_imgui->calc_button_size("").x; float caption_max = 0.f; @@ -197,19 +191,12 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) caption_max = std::max(caption_max, m_imgui->calc_text_size(m_desc[t + "_caption"]).x); total_text_max = std::max(total_text_max, m_imgui->calc_text_size(m_desc[t]).x); } - total_text_max += caption_max + m_imgui->scaled(1.f); - caption_max += m_imgui->scaled(1.f); - float slider_width_times = 1.5; + const float sliders_left_width = std::max(cursor_size_slider_left, clipping_slider_left); -#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT const float slider_icon_width = m_imgui->get_slider_icon_size().x; - float window_width = minimal_slider_width + sliders_left_width + slider_icon_width; -#else - float window_width = minimal_slider_width + sliders_left_width; -#endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT - window_width = std::max(window_width, total_text_max); - window_width = std::max(window_width, button_width); - window_width = std::max(window_width, cursor_type_radio_left + cursor_type_radio_sphere + cursor_type_radio_circle); + + const float sliders_width = m_imgui->scaled(7.0f); + const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_left_width + sliders_width - space_size; const float max_tooltip_width = ImGui::GetFontSize() * 20.0f; @@ -222,17 +209,22 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) std::wstring btn_name = tool_icons[i] + boost::nowide::widen(str_label); if (i != 0) ImGui::SameLine((empty_button_width + m_imgui->scaled(1.75f)) * i + m_imgui->scaled(1.3f)); - - if (m_current_tool == tool_icons[i]) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); // r, g, b, a - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); - } ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); + if (m_current_tool == tool_icons[i]) { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); // r, g, b, a + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.86f, 0.99f, 0.91f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0); + } bool btn_clicked = ImGui::Button(into_u8(btn_name).c_str()); + if (m_current_tool == tool_icons[i]) + { + ImGui::PopStyleColor(4); + ImGui::PopStyleVar(2); + } ImGui::PopStyleVar(1); - if (m_current_tool == tool_icons[i])ImGui::PopStyleColor(3); - if (btn_clicked && m_current_tool != tool_icons[i]) { m_current_tool = tool_icons[i]; for (auto& triangle_selector : m_triangle_selectors) { @@ -263,9 +255,9 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) m_imgui->text(m_desc.at("cursor_size")); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); m_imgui->bbl_slider_float_style("##cursor_radius", &m_cursor_radius, CursorRadiusMin, CursorRadiusMax, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); ImGui::BBLDragFloat("##cursor_radius_input", &m_cursor_radius, 0.05f, 0.0f, 0.0f, "%.2f"); @@ -275,10 +267,10 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) auto clp_dist = float(m_c->object_clipper()->get_position()); ImGui::SameLine(sliders_left_width); - ImGui::PushItemWidth(window_width - sliders_left_width - slider_width_times * slider_icon_width); + ImGui::PushItemWidth(sliders_width); bool slider_clp_dist = m_imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true); - ImGui::SameLine(window_width - slider_icon_width); + ImGui::SameLine(drag_left_width); ImGui::PushItemWidth(1.5 * slider_icon_width); bool b_clp_dist_input = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f"); if (slider_clp_dist || b_clp_dist_input) { m_c->object_clipper()->set_position(clp_dist, true); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoText.cpp b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp new file mode 100644 index 0000000000..61763b1970 --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoText.cpp @@ -0,0 +1,210 @@ +// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro. +#include "GLGizmoText.hpp" +#include "slic3r/GUI/GLCanvas3D.hpp" +#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/ImGuiWrapper.hpp" +#include "slic3r/GUI/GUI_ObjectList.hpp" + +#include "libslic3r/Geometry/ConvexHull.hpp" +#include "libslic3r/Model.hpp" + +#include "libslic3r/Shape/TextShape.hpp" + +#include + +#include + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include + +namespace Slic3r { +namespace GUI { + +static double g_normal_precise = 0.0015; + +GLGizmoText::GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) + : GLGizmoBase(parent, icon_filename, sprite_id) +{ +} + +bool GLGizmoText::on_init() +{ + m_avail_font_names = init_occt_fonts(); + m_shortcut_key = WXK_CONTROL_T; + return true; +} + +void GLGizmoText::on_set_state() +{ +} + +CommonGizmosDataID GLGizmoText::on_get_requirements() const +{ + return CommonGizmosDataID::SelectionInfo; +} + +std::string GLGizmoText::on_get_name() const +{ + return _u8L("Text shape"); +} + +bool GLGizmoText::on_is_activable() const +{ + // This is assumed in GLCanvas3D::do_rotate, do not change this + // without updating that function too. + return m_parent.get_selection().is_single_full_instance(); +} + +void GLGizmoText::on_render() +{ + // TODO: +} + +void GLGizmoText::on_render_for_picking() +{ + // TODO: +} + +void GLGizmoText::push_combo_style(const float scale) +{ + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.0f * scale); + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale); + ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG); + ImGui::PushStyleColor(ImGuiCol_BorderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.00f, 0.68f, 0.26f, 0.0f)); + ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG); + ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f }); +} + +void GLGizmoText::pop_combo_style() +{ + ImGui::PopStyleVar(2); + ImGui::PopStyleColor(7); +} + +// BBS +void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit) +{ + const float win_h = ImGui::GetWindowHeight(); + y = std::min(y, bottom_limit - win_h); + GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f); + + static float last_y = 0.0f; + static float last_h = 0.0f; + + const float currt_scale = m_parent.get_scale(); + ImGuiWrapper::push_toolbar_style(currt_scale); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0,5.0) * currt_scale); + GizmoImguiBegin("Text", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); + + float space_size = m_imgui->get_style_scaling() * 8; + float font_cap = m_imgui->calc_text_size(_L("Font")).x; + float size_cap = m_imgui->calc_text_size(_L("Size")).x; + float thickness_cap = m_imgui->calc_text_size(_L("Thickness")).x; + float input_cap = m_imgui->calc_text_size(_L("Input text")).x; + float caption_size = std::max(std::max(font_cap, size_cap), std::max(thickness_cap, input_cap)) + space_size + ImGui::GetStyle().WindowPadding.x; + + float input_text_size = m_imgui->scaled(12.0f); + float button_size = ImGui::GetFrameHeight(); + float input_size = input_text_size - button_size * 2 - ImGui::GetStyle().ItemSpacing.x * 4; + + ImTextureID normal_B = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B); + ImTextureID press_B_hover = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B_HOVER); + ImTextureID press_B_press = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_B_PRESS); + + ImTextureID normal_T = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T); + ImTextureID press_T_hover = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T_HOVER); + ImTextureID press_T_press = m_parent.get_gizmos_manager().get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TEXT_T_PRESS); + + // adjust window position to avoid overlap the view toolbar + if (last_h != win_h || last_y != y) { + // ask canvas for another frame to render the window in the correct position + m_imgui->set_requires_extra_frame(); + if (last_h != win_h) + last_h = win_h; + if (last_y != y) + last_y = y; + } + + ImGui::AlignTextToFramePadding(); + + const char** cstr_font_names = (const char**)calloc(m_avail_font_names.size(), sizeof(const char*)); + for (int i = 0; i < m_avail_font_names.size(); i++) + cstr_font_names[i] = m_avail_font_names[i].c_str(); + + m_imgui->text(_L("Font")); + ImGui::SameLine(caption_size); + ImGui::PushItemWidth(input_text_size + ImGui::GetFrameHeight() * 2); + push_combo_style(currt_scale); + if (ImGui::BBLBeginCombo("##Font", cstr_font_names[m_curr_font_idx], 0)) { + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4.0f, 0.0f) * currt_scale); + for (int i = 0; i < m_avail_font_names.size(); i++) { + const bool is_selected = (m_curr_font_idx == i); + if (ImGui::BBLSelectable(cstr_font_names[i], is_selected)) { + m_curr_font_idx = i; + m_font_name = cstr_font_names[m_curr_font_idx]; + } + if (is_selected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::PopStyleVar(2); + ImGui::EndCombo(); + } + + pop_combo_style(); + ImGui::AlignTextToFramePadding(); + m_imgui->text(_L("Size")); + ImGui::SameLine(caption_size); + ImGui::PushItemWidth(input_size); + ImGui::InputFloat("###font_size", &m_font_size, 0.0f, 0.0f, "%.2f"); + if (m_font_size < 3.0f)m_font_size = 3.0f; + ImGui::SameLine(); + + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0.0,0.0}); + ImGui::BBLImageButton(normal_B,press_B_hover,press_B_press,{button_size,button_size},m_bold); + ImGui::SameLine(); + ImGui::BBLImageButton(normal_T,press_T_hover,press_T_press,{button_size,button_size},m_italic); + ImGui::PopStyleVar(2); + + ImGui::AlignTextToFramePadding(); + m_imgui->text(_L("Thickness")); + ImGui::SameLine(caption_size); + ImGui::PushItemWidth(input_text_size); + ImGui::InputFloat("###text_thickness", &m_thickness,0.0f, 0.0f, "%.2f"); + if (m_thickness < 0.1f)m_thickness = 0.1f; + + ImGui::AlignTextToFramePadding(); + m_imgui->text(_L("Input text")); + ImGui::SameLine(caption_size); + ImGui::PushItemWidth(input_text_size); + ImGui::InputText("", m_text, sizeof(m_text)); + + ImGui::Separator(); + m_imgui->disabled_begin(m_text[0] == '\0' || m_text[0] == ' '); + float offset = caption_size + input_text_size - m_imgui->calc_text_size(_L("Add")).x - space_size; + ImGui::Dummy({0.0, 0.0}); + ImGui::SameLine(offset); + bool add_clicked = m_imgui->button(_L("Add")); + if (add_clicked) { + TriangleMesh mesh; + load_text_shape(m_text, m_font_name.c_str(), m_font_size, m_thickness, m_bold, m_italic, mesh); + ObjectList* obj_list = wxGetApp().obj_list(); + obj_list->load_mesh_part(mesh, "text_shape"); + } + m_imgui->disabled_end(); + + GizmoImguiEnd(); + ImGui::PopStyleVar(); + ImGuiWrapper::pop_toolbar_style(); +} + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoText.hpp b/src/slic3r/GUI/Gizmos/GLGizmoText.hpp new file mode 100644 index 0000000000..121263741b --- /dev/null +++ b/src/slic3r/GUI/Gizmos/GLGizmoText.hpp @@ -0,0 +1,45 @@ +#ifndef slic3r_GLGizmoText_hpp_ +#define slic3r_GLGizmoText_hpp_ + +#include "GLGizmoBase.hpp" +#include "slic3r/GUI/3DScene.hpp" + + +namespace Slic3r { + +enum class ModelVolumeType : int; + +namespace GUI { + +class GLGizmoText : public GLGizmoBase +{ +private: + std::vector m_avail_font_names; + char m_text[256] = { 0 }; + std::string m_font_name; + float m_font_size = 16.f; + int m_curr_font_idx = 0; + bool m_bold = true; + bool m_italic = false; + float m_thickness = 2.f; + +public: + GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id); + +protected: + virtual bool on_init() override; + virtual std::string on_get_name() const override; + virtual bool on_is_activable() const override; + virtual void on_render() override; + virtual void on_render_for_picking() override; + void push_combo_style(const float scale); + void pop_combo_style(); + virtual void on_set_state() override; + virtual CommonGizmosDataID on_get_requirements() const override; + virtual void on_render_input_window(float x, float y, float bottom_limit); +}; + +} // namespace GUI +} // namespace Slic3r + +#endif // slic3r_GLGizmoText_hpp_ \ No newline at end of file diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 21a8be5bc6..b8b3ddef99 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -22,6 +22,7 @@ #include "slic3r/GUI/Gizmos/GLGizmoSeam.hpp" #include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp" #include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp" +#include "slic3r/GUI/Gizmos/GLGizmoText.hpp" #include "libslic3r/format.hpp" #include "libslic3r/Model.hpp" @@ -146,6 +147,7 @@ bool GLGizmosManager::init() m_gizmos.emplace_back(new GLGizmoAdvancedCut(m_parent, "toolbar_cut.svg", EType::Cut)); m_gizmos.emplace_back(new GLGizmoFdmSupports(m_parent, "toolbar_support.svg", EType::FdmSupports)); m_gizmos.emplace_back(new GLGizmoSeam(m_parent, "toolbar_seam.svg", EType::Seam)); + m_gizmos.emplace_back(new GLGizmoText(m_parent, "toolbar_text.svg", EType::Text)); m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", EType::MmuSegmentation)); m_gizmos.emplace_back(new GLGizmoSimplify(m_parent, "reduce_triangles.svg", EType::Simplify)); //m_gizmos.emplace_back(new GLGizmoSlaSupports(m_parent, "sla_supports.svg", sprite_id++)); @@ -194,6 +196,37 @@ bool GLGizmosManager::init_icon_textures() else return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_B, texture_id)); + else + return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B_hover.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_B_HOVER, texture_id)); + else + return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_B_press.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_B_PRESS, texture_id)); + else + return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_T, texture_id)); + else + return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T_hover.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_T_HOVER, texture_id)); + else + return false; + + if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/text_T_press.svg", 20, 20, texture_id)) + icon_list.insert(std::make_pair((int)IC_TEXT_T_PRESS, texture_id)); + else + return false; + return true; } @@ -1379,7 +1412,8 @@ void GLGizmosManager::update_on_off_state(const Vec2d& mouse_pos) size_t idx = get_gizmo_idx_from_mouse(mouse_pos); if (idx != Undefined && m_gizmos[idx]->is_activable() && m_hover == idx) { activate_gizmo(m_current == idx ? Undefined : (EType)idx); - wxGetApp().obj_list()->select_object_item((EType)idx <= Rotate); + // BBS + wxGetApp().obj_list()->select_object_item((EType)idx <= Scale); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 20584e7c47..c1338fdf38 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -72,6 +72,8 @@ public: Cut, FdmSupports, Seam, + // BBS + Text, MmuSegmentation, Simplify, SlaSupports, @@ -149,6 +151,12 @@ public: IC_TOOLBAR_RESET_HOVER, IC_TOOLBAR_TOOLTIP, IC_TOOLBAR_TOOLTIP_HOVER, + IC_TEXT_B, + IC_TEXT_B_HOVER, + IC_TEXT_B_PRESS, + IC_TEXT_T, + IC_TEXT_T_HOVER, + IC_TEXT_T_PRESS, IC_NAME_COUNT, }; diff --git a/src/slic3r/GUI/HMS.cpp b/src/slic3r/GUI/HMS.cpp index 203b2d3217..63ce64cb21 100644 --- a/src/slic3r/GUI/HMS.cpp +++ b/src/slic3r/GUI/HMS.cpp @@ -83,7 +83,11 @@ int HMSQuery::load_from_local(std::string &version_info) return -1; } std::string filename = get_hms_file(); - std::string dir_str = (boost::filesystem::path(data_dir()) / filename).make_preferred().string(); + auto hms_folder = (boost::filesystem::path(data_dir()) / "hms"); + if (!fs::exists(hms_folder)) + fs::create_directory(hms_folder); + + std::string dir_str = (hms_folder / filename).make_preferred().string(); std::ifstream json_file(encode_path(dir_str.c_str())); try { if (json_file.is_open()) { @@ -111,7 +115,10 @@ int HMSQuery::save_to_local() return -1; } std::string filename = get_hms_file(); - std::string dir_str = (boost::filesystem::path(data_dir()) / filename).make_preferred().string(); + auto hms_folder = (boost::filesystem::path(data_dir()) / "hms"); + if (!fs::exists(hms_folder)) + fs::create_directory(hms_folder); + std::string dir_str = (hms_folder / filename).make_preferred().string(); std::ofstream json_file(encode_path(dir_str.c_str())); if (json_file.is_open()) { json_file << std::setw(4) << m_hms_json << std::endl; diff --git a/src/slic3r/GUI/HMSPanel.cpp b/src/slic3r/GUI/HMSPanel.cpp index 45a3c7a683..07e0bdce5e 100644 --- a/src/slic3r/GUI/HMSPanel.cpp +++ b/src/slic3r/GUI/HMSPanel.cpp @@ -83,9 +83,8 @@ HMSNotifyItem::HMSNotifyItem(wxWindow *parent, HMSItem& item) } }); m_hms_content->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) { - if(!m_url.empty()) - wxLaunchDefaultBrowser(get_hms_wiki_url(m_hms_item.get_long_error_code())); - }); + if (!m_url.empty()) wxLaunchDefaultBrowser(m_url); + }); } HMSNotifyItem ::~HMSNotifyItem() { ; diff --git a/src/slic3r/GUI/IMSlider.cpp b/src/slic3r/GUI/IMSlider.cpp index ac3c0da2b1..7bda99eb88 100644 --- a/src/slic3r/GUI/IMSlider.cpp +++ b/src/slic3r/GUI/IMSlider.cpp @@ -521,6 +521,11 @@ Info IMSlider::GetTicksValues() const void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z) { + if (!m_can_change_color) { + m_ticks.erase_all_ticks_with_code(ToolChange); + return; + } + if (m_values.empty()) { m_ticks.mode = m_mode; return; @@ -584,7 +589,7 @@ void IMSlider::SetDrawMode(bool is_sequential_print) dmRegular; } -void IMSlider::SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder) +void IMSlider::SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder, bool can_change_color) { m_mode = !is_one_extruder_printed_model ? MultiExtruder : only_extruder < 0 ? SingleExtruder : MultiAsSingle; if (!m_ticks.mode || (m_ticks.empty() && m_ticks.mode != m_mode)) m_ticks.mode = m_mode; @@ -593,6 +598,8 @@ void IMSlider::SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, UseDefaultColors(m_mode == SingleExtruder); m_is_wipe_tower = m_mode != SingleExtruder; + + m_can_change_color = can_change_color; } void IMSlider::SetExtruderColors( const std::vector& extruder_colors) @@ -1252,7 +1259,10 @@ void IMSlider::render_menu() //BBS render this menu item only when extruder_num > 1 if (extruder_num > 1) { - if (begin_menu(_u8L("Change Filament").c_str())) { + if (!m_can_change_color) { + begin_menu(_u8L("Change Filament").c_str(), false); + } + else if (begin_menu(_u8L("Change Filament").c_str())) { for (int i = 0; i < extruder_num; i++) { std::array rgba = decode_color_to_float_array(colors[i]); ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f); diff --git a/src/slic3r/GUI/IMSlider.hpp b/src/slic3r/GUI/IMSlider.hpp index 5967bcd875..c30c7451cf 100644 --- a/src/slic3r/GUI/IMSlider.hpp +++ b/src/slic3r/GUI/IMSlider.hpp @@ -245,7 +245,7 @@ public: void SetExtraStyle(long style) { m_extra_style = style; } void SetManipulationMode(Mode mode) { m_mode = mode; } Mode GetManipulationMode() const { return m_mode; } - void SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder); + void SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder, bool can_change_color); void SetExtruderColors(const std::vector &extruder_colors); bool IsNewPrint(); @@ -360,6 +360,7 @@ private: std::vector m_layers_times; std::vector m_layers_values; std::vector m_extruder_colors; + bool m_can_change_color; std::string m_print_obj_idxs; bool m_is_need_post_tick_changed_event { false }; Type m_tick_change_event_type; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index f3fe8d7704..b78cacde0b 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -543,7 +543,7 @@ bool ImGuiWrapper::bbl_slider_float_style(const std::string &label, float *v, fl ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 0.00f)); ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 0.00f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(0.81f, 0.81f, 0.81f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); bool ret = bbl_slider_float(label, v, v_min,v_max, format, power, clamp,tooltip); @@ -1643,6 +1643,7 @@ void ImGuiWrapper::push_toolbar_style(const float scale) ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale); ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f * scale); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(50/255.0f, 58/255.0f, 61/255.0f, 1.00f)); // 1 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG); // 2 @@ -1665,7 +1666,7 @@ void ImGuiWrapper::pop_toolbar_style() { // size in push toolbar style ImGui::PopStyleColor(15); - ImGui::PopStyleVar(5); + ImGui::PopStyleVar(6); } void ImGuiWrapper::push_menu_style(const float scale) diff --git a/src/slic3r/GUI/ImageGrid.cpp b/src/slic3r/GUI/ImageGrid.cpp index 5305ec97d1..1a1751fb8f 100644 --- a/src/slic3r/GUI/ImageGrid.cpp +++ b/src/slic3r/GUI/ImageGrid.cpp @@ -138,7 +138,7 @@ void Slic3r::GUI::ImageGrid::DoAction(size_t index, int action) if (action == 0) { m_file_sys->DeleteFiles(index); } else { - if (index >= 0) { + if (index != -1) { auto &file = m_file_sys->GetFile(index); if (file.IsDownload() && file.progress >= -1) { if (file.progress >= 100) { @@ -480,13 +480,13 @@ void ImageGrid::render(wxDC& dc) if (file.IsDownload()) { if (file.progress == -1) { secondAction = _L("Cancel"); - dc.DrawText(_L("Waiting"), pt + wxPoint{24, m_image_size.GetHeight() - 36}); + dc.DrawText(_L("Waiting"), pt + wxPoint{24, m_image_size.GetHeight() - 64}); } else if (file.progress < 0) { secondAction = _L("Retry"); - dc.DrawText(_L("Failed"), pt + wxPoint{24, m_image_size.GetHeight() - 36}); + dc.DrawText(_L("Failed"), pt + wxPoint{24, m_image_size.GetHeight() - 64}); } else if (file.progress >= 100) { secondAction = _L("Open"); - dc.DrawText(_L("Finished"), pt + wxPoint{24, m_image_size.GetHeight() - 36}); + dc.DrawText(_L("Finished"), pt + wxPoint{24, m_image_size.GetHeight() - 64}); } else { secondAction = _L("Cancel"); if (file.progress != m_background_progress) { @@ -567,7 +567,7 @@ void Slic3r::GUI::ImageGrid::renderButtons(wxDC &dc, wxStringList const &texts, wxRect rect(rect2); rect.SetWidth(rect.GetWidth() / texts.size()); int state = m_pressed ? StateColor::Pressed : StateColor::Hovered; - dc.SetFont(Label::Body_12); + dc.SetFont(Label::Body_14); //mdc.SelectObject(m_button_background); for (size_t i = 0; i < texts.size(); ++i) { int states = hit == i ? state : 0; diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index db760503ad..f56c8e546b 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -152,6 +152,7 @@ void PrintJob::process() params.task_record_timelapse= this->task_record_timelapse; params.ams_mapping = this->task_ams_mapping; params.connection_type = this->connection_type; + params.task_use_ams = this->task_use_ams; // local print access params.dev_ip = m_dev_ip; @@ -221,9 +222,19 @@ void PrintJob::process() return was_canceled(); }; + NetworkAgent* m_agent = wxGetApp().getAgent(); if (params.connection_type != "lan") { + if (params.dev_ip.empty()) + params.comments = "no_ip"; + else if (this->cloud_print_only) + params.comments = "low_version"; + else if (!this->has_sdcard) + params.comments = "no_sdcard"; + else if (params.password.empty()) + params.comments = "no_password"; + if (!this->cloud_print_only && !params.password.empty() && !params.dev_ip.empty() @@ -232,6 +243,13 @@ void PrintJob::process() BOOST_LOG_TRIVIAL(info) << "print_job: try to start local print with record"; this->update_status(curr_percent, _L("Sending print job over LAN")); result = m_agent->start_local_print_with_record(params, update_fn, cancel_fn); + if (result == BAMBU_NETWORK_ERR_FTP_LOGIN_DENIED) { + params.comments = "wrong_code"; + } else if (result == BAMBU_NETWORK_ERR_FTP_UPLOAD_FAILED) { + params.comments = "upload_failed"; + } else { + params.comments = (boost::format("failed(%1%)") % result).str(); + } if (result < 0) { // try to send with cloud BOOST_LOG_TRIVIAL(warning) << "print_job: try to send with cloud"; diff --git a/src/slic3r/GUI/Jobs/PrintJob.hpp b/src/slic3r/GUI/Jobs/PrintJob.hpp index dae9d1ea50..86b13fa585 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.hpp +++ b/src/slic3r/GUI/Jobs/PrintJob.hpp @@ -50,6 +50,7 @@ public: std::string connection_type; bool cloud_print_only { false }; bool has_sdcard { false }; + bool task_use_ams { true }; void set_print_config(std::string bed_type, bool bed_leveling, bool flow_cali, bool vabration_cali, bool record_timelapse, bool layer_inspect) { diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index ef26876e95..7d285d3ef4 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -181,6 +181,11 @@ void KBShortcutsDialog::fill_shortcuts() { ctrl + "X", L("Cut") }, { ctrl + "C", L("Copy to clipboard") }, { ctrl + "V", L("Paste from clipboard") }, + // Configuration + { ctrl + "P", L("Preferences") }, + //3D control + { ctrl + "M", L("Show/Hide 3Dconnexion devices settings dialog") }, + //DEL #ifdef __APPLE__ {"fn+⌫", L("Delete selected")}, #else @@ -215,7 +220,6 @@ void KBShortcutsDialog::fill_shortcuts() {L("Arrow Left"), L("Move selection 10 mm in negative X direction")}, {L("Arrow Right"), L("Move selection 10 mm in positive X direction")}, {L("Shift+Any arrow"), L("Movement step set to 1 mm")}, - {"Esc", L("Deselect all")}, {"1-9", L("keyboard 1-9: set filament for object/part")}, {ctrl + "0", L("Camera view - Default")}, @@ -225,11 +229,11 @@ void KBShortcutsDialog::fill_shortcuts() {ctrl + "4", L("Camera view - Behind")}, {ctrl + "5", L("Camera Angle - Left side")}, {ctrl + "6", L("Camera Angle - Right side")}, + {ctrl + "A", L("Select all objects")}, {ctrl + "D", L("Delete all")}, {ctrl + "Z", L("Undo")}, {ctrl + "Y", L("Redo")}, - {ctrl + "M", L("Clone selected")}, { "M", L("Gizmo move") }, { "S", L("Gizmo scale") }, { "R", L("Gizmo rotate") }, @@ -237,6 +241,7 @@ void KBShortcutsDialog::fill_shortcuts() { "F", L("Gizmo Place face on bed") }, { "L", L("Gizmo SLA support points") }, { "P", L("Gizmo FDM paint-on seam") }, + }; m_full_shortcuts.push_back({ { _L("Plater"), "" }, plater_shortcuts }); @@ -245,13 +250,11 @@ void KBShortcutsDialog::fill_shortcuts() {"Shift+", L("Move: press to snap by 1mm") }, #ifdef __APPLE__ {L("⌘+Mouse wheel"), L("Support/Color Painting: adjust pen radius")}, - {L("⌘+Mouse wheel"), L("Support/Color Painting: adjust section position")}, + {L("⌥+Mouse wheel"), L("Support/Color Painting: adjust section position")}, #else {L("Ctrl+Mouse wheel"), L("Support/Color Painting: adjust pen radius")}, {L("Alt+Mouse wheel"), L("Support/Color Painting: adjust section position")}, #endif - - }; m_full_shortcuts.push_back({{_L("Gizmo"), ""}, gizmos_shortcuts}); @@ -293,7 +296,6 @@ void KBShortcutsDialog::fill_shortcuts() m_full_shortcuts.push_back({ { _L("Preview"), "" }, preview_shortcuts }); } - wxPanel* KBShortcutsDialog::create_page(wxWindow* parent, const ShortcutsItem& shortcuts, const wxFont& font, const wxFont& bold_font) { wxPanel* main_page = new wxPanel(parent); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 21d0b36f3f..d5da1872b1 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1241,6 +1241,7 @@ wxBoxSizer* MainFrame::create_side_tools() m_slice_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { //this->m_plater->select_view_3D("Preview"); + m_plater->update(); if (m_slice_select == eSliceAll) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_ALL)); else @@ -1692,7 +1693,10 @@ static wxMenu* generate_help_menu() static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, std::function can_change_view) { // The camera control accelerators are captured by GLCanvas3D::on_char(). - append_menu_item(view_menu, wxID_ANY, _L("Default View") + "\tCtrl+0", _L("Default View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("topfront"); }, + append_menu_item(view_menu, wxID_ANY, _L("Default View") + "\tCtrl+0", _L("Default View"), [mainFrame](wxCommandEvent&) { + mainFrame->select_view("plate"); + mainFrame->plater()->get_current_canvas3D()->zoom_to_bed(); + }, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); //view_menu->AppendSeparator(); //TRN To be shown in the main menu View->Top @@ -1782,18 +1786,24 @@ void MainFrame::init_menubar_as_editor() fileMenu->AppendSeparator(); - //BBS + // BBS + wxMenu *import_menu = new wxMenu(); #ifdef __WINDOWS__ - append_menu_item(fileMenu, wxID_ANY, _L("Import 3MF/STL/STEP/OBJ/AMF") + dots + "\tCtrl+I", _L("Load a model"), + append_menu_item(import_menu, wxID_ANY, _L("Import 3MF/STL/STEP/OBJ/AMF") + dots + "\tCtrl+I", _L("Load a model"), [this](wxCommandEvent&) { if (m_plater) { m_plater->add_model(); } }, "menu_import", nullptr, [this](){return can_add_models(); }, this); #else - append_menu_item(fileMenu, wxID_ANY, _L("Import 3MF/STL/STEP/OBJ/AMF") + dots + "\tCtrl+I", _L("Load a model"), + append_menu_item(import_menu, wxID_ANY, _L("Import 3MF/STL/STEP/OBJ/AMF") + dots + "\tCtrl+I", _L("Load a model"), [this](wxCommandEvent&) { if (m_plater) { m_plater->add_model(); } }, "", nullptr, [this](){return can_add_models(); }, this); #endif + append_menu_item(import_menu, wxID_ANY, _L("Import Configs") + dots /*+ "\tCtrl+I"*/, _L("Load configs"), + [this](wxCommandEvent&) { load_config_file(); }, "menu_import", nullptr, + [this](){return true; }, this); + + append_submenu(fileMenu, import_menu, wxID_ANY, _L("Import"), ""); wxMenu* export_menu = new wxMenu(); @@ -1801,6 +1811,9 @@ void MainFrame::init_menubar_as_editor() append_menu_item(export_menu, wxID_ANY, _L("Export all objects as STL") + dots, _L("Export all objects as STL"), [this](wxCommandEvent&) { if (m_plater) m_plater->export_stl(); }, "menu_export_stl", nullptr, [this](){return can_export_model(); }, this); + append_menu_item(export_menu, wxID_ANY, _L("Export Generic 3MF") + dots/* + "\tCtrl+G"*/, _L("Export 3mf file without using some 3mf-extensions"), + [this](wxCommandEvent&) { if (m_plater) m_plater->export_core_3mf(); }, "menu_export_sliced_file", nullptr, + [this](){return can_export_model(); }, this); // BBS export .gcode.3mf append_menu_item(export_menu, wxID_ANY, _L("Export Sliced File") + dots/* + "\tCtrl+G"*/, _L("Export current Sliced file"), [this](wxCommandEvent&) { if (m_plater) wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_EXPORT_SLICED_FILE)); }, "menu_export_sliced_file", nullptr, @@ -1808,6 +1821,11 @@ void MainFrame::init_menubar_as_editor() append_menu_item(export_menu, wxID_ANY, _L("Export G-code") + dots/* + "\tCtrl+G"*/, _L("Export current plate as G-code"), [this](wxCommandEvent&) { if (m_plater) m_plater->export_gcode(false); }, "menu_export_gcode", nullptr, [this]() {return can_export_gcode(); }, this); + append_menu_item( + export_menu, wxID_ANY, _L("Export &Configs") + dots /* + "\tCtrl+E"*/, _L("Export current configuration to files"), + [this](wxCommandEvent &) { export_config(); }, + "menu_export_config", nullptr, + []() { return true; }, this); append_submenu(fileMenu, export_menu, wxID_ANY, _L("Export"), ""); @@ -1866,7 +1884,7 @@ void MainFrame::init_menubar_as_editor() "menu_remove", nullptr, [this](){return can_delete_all(); }, this); editMenu->AppendSeparator(); // BBS Clone Selected - append_menu_item(editMenu, wxID_ANY, _L("Clone selected") + "\tCtrl+M", + append_menu_item(editMenu, wxID_ANY, _L("Clone selected") /*+ "\tCtrl+M"*/, _L("Clone copies of selections"),[this](wxCommandEvent&) { m_plater->clone_selection(); }, @@ -1981,7 +1999,7 @@ void MainFrame::init_menubar_as_editor() #ifdef __APPLE__ wxWindowID bambu_studio_id_base = wxWindow::NewControlId(int(2)); wxMenu* parent_menu = m_menubar->OSXGetAppleMenu(); - auto preference_item = new wxMenuItem(parent_menu, BambuStudioMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\tCtrl+,", ""); + //auto preference_item = new wxMenuItem(parent_menu, BambuStudioMenuPreferences + bambu_studio_id_base, _L("Preferences") + "\tCtrl+,", ""); #else wxMenu* parent_menu = m_topbar->GetTopMenu(); auto preference_item = new wxMenuItem(parent_menu, ConfigMenuPreferences + config_id_base, _L("Preferences") + "\tCtrl+P", ""); @@ -2056,7 +2074,7 @@ void MainFrame::init_menubar_as_editor() #ifdef __APPLE__ wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME); - auto about_item = new wxMenuItem(parent_menu, BambuStudioMenuAbout + bambu_studio_id_base, about_title, ""); + //auto about_item = new wxMenuItem(parent_menu, BambuStudioMenuAbout + bambu_studio_id_base, about_title, ""); //parent_menu->Bind(wxEVT_MENU, [this, bambu_studio_id_base](wxEvent& event) { // switch (event.GetId() - bambu_studio_id_base) { // case BambuStudioMenuAbout: @@ -2080,11 +2098,11 @@ void MainFrame::init_menubar_as_editor() //}); //parent_menu->Insert(0, about_item); append_menu_item( - parent_menu, wxID_ANY, _L("About") + "", _L(""), + parent_menu, wxID_ANY, _L(about_title), _L(""), [this](wxCommandEvent &) { Slic3r::GUI::about();}, "", nullptr, []() { return true; }, this, 0); append_menu_item( - parent_menu, wxID_ANY, _L("Preferences") + "\tCtrl+'", _L(""), + parent_menu, wxID_ANY, _L("Preferences") + "\tCtrl+,", _L(""), [this](wxCommandEvent &) { PreferencesDialog dlg(this); dlg.ShowModal(); @@ -2129,13 +2147,13 @@ void MainFrame::init_menubar_as_editor() //m_topbar->AddDropDownMenuItem(config_item); m_topbar->AddDropDownSubMenu(helpMenu, _L("Help")); #else - m_menubar->Append(fileMenu, _L("&File")); + m_menubar->Append(fileMenu, wxString::Format("&%s", _L("File"))); if (editMenu) - m_menubar->Append(editMenu, _L("&Edit")); + m_menubar->Append(editMenu, wxString::Format("&%s", _L("Edit"))); if (viewMenu) - m_menubar->Append(viewMenu, _L("&View")); + m_menubar->Append(viewMenu, wxString::Format("&%s", _L("View"))); if (helpMenu) - m_menubar->Append(helpMenu, _L("&Help")); + m_menubar->Append(helpMenu, wxString::Format("&%s", _L("Help"))); SetMenuBar(m_menubar); #endif @@ -2258,28 +2276,48 @@ void MainFrame::reslice_now() m_plater->reslice(); } +struct ConfigsOverwriteConfirmDialog : MessageDialog +{ + ConfigsOverwriteConfirmDialog(wxWindow *parent, wxString name, bool exported) + : MessageDialog(parent, + wxString::Format(exported ? _("A file exists with the same name: %s, do you wan't to override it.") : + _("A config exists with the same name: %s, do you wan't to override it."), + name), + _L(exported ? "Overwrite file" : "Overwrite config"), + wxYES_NO | wxNO_DEFAULT) + { + add_button(wxID_YESTOALL, false, _L("Yes to All")); + add_button(wxID_NOTOALL, false, _L("No to All")); + } +}; + void MainFrame::export_config() { // Generate a cummulative configuration for the selected print, filaments and printer. - auto config = wxGetApp().preset_bundle->full_config(); - // Validate the cummulative configuration. - auto valid = config.validate(); - if (! valid.empty()) { - show_error(this, valid); - return; - } - // Ask user for the file name for the config file. - wxFileDialog dlg(this, _L("Save configuration as:"), - !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), - !m_last_config.IsEmpty() ? get_base_name(m_last_config) : "config.ini", - file_wildcards(FT_INI), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); - wxString file; + wxDirDialog dlg(this, _L("Choose a directory"), + from_u8(!m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir()), wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + wxString path; if (dlg.ShowModal() == wxID_OK) - file = dlg.GetPath(); - if (!file.IsEmpty()) { - wxGetApp().app_config->update_config_dir(get_dir_name(file)); - m_last_config = file; - config.save(file.ToUTF8().data()); + path = dlg.GetPath(); + if (!path.IsEmpty()) { + // Export the config bundle. + wxGetApp().app_config->update_config_dir(into_u8(path)); + try { + auto files = wxGetApp().preset_bundle->export_current_configs(into_u8(path), [this](std::string const & name) { + ConfigsOverwriteConfirmDialog dlg(this, from_u8(name), true); + int res = dlg.ShowModal(); + int ids[]{wxID_NO, wxID_YES, wxID_NOTOALL, wxID_YESTOALL}; + return std::find(ids, ids + 4, res) - ids; + }, false); + if (!files.empty()) + m_last_config = from_u8(files.back()); + MessageDialog dlg(this, wxString::Format(_L_PLURAL("There is %d config exported. (Only non-system configs)", + "There are %d configs exported. (Only non-system configs)", files.size()), files.size()), + _L("Export result"), wxOK); + dlg.ShowModal(); + } catch (const std::exception &ex) { + show_error(this, ex.what()); + } } } @@ -2289,16 +2327,34 @@ void MainFrame::load_config_file() //BBS do not load config file // if (!wxGetApp().check_and_save_current_preset_changes(_L("Loading profile file"), "", false)) // return; - // wxFileDialog dlg(this, _L("Select profile to load:"), - // !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), - // "config.json", "INI files (*.ini, *.gcode)|*.json;;*.gcode;*.g", wxFD_OPEN | wxFD_FILE_MUST_EXIST); - // wxString file; - // if (dlg.ShowModal() == wxID_OK) - // file = dlg.GetPath(); - // if (! file.IsEmpty() && this->load_config_file(file.ToUTF8().data())) { - // wxGetApp().app_config->update_config_dir(get_dir_name(file)); - // m_last_config = file; - // } + wxFileDialog dlg(this, _L("Select profile to load:"), + !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), + "config.json", "Config files (*.json)|*.json", wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); + wxArrayString files; + if (dlg.ShowModal() != wxID_OK) + return; + dlg.GetPaths(files); + std::vector cfiles; + for (auto file : files) { + cfiles.push_back(into_u8(file)); + m_last_config = file; + } + bool update = false; + wxGetApp().preset_bundle->import_presets(cfiles, [this](std::string const & name) { + ConfigsOverwriteConfirmDialog dlg(this, from_u8(name), false); + int res = dlg.ShowModal(); + int ids[]{wxID_NO, wxID_YES, wxID_NOTOALL, wxID_YESTOALL}; + return std::find(ids, ids + 4, res) - ids; + }, + ForwardCompatibilitySubstitutionRule::Enable); + if (!cfiles.empty()) { + wxGetApp().app_config->update_config_dir(get_dir_name(cfiles.back())); + wxGetApp().load_current_presets(); + } + MessageDialog dlg2(this, wxString::Format(_L_PLURAL("There is %d config imported. (Only non-system and compatible configs)", + "There are %d configs imported. (Only non-system and compatible configs)", cfiles.size()), cfiles.size()), + _L("Import result"), wxOK); + dlg2.ShowModal(); } // Load a config file containing a Print, Filament & Printer preset from command line. @@ -2656,6 +2712,28 @@ void MainFrame::open_recent_project(size_t file_id, wxString const & filename) } } +void MainFrame::remove_recent_project(size_t file_id, wxString const &filename) +{ + if (file_id == size_t(-1)) { + if (filename.IsEmpty()) + while (m_recent_projects.GetCount() > 0) + m_recent_projects.RemoveFileFromHistory(0); + else + file_id = m_recent_projects.FindFileInHistory(filename); + } + if (file_id != size_t(-1)) + m_recent_projects.RemoveFileFromHistory(file_id); + std::vector recent_projects; + size_t count = m_recent_projects.GetCount(); + for (size_t i = 0; i < count; ++i) + { + recent_projects.push_back(into_u8(m_recent_projects.GetHistoryFile(i))); + } + wxGetApp().app_config->set_recent_projects(recent_projects); + wxGetApp().app_config->save(); + m_webview->SendRecentList(""); +} + void MainFrame::load_url(wxString url) { BOOST_LOG_TRIVIAL(trace) << "load_url:" << url; @@ -2760,7 +2838,7 @@ std::string MainFrame::get_base_name(const wxString &full_name, const char *exte std::string MainFrame::get_dir_name(const wxString &full_name) const { - return boost::filesystem::path(full_name.wx_str()).parent_path().string(); + return boost::filesystem::path(into_u8(full_name)).parent_path().string(); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 321b92af87..affaf2fc13 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -299,6 +299,7 @@ public: void add_to_recent_projects(const wxString& filename); void get_recent_projects(boost::property_tree::wptree & tree); void open_recent_project(size_t file_id, wxString const & filename); + void remove_recent_project(size_t file_id, wxString const &filename); void technology_changed(); diff --git a/src/slic3r/GUI/MediaFilePanel.cpp b/src/slic3r/GUI/MediaFilePanel.cpp index 5c8f1a42d5..de4ee7970d 100644 --- a/src/slic3r/GUI/MediaFilePanel.cpp +++ b/src/slic3r/GUI/MediaFilePanel.cpp @@ -53,19 +53,23 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent) m_type_panel->SetCornerRadius(FromDIP(5)); m_type_panel->SetMinSize({-1, 48 * em_unit(this) / 10}); m_button_timelapse = new ::Button(m_type_panel, _L("Timelapse"), "", wxBORDER_NONE); - m_button_video = new ::Button(m_type_panel, _L("Video"), "", wxBORDER_NONE); + m_button_timelapse->SetCanFocus(false); + m_button_video = new ::Button(m_type_panel, _L("Video"), "", wxBORDER_NONE); + m_button_video->SetCanFocus(false); wxBoxSizer *type_sizer = new wxBoxSizer(wxHORIZONTAL); type_sizer->Add(m_button_timelapse, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 24); type_sizer->Add(m_button_video, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 24); m_type_panel->SetSizer(type_sizer); - top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL); + //top_sizer->Add(m_type_panel, 0, wxALIGN_CENTER_VERTICAL); // File management m_manage_panel = new ::StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); m_manage_panel->SetBackgroundColor(StateColor()); m_button_delete = new ::Button(m_manage_panel, _L("Delete")); - m_button_download = new ::Button(m_manage_panel, _L("Download")); + m_button_delete->SetCanFocus(false); + m_button_download = new ::Button(m_manage_panel, _L("Download")); + m_button_download->SetCanFocus(false); m_button_management = new ::Button(m_manage_panel, _L("Management")); wxBoxSizer *manage_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -110,7 +114,10 @@ MediaFilePanel::MediaFilePanel(wxWindow * parent) auto b = dynamic_cast