├── LICENSE ├── PluginPreferences.py ├── README.md ├── README.zh-cn.md ├── __init__.py ├── config.py ├── gcode_writer ├── SnapmakerGCodeWriter.py └── __init__.py ├── network_plugin ├── DiscoverSocket.py ├── HTTPNetworkedPrinterOutputDevice.py ├── HTTPTokenManager.py ├── SACP.py ├── SACPNetworkedPrinterOutputDevice.py ├── Snapamker2OutputDevice.py ├── SnapmakerArtisanOutputDevice.py ├── SnapmakerJ1OutputDevice.py ├── SnapmakerOutputDevicePlugin.py └── __init__.py ├── plugin.json ├── resources ├── materials │ ├── snapmaker_abs_black.xml.fdm_material │ ├── snapmaker_breakaway_white.xml.fdm_material │ ├── snapmaker_petg_white.xml.fdm_material │ ├── snapmaker_pla_white.xml.fdm_material │ ├── snapmaker_pva_white.xml.fdm_material │ └── snapmaker_tpu_white.xml.fdm_material ├── snapmaker_2_dual_extruder │ ├── definitions │ │ ├── snapmaker_2_a150_dual_extruder.def.json │ │ ├── snapmaker_2_a250_dual_extruder.def.json │ │ ├── snapmaker_2_a350_dual_extruder.def.json │ │ └── snapmaker_2_dual_extruder.def.json │ ├── extruders │ │ ├── snapmaker_2_dual_extruder_0.def.json │ │ └── snapmaker_2_dual_extruder_1.def.json │ └── quality │ │ └── snapmaker_2_dual_extruder │ │ ├── snapmaker_2_dual_extruder_PLA_Draft.inst.cfg │ │ ├── snapmaker_2_dual_extruder_PLA_Fast.inst.cfg │ │ ├── snapmaker_2_dual_extruder_PLA_Fine.inst.cfg │ │ ├── snapmaker_2_dual_extruder_PLA_Normal.inst.cfg │ │ ├── snapmaker_2_dual_extruder_global_Draft.inst.cfg │ │ ├── snapmaker_2_dual_extruder_global_Fast.inst.cfg │ │ ├── snapmaker_2_dual_extruder_global_Fine.inst.cfg │ │ └── snapmaker_2_dual_extruder_global_Normal.inst.cfg ├── snapmaker_artisan │ ├── definitions │ │ └── snapmaker_artisan.def.json │ ├── extruders │ │ ├── snapmaker_artisan_extruder_0.def.json │ │ └── snapmaker_artisan_extruder_1.def.json │ └── quality │ │ └── snapmaker_artisan │ │ ├── artisan_PLA_Draft.inst.cfg │ │ ├── artisan_PLA_Fast.inst.cfg │ │ ├── artisan_PLA_Fine.inst.cfg │ │ ├── artisan_PLA_Normal.inst.cfg │ │ ├── artisan_global_Draft.inst.cfg │ │ ├── artisan_global_Fast.inst.cfg │ │ ├── artisan_global_Fine.inst.cfg │ │ └── artisan_global_Normal.inst.cfg └── snapmaker_j1_profiles │ ├── definitions │ └── snapmaker_j1.def.json │ ├── extruders │ ├── snapmaker_j1_extruder_0.def.json │ └── snapmaker_j1_extruder_1.def.json │ └── quality │ └── snapmaker_j1 │ ├── j1_ABS_Draft.inst.cfg │ ├── j1_ABS_Fast.inst.cfg │ ├── j1_ABS_Fine.inst.cfg │ ├── j1_ABS_Normal.inst.cfg │ ├── j1_Breakaway_Draft.inst.cfg │ ├── j1_Breakaway_Fast.inst.cfg │ ├── j1_Breakaway_Fine.inst.cfg │ ├── j1_Breakaway_Normal.inst.cfg │ ├── j1_PETG_Draft.inst.cfg │ ├── j1_PETG_Fast.inst.cfg │ ├── j1_PETG_Fine.inst.cfg │ ├── j1_PETG_Normal.inst.cfg │ ├── j1_PLA_Draft.inst.cfg │ ├── j1_PLA_Fast.inst.cfg │ ├── j1_PLA_Fine.inst.cfg │ ├── j1_PLA_Normal.inst.cfg │ ├── j1_PVA_Draft.inst.cfg │ ├── j1_PVA_Fast.inst.cfg │ ├── j1_PVA_Fine.inst.cfg │ ├── j1_PVA_Normal.inst.cfg │ ├── j1_TPU_Draft.inst.cfg │ ├── j1_TPU_Fast.inst.cfg │ ├── j1_TPU_Fine.inst.cfg │ ├── j1_TPU_Normal.inst.cfg │ ├── j1_global_Draft.inst.cfg │ ├── j1_global_Fast.inst.cfg │ ├── j1_global_Fine.inst.cfg │ └── j1_global_Normal.inst.cfg └── settings_plugin └── SnapmakerSettingsPlugin.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 parachvte 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PluginPreferences.py: -------------------------------------------------------------------------------- 1 | from UM.Application import Application 2 | from typing import TYPE_CHECKING, Any 3 | 4 | if TYPE_CHECKING: 5 | from UM.Preferences import Preferences 6 | 7 | 8 | class PluginPreferences: 9 | 10 | def __init__(self, category: str) -> None: 11 | self._category = category 12 | 13 | def getFullKey(self, key) -> str: 14 | if self._category: 15 | return "{}/{}".format(self._category, key) 16 | return key 17 | 18 | def addPrefenrece(self, key: str, default_value: Any) -> None: 19 | preferences = Application.getInstance().getPreferences() # type: Preferences 20 | preferences.addPreference(self.getFullKey(key), default_value) 21 | 22 | def getValue(self, key: str) -> Any: 23 | preferences = Application.getInstance().getPreferences() # type: Preferences 24 | return preferences.getValue(self.getFullKey(key)) 25 | 26 | def setValue(self, key: str, value: Any) -> None: 27 | preferences = Application.getInstance().getPreferences() # type: Preferences 28 | preferences.setValue(self.getFullKey(key), value) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Snapmaker Cura Plugin 2 | 3 | **CAUTION: If you have already installed the `Snapmaker J1 Plugin`, make sure that you uninstall it before installing or updating `Snapmaker Plugin`.** 4 | 5 | [Cura](https://github.com/Ultimaker/Cura) plugin that provides support for Snapmaker J1 & Snapmaker Artisan & Snapmaker 2.0 Dual Extruder. 6 | 7 | Features: 8 | 9 | - Add machine definitions and quality profiles for Snapmaker 3D printers (Snapmaker J1 & Snapmaker Artisan & Snapmaker 2.0 Dual Extruder). 10 | - Add Snapmaker branded materials (including Breakaway Support material). 11 | - Be able to export Snapmaker favoured G-code file format (with informative headers). 12 | - Detect networked printers, and send G-code to the machine. 13 | 14 | ## Before installing the plugin 15 | 16 | Before installing the plugin, make sure you have Cura >= 5 installed. 17 | 18 | When you first launch Cura, user guide may ask you to add a printer. You can add a offline printer, say "Ultimaker S5" for now. 19 | 20 | You will be able to add Snapmaker printers with plugin installed. 21 | 22 | ## How to Install (Marketplace) 23 | 24 | Search "Snapmaker Plugin" in Cura's marketplace (on top right corner of Cura window), and install. 25 | 26 | ## How to Install (Drag and Drop, curapackage release) 27 | 28 | - Download `SnapmakerPlugin-{latest version}.curapackage` in [latest release](https://github.com/Snapmaker/SnapmakerJ1CuraPlugin/releases) tab. 29 | - Drag and drop downloaded ".curapackage" file into Cura window. 30 | - Re-start Cura. 31 | 32 | ## How to Install (Manually, zip release) 33 | 34 | - Download `Source code (zip)` in [latest release](https://github.com/Snapmaker/SnapmakerJ1CuraPlugin/releases). 35 | - Unzip downloaded plugin, rename the folder name to "SnapmakerJ1CuraPlugin" (if it has a version suffix). 36 | - Start Cura applcation. Open *Help Menu* -> *Show Configuration Folder*, copy downloaded plugin folder to `plugins` directory. 37 | - Re-start Cura. 38 | 39 | ## Add Snapmaker printer 40 | 41 | Navigate through application menu, **Settings** > **Printers** > **Add Printer...** 42 | 43 | In the popup window "Add Printer", select "Add a non-networked printer". Scroll down the available printers to find `Snapmaker` brand, check "Snapmaker XXX" option and click "Add". A new "Snapmaker" printer should be added successfully. 44 | 45 | Add Snapmaker J1 printer 46 | 47 | Note that there are several ways in Cura to add a printer, we only cover one in our documentation. 48 | 49 | ## Use Snapmaker materials 50 | 51 | We pre-defined several material under the brand `Snapmaker`, including PLA, ABS, PETG, TPU, PVA and Breakaway. 52 | 53 | Pre-defined materials usually has printing temperatures and retraction parameters well tuned by the manufacturer. You can assign them to extruder and use them directly. 54 | 55 | Take **Breakaway** material for example, you can tap the extruder selector, in the extruder dialog, choose **Material** > **Snapmaker** > **Breakaway** > **Breakaway Support** to use it. 56 | 57 | ## Print via network printer 58 | 59 | Have your models sliced, you can either export the G-code to local file, or send it to a networked Snapmaker machine: 60 | 61 | image 62 | 63 | ## Export Snapmaker Flavor G-code 64 | 65 | Select `Snapmaker Flavor G-code File (*.gcode)` format to export G-code files. 66 | 67 | Export G-code 68 | 69 | ## Other languages 70 | 71 | - [中文简介 README.md](./README.zh-cn.md) 72 | -------------------------------------------------------------------------------- /README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # Snapmaker Cura Plugin 2 | 3 | **注意: 请先卸载 Snapmaker J1 Plugin, 再安装 Snapmaker Plugin。** 4 | 5 | 功能特性: 6 | 7 | - 增加 Snapmaker J1 & Snapmaker Artsian & Snapmaker 2.0 双挤出模块 机型和打印质量配置。 8 | - 增加 Snapmaker 材料(包括 Breakaway 支撑材料)。 9 | - 支持导出 Snapmaker 设备可识别的 G-code 文件。 10 | - 检测联网的 Snapmaker 设备,并传输 G-code 到设备上。 11 | 12 | ## 安装 Cura 5 13 | 14 | 在安装插件之前,确保安装 [Cura 5.0](https://ultimaker.com/software/ultimaker-cura) 以上版本。 15 | 16 | 初次启动 Cura 时,引导流程会要求用户添加一个打印机,这时候我们还未安装插件,可以先选择添加离线的打印机 Ultimaker S5 来跳过引导流程。 17 | 18 | ## 安装插件 (Marketplace) 19 | 20 | 在Cura的市场中搜索 "Snapmaker插件"(位于Cura窗口的右上角),然后安装。 21 | 22 | ## 安装插件 (拖拽安装 curapackage 安装包) 23 | 24 | - 在 [Releases](https://github.com/Snapmaker/SnapmakerCuraPlugin/releases) 中点击 `SnapmakerCuraPlugin-{版本号}.curapackage` 下载最新的插件。 25 | - 拖拽下载的 .curapackage 安装包到 Cura 里。 26 | - 重启 Cura。 27 | 28 | ## 安装插件 (手动安装 zip 压缩文件) 29 | 30 | - 在 [Releases](https://github.com/Snapmaker/SnapmakerCuraPlugin/releases) 中点击 `Source code (zip)` 下载最新的插件。 31 | - 解压 zip 文件,并且将文件夹重命名为 "SnapmakerCuraPlugin" (去掉最后的版本号标识)。 32 | - 在 Cura 的菜单中,「帮助」>「显示配置文件夹」,将 "SnapmakerCuraPlugin" 文件夹复制到「plugins」文件夹中。 33 | - 重启 Cura。 34 | 35 | ## 添加 Snapmaker 打印机 36 | 37 | 在应用程序菜单中, **设置** > **打印机** > **添加打印机...** 38 | 39 | Add Snapmaker printer 40 | 41 | ## 使用 Snapmaker 材料 42 | 43 | 安装插件后,可以在软件中添加 Snapmaker 打印机。添加之后,在软件的主页面选择 Snapmaker 打印机,可见到两个打印头的配置。 44 | 45 | 我们在Snapmaker品牌下预先定义了几种材料,包括PLA、ABS、PETG、TPU、PVA和Breakaway。 46 | 47 | 预先定义的材料通常具有由制造商调整好的打印温度和回缩参数。您可以将它们分配给挤出机并直接使用。 48 | 49 | 以分 Breakaway 材料为例,你可以点击挤出机选择器,在挤出机对话框中,选择材料 > Snapmaker > Breakaway > Breakaway Support来使用它。 50 | 51 | ## 通过网络打印机打印 52 | 让您的模型切片,您可以将G代码导出到本地文件,或者将其发送到联网的 Snapmaker 机器上。 53 | Print via network printer 54 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | from UM.FileHandler.FileWriter import FileWriter 2 | 3 | from .settings_plugin.SnapmakerSettingsPlugin import SnapmakerSettingsPlugin 4 | from .gcode_writer.SnapmakerGCodeWriter import SnapmakerGCodeWriter 5 | from .network_plugin.SnapmakerOutputDevicePlugin import SnapmakerOutputDevicePlugin 6 | 7 | 8 | def getMetaData(): 9 | return { 10 | "mesh_writer": { 11 | "output": [{ 12 | "extension": "gcode", 13 | "description": "Snapmaker Flavor G-code File", 14 | "mime_type": "text/x-snapmaker-gcode", 15 | "mode": FileWriter.OutputMode.TextMode, 16 | }] 17 | } 18 | } 19 | 20 | 21 | def register(app): 22 | """Register plugins.""" 23 | return { 24 | # Extends Snapmaker related settings 25 | "extension": SnapmakerSettingsPlugin(), 26 | 27 | # Writer to write Snapmaker J1 specific G-code 28 | "mesh_writer": SnapmakerGCodeWriter(), 29 | 30 | # Treat networked printers as output devices 31 | "output_device": SnapmakerOutputDevicePlugin(), 32 | } 33 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | SNAPMAKER_2_A150 = dict( 2 | name="Snapmaker A150", 3 | model="Snapmaker 2 Model A150", 4 | header_version=0, # default is 1 5 | ) 6 | 7 | SNAPMAKER_2_A250 = dict( 8 | name="Snapmaker A250", 9 | model="Snapmaker 2 Model A250", 10 | header_version=0, 11 | ) 12 | 13 | SNAPMAKER_2_A350 = dict( 14 | name="Snapmaker A350", 15 | model="Snapmaker 2 Model A350", 16 | header_version=0, 17 | ) 18 | 19 | SNAPMAKER_2_A150_DUAL_EXTRUDER = dict( 20 | name="Snapmaker 2.0 A150 Dual Extruder", 21 | model="Snapmaker 2 Model A150", 22 | header_version=0, 23 | ) 24 | 25 | SNAPMAKER_2_A250_DUAL_EXTRUDER = dict( 26 | name="Snapmaker 2.0 A250 Dual Extruder", 27 | model="Snapmaker 2 Model A250", 28 | header_version=0, 29 | ) 30 | 31 | SNAPMAKER_2_A350_DUAL_EXTRUDER = dict( 32 | name="Snapmaker 2.0 A350 Dual Extruder", 33 | model="Snapmaker 2 Model A350", 34 | header_version=0, 35 | ) 36 | 37 | SNAPMAKER_J1 = dict( 38 | name="Snapmaker J1", 39 | model="Snapmaker J1", 40 | header_version=1, # default is 1 41 | ) 42 | 43 | SNAPMAKER_ARTISAN = dict( 44 | name="Snapmaker Artisan", 45 | model="Snapmaker Artisan", 46 | header_version=1, 47 | ) 48 | 49 | SNAPMAKER_DISCOVER_MACHINES = [ 50 | SNAPMAKER_J1, 51 | SNAPMAKER_ARTISAN, 52 | SNAPMAKER_2_A150, 53 | SNAPMAKER_2_A250, 54 | SNAPMAKER_2_A350, 55 | SNAPMAKER_2_A150_DUAL_EXTRUDER, 56 | SNAPMAKER_2_A250_DUAL_EXTRUDER, 57 | SNAPMAKER_2_A350_DUAL_EXTRUDER, 58 | ] 59 | 60 | 61 | def is_machine_discover_supported(machine_name: str) -> bool: 62 | return machine_name in [machine['name'] for machine in SNAPMAKER_DISCOVER_MACHINES] 63 | -------------------------------------------------------------------------------- /gcode_writer/SnapmakerGCodeWriter.py: -------------------------------------------------------------------------------- 1 | import base64 2 | from typing import List 3 | 4 | from PyQt6.QtCore import QBuffer 5 | from UM.Application import Application 6 | from UM.FileHandler.FileWriter import FileWriter 7 | from UM.Logger import Logger 8 | from UM.Math.AxisAlignedBox import AxisAlignedBox 9 | from UM.Math.Vector import Vector 10 | from UM.Mesh.MeshWriter import MeshWriter 11 | from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator 12 | from UM.i18n import i18nCatalog 13 | 14 | from cura.CuraApplication import CuraApplication 15 | from cura.Settings.ExtruderManager import ExtruderManager 16 | from cura.Snapshot import Snapshot 17 | from cura.Utils.Threading import call_on_qt_thread 18 | from ..config import SNAPMAKER_DISCOVER_MACHINES 19 | 20 | catalog = i18nCatalog("cura") 21 | 22 | 23 | class GCodeInfo: 24 | 25 | def __init__(self) -> None: 26 | self.bbox = AxisAlignedBox() 27 | self.flavor = 'Marlin' 28 | self.line_count = 0 29 | 30 | 31 | class SnapmakerGCodeWriter(MeshWriter): 32 | """GCode Writer that writes G-code in Snapmaker favour. 33 | 34 | - Add Snapmaker specific headers and thumbnail 35 | """ 36 | 37 | def __init__(self) -> None: 38 | super().__init__(add_to_recent_files=True) 39 | 40 | self._extruder_mode = "Default" 41 | self._header_version = 1 42 | 43 | def setExtruderMode(self, extruder_mode: str) -> None: 44 | self._extruder_mode = extruder_mode 45 | 46 | def __detectHeaderVersion(self): 47 | global_stack = CuraApplication.getInstance().getGlobalContainerStack() 48 | machine_name = global_stack.getProperty("machine_name", "value") 49 | 50 | for machine in SNAPMAKER_DISCOVER_MACHINES: 51 | if machine['name'] == machine_name: 52 | break 53 | 54 | self._header_version = machine.get('header_version', 1) if machine else -1 55 | 56 | def write(self, stream, node, mode=FileWriter.OutputMode.BinaryMode) -> None: 57 | """Writes the G-code for the entire scene to a stream. 58 | 59 | Copied from GCodeWriter, do little modifications. 60 | """ 61 | 62 | if mode != MeshWriter.OutputMode.TextMode: 63 | Logger.log("e", "GCodeWriter does not support non-text mode.") 64 | self.setInformation(catalog.i18nc("@error:not supported", "GCodeWriter does not support non-text mode.")) 65 | return False 66 | 67 | active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate 68 | scene = Application.getInstance().getController().getScene() 69 | if not hasattr(scene, "gcode_dict"): 70 | self.setInformation(catalog.i18nc("@warning:status", "Please prepare G-code before exporting.")) 71 | return False 72 | 73 | gcode_dict = getattr(scene, "gcode_dict") 74 | gcode_list = gcode_dict.get(active_build_plate, None) 75 | if gcode_list is not None: 76 | self.processGCodeList(stream, gcode_list) 77 | return True 78 | 79 | self.setInformation(catalog.i18nc("@warning:status", "Please prepare G-code before exporting.")) 80 | return False 81 | 82 | @call_on_qt_thread 83 | def __generateThumbnail(self) -> str: 84 | """Generate thumbnail using PreviewPass. 85 | 86 | Need to be run on Qt thread. 87 | """ 88 | try: 89 | image = Snapshot.snapshot(600, 600) 90 | if not image: 91 | return "" 92 | 93 | buffer = QBuffer() 94 | buffer.open(QBuffer.OpenModeFlag.ReadWrite) 95 | image.save(buffer, "PNG") 96 | base64_bytes = base64.b64encode(buffer.data()) 97 | base64_message = base64_bytes.decode("ascii") 98 | buffer.close() 99 | 100 | return "data:image/png;base64," + base64_message 101 | except Exception: 102 | Logger.logException("w", "Failed to create thumbnail for G-code") 103 | return "" 104 | 105 | def __parseOriginalGCode(self, gcode_list: List[str]) -> GCodeInfo: 106 | """Parse Original GCode to get info. 107 | 108 | ;FLAVOR:Marlin\n;TIME:6183\n;Filament used: 3.21557m, 0m\n;Layer height: 0.1\n;MINX:136.734\n;MINY:74.638\n;MINZ:0.3\n;MAXX:186.578\n;MAXY:125.365\n;MAXZ:52\n 109 | """ 110 | 111 | check_header_line = True 112 | line_count = 0 113 | 114 | key_value_pairs = {} 115 | 116 | for gcode in gcode_list: 117 | lines = gcode.split('\n') 118 | line_count += len(lines) - 1 119 | 120 | if check_header_line: 121 | for line in lines: 122 | if line.startswith(";Generated with Cura_SteamEngine"): # header ends 123 | check_header_line = False 124 | break 125 | 126 | if line.startswith(";") and ':' in line: 127 | line = line[1:].strip() 128 | key, value = line.split(":", 1) 129 | value = value.strip() 130 | 131 | key_value_pairs[key] = value 132 | 133 | gcode_info = GCodeInfo() 134 | if "FLAVOR" in key_value_pairs: 135 | gcode_info.flavour = key_value_pairs["FLAVOR"] 136 | if "MINX" in key_value_pairs: 137 | gcode_info.bbox = AxisAlignedBox( 138 | Vector(float(key_value_pairs["MINX"]), float(key_value_pairs["MINY"]), float(key_value_pairs["MINZ"])), 139 | Vector(float(key_value_pairs["MAXX"]), float(key_value_pairs["MAXY"]), float(key_value_pairs["MAXZ"])), 140 | ) 141 | gcode_info.line_count = line_count 142 | 143 | return gcode_info 144 | 145 | def processGCodeList(self, stream, gcode_list: List[str]) -> None: 146 | self.__detectHeaderVersion() 147 | 148 | if self._header_version == 1: 149 | self._processGCodeListV1(stream, gcode_list) 150 | elif self._header_version == 0: 151 | self._processGCodeListLegacy(stream, gcode_list) 152 | else: 153 | # Unsupported machine header, just use original 154 | self._processGCodeListTransparent(stream, gcode_list) 155 | 156 | def _processGCodeListV1(self, stream, gcode_list: List[str]) -> None: 157 | try: 158 | gcode_info = self.__parseOriginalGCode(gcode_list) 159 | except KeyError: 160 | gcode_info = None 161 | 162 | print_info = CuraApplication.getInstance().getPrintInformation() 163 | global_stack = CuraApplication.getInstance().getGlobalContainerStack() 164 | scene = CuraApplication.getInstance().getController().getScene() 165 | 166 | machine_name = global_stack.getProperty("machine_name", "value") 167 | 168 | # convert Duration to int 169 | estimated_time = int(print_info.currentPrintTime) 170 | 171 | headers = [ 172 | ";Header Start", 173 | ";Version:1", 174 | ";Slicer:CuraEngine", 175 | ";Printer:{}".format(machine_name), 176 | ";Estimated Print Time:{}".format(estimated_time), 177 | ";Lines:{}".format(gcode_info.line_count if gcode_info else 0), 178 | ";Extruder Mode:{}".format(self._extruder_mode), 179 | ] 180 | 181 | for extruder in global_stack.extruderList: 182 | nozzle_size = extruder.getProperty("machine_nozzle_size", "value") 183 | 184 | material = extruder.material 185 | temperature = extruder.getProperty("material_print_temperature", "value") 186 | 187 | retraction_amount = extruder.getProperty("retraction_amount", "value") 188 | switch_retraction_amount = extruder.getProperty("switch_extruder_retraction_amount", "value") 189 | 190 | headers.append(";Extruder {} Nozzle Size:{}".format(extruder.position, nozzle_size)) 191 | headers.append(";Extruder {} Material:{}".format(extruder.position, material.getName())) 192 | headers.append(";Extruder {} Print Temperature:{}".format(extruder.position, temperature)) 193 | headers.append(";Extruder {} Retraction Distance:{}".format(extruder.position, retraction_amount)) 194 | headers.append(";Extruder {} Switch Retraction Distance:{}".format(extruder.position, switch_retraction_amount)) 195 | 196 | bed_temperature = global_stack.getProperty("material_bed_temperature_layer_0", "value") 197 | headers.append(";Bed Temperature:{}".format(bed_temperature)) 198 | 199 | extruders_used = set() 200 | for node in DepthFirstIterator(scene.getRoot()): 201 | stack = node.callDecoration("getStack") 202 | if not stack: 203 | continue 204 | 205 | extruder_nr = stack.getProperty("extruder_nr", "value") 206 | extruders_used.add(int(extruder_nr)) 207 | 208 | headers.append(";Extruder(s) Used:{}".format(len(extruders_used))) 209 | 210 | if gcode_info and gcode_info.bbox.isValid(): 211 | bbox = gcode_info.bbox 212 | headers.extend([ 213 | ";Work Range - Min X:{}".format(bbox.minimum.x), 214 | ";Work Range - Min Y:{}".format(bbox.minimum.y), 215 | ";Work Range - Min Z:{}".format(bbox.minimum.z), 216 | ";Work Range - Max X:{}".format(bbox.maximum.x), 217 | ";Work Range - Max Y:{}".format(bbox.maximum.y), 218 | ";Work Range - Max Z:{}".format(bbox.maximum.z), 219 | ]) 220 | 221 | thumbnail = self.__generateThumbnail() 222 | headers.append(";Thumbnail:{}".format(thumbnail)) 223 | 224 | headers.append(";Header End") 225 | headers.append("") 226 | 227 | stream.write("\n".join(headers)) 228 | 229 | for gcode in gcode_list: 230 | stream.write(gcode) 231 | 232 | def __getExtruderValue(self, key) -> str: 233 | extruder_stack = ExtruderManager.getInstance().getActiveExtruderStack() 234 | 235 | type_ = extruder_stack.getProperty(key, "type") 236 | value_ = extruder_stack.getProperty(key, "value") 237 | 238 | if str(type_) == "float": 239 | value = "{:.4f}".format(value_).rstrip("0").rstrip(".") 240 | else: 241 | if str(type_) == "enum": 242 | options_ = extruder_stack.getProperty(key, "options") 243 | value = options_[str(value_)] 244 | else: 245 | value = str(value_) 246 | 247 | return value 248 | 249 | def _processGCodeListLegacy(self, stream, gcode_list: List[str]) -> None: 250 | try: 251 | gcode_info = self.__parseOriginalGCode(gcode_list) 252 | except KeyError: 253 | gcode_info = None 254 | 255 | print_info = CuraApplication.getInstance().getPrintInformation() 256 | global_stack = CuraApplication.getInstance().getGlobalContainerStack() 257 | 258 | machine_name = global_stack.getProperty("machine_name", "value") 259 | 260 | # convert Duration to int 261 | estimated_time = int(print_info.currentPrintTime) 262 | 263 | print_temp = float(self.__getExtruderValue("material_print_temperature")) 264 | bed_temp = float(self.__getExtruderValue("material_bed_temperature")) or 0. 265 | print_speed = float(self.__getExtruderValue("speed_infill")) 266 | 267 | headers = [ 268 | ";Header Start", 269 | 270 | # legacy keys 271 | ";header_type: 3dp", 272 | ";file_total_lines: {}".format(gcode_info.line_count if gcode_info else 0), 273 | ";estimated_time(s): {:.02f}".format(estimated_time), 274 | ";nozzle_temperature(°C): {:.0f}".format(print_temp), 275 | ";build_plate_temperature(°C): {:.0f}".format(bed_temp), 276 | ";work_speed(mm/minute): {:.0f}".format(print_speed), 277 | 278 | # keys for Version 1 279 | # ";Version:0", 280 | # ";Slicer:CuraEngine", 281 | ";Printer:{}".format(machine_name), 282 | # ";Estimated Print Time:{}".format(estimated_time), 283 | # ";Lines:{}".format(gcode_info.line_count if gcode_info else 0), 284 | # ";Extruder Mode:{}".format(self._extruder_mode), 285 | ] 286 | 287 | for extruder in global_stack.extruderList: 288 | nozzle_size = extruder.getProperty("machine_nozzle_size", "value") 289 | 290 | material = extruder.material 291 | temperature = extruder.getProperty("material_print_temperature", "value") 292 | 293 | retraction_amount = extruder.getProperty("retraction_amount", "value") 294 | switch_retraction_amount = extruder.getProperty("switch_extruder_retraction_amount", "value") 295 | 296 | headers.append(";Extruder {} Nozzle Size:{}".format(extruder.position, nozzle_size)) 297 | headers.append(";Extruder {} Material:{}".format(extruder.position, material.getName())) 298 | headers.append(";Extruder {} Print Temperature:{}".format(extruder.position, temperature)) 299 | headers.append(";Extruder {} Retraction Distance:{}".format(extruder.position, retraction_amount)) 300 | headers.append(";Extruder {} Switch Retraction Distance:{}".format(extruder.position, switch_retraction_amount)) 301 | 302 | if gcode_info and gcode_info.bbox.isValid(): 303 | bbox = gcode_info.bbox 304 | headers.extend([ 305 | ";min_x(mm): {}".format(bbox.minimum.x), 306 | ";min_y(mm): {}".format(bbox.minimum.y), 307 | ";min_z(mm): {}".format(bbox.minimum.z), 308 | ";max_x(mm): {}".format(bbox.maximum.x), 309 | ";max_y(mm): {}".format(bbox.maximum.y), 310 | ";max_z(mm): {}".format(bbox.maximum.z), 311 | ]) 312 | 313 | thumbnail = self.__generateThumbnail() 314 | headers.append(";thumbnail: {}".format(thumbnail)) 315 | 316 | headers.append(";Header End") 317 | headers.append("") 318 | 319 | stream.write("\n".join(headers)) 320 | 321 | for gcode in gcode_list: 322 | stream.write(gcode) 323 | 324 | def _processGCodeListTransparent(self, stream, gcode_list: List[str]) -> None: 325 | for gcode in gcode_list: 326 | stream.write(gcode) 327 | -------------------------------------------------------------------------------- /gcode_writer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapmaker/SnapmakerCuraPlugin/717cd07ec4a18d6d4fb345e1f328a091f1dac4e3/gcode_writer/__init__.py -------------------------------------------------------------------------------- /network_plugin/DiscoverSocket.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | from PyQt6.QtCore import QTimer 4 | from PyQt6.QtNetwork import QUdpSocket, QAbstractSocket, QHostAddress, QNetworkAddressEntry 5 | 6 | from UM.Platform import Platform 7 | from UM.Signal import signalemitter, Signal 8 | 9 | 10 | # Hard-coded discover port, all Snapmaker printer will be listen on 20054 11 | DISCOVER_PORT = 20054 12 | 13 | 14 | @signalemitter 15 | class DiscoverSocket: 16 | dataReady = Signal() 17 | 18 | def __init__(self, address_entry: QNetworkAddressEntry) -> None: 19 | self._address_entry = address_entry 20 | self._broadcast_address = address_entry.broadcast() 21 | 22 | self._socket = None # internal socket 23 | 24 | self._collect_timer = QTimer() 25 | self._collect_timer.setInterval(200) 26 | self._collect_timer.setSingleShot(True) 27 | self._collect_timer.timeout.connect(self.__collect) 28 | 29 | @property 30 | def address(self) -> QHostAddress: 31 | return self._address_entry.ip() 32 | 33 | def bind(self) -> bool: 34 | sock = QUdpSocket() 35 | 36 | bind_result = sock.bind(self._address_entry.ip(), mode=QAbstractSocket.BindFlag.DontShareAddress | 37 | QAbstractSocket.BindFlag.ReuseAddressHint) 38 | if not bind_result: 39 | return False 40 | 41 | if Platform.isWindows(): 42 | # On Windows, QUdpSocket is unable to receive broadcast data, we use original socket instead 43 | sock = socket.socket( 44 | socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 45 | sock.settimeout(0.2) 46 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 47 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 48 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) 49 | self._socket = sock 50 | else: 51 | # On Unix, we use socket interface provided by Qt 6 52 | self._socket = sock 53 | sock.readyRead.connect(self.__read) 54 | 55 | return True 56 | 57 | def discover(self, message: bytes) -> None: 58 | if isinstance(self._socket, QUdpSocket): 59 | self._socket.writeDatagram( 60 | message, self._broadcast_address, DISCOVER_PORT) 61 | else: 62 | try: 63 | self._socket.sendto( 64 | message, (self._broadcast_address.toString(), DISCOVER_PORT)) 65 | self._collect_timer.start() 66 | except (OSError, socket.timeout): 67 | pass 68 | 69 | def abort(self) -> None: 70 | if not self._socket: 71 | return 72 | 73 | if isinstance(self._socket, QUdpSocket): 74 | self._socket.abort() 75 | else: 76 | self._socket.close() 77 | 78 | self._socket = None 79 | 80 | def __read(self) -> None: 81 | while self._socket.hasPendingDatagrams(): 82 | data = self._socket.receiveDatagram() 83 | if data.isValid() and not data.senderAddress().isNull(): 84 | try: 85 | message = bytes(data.data()).decode("utf-8") 86 | self.dataReady.emit(message) 87 | except UnicodeDecodeError: 88 | pass 89 | 90 | def __collect(self) -> None: 91 | # the socket has abort and discover is cancelled 92 | if not self._socket: 93 | return 94 | 95 | if isinstance(self._socket, QUdpSocket): 96 | return 97 | 98 | while True: 99 | try: 100 | msg, _ = self._socket.recvfrom(128) 101 | except (TimeoutError, ConnectionError, socket.timeout): 102 | # normal timeout, or ConnectionError (including ConnectionAbortedError, ConnectionRefusedError, 103 | # ConnectionResetError) errors raise by the peer 104 | break 105 | 106 | try: 107 | message = msg.decode("utf-8") 108 | self.dataReady.emit(message) 109 | except UnicodeDecodeError: 110 | pass 111 | -------------------------------------------------------------------------------- /network_plugin/HTTPNetworkedPrinterOutputDevice.py: -------------------------------------------------------------------------------- 1 | import json 2 | import time 3 | from io import StringIO 4 | from typing import TYPE_CHECKING, Dict, List, Optional 5 | 6 | from PyQt6.QtCore import QTimer 7 | from PyQt6.QtNetwork import ( 8 | QHttpPart, 9 | QNetworkReply, 10 | QNetworkRequest, 11 | QNetworkAccessManager, 12 | ) 13 | from UM.Application import Application 14 | from UM.Logger import Logger 15 | from UM.Message import Message 16 | 17 | from cura.PrinterOutput.NetworkedPrinterOutputDevice import \ 18 | NetworkedPrinterOutputDevice, AuthState 19 | from cura.PrinterOutput.PrinterOutputDevice import ConnectionState 20 | from .HTTPTokenManager import HTTPTokenManager 21 | 22 | if TYPE_CHECKING: 23 | from UM.FileHandler.FileHandler import FileHandler 24 | from UM.Scene.SceneNode import SceneNode 25 | 26 | 27 | class HTTPNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice): 28 | """Snapmaker 2.0 printer control over HTTP. 29 | 30 | 1. Connect 31 | 2. Authenticate 32 | 3. Send G-code file 33 | 4. Disconnect 34 | """ 35 | 36 | def __init__(self, device_id: str, address: str, properties: Dict[str, str]) -> None: 37 | super().__init__(device_id, address, properties) 38 | 39 | self._setInterfaceElements() 40 | 41 | self._api_prefix = ":8080/api/v1" 42 | 43 | self._token = "" # API token 44 | self._stream = StringIO() # data stream of file 45 | 46 | self.authenticationStateChanged.connect(self._onAuthenticationStateChanged) 47 | self.connectionStateChanged.connect(self._onConnectionStateChanged) 48 | 49 | # write done, cleanup 50 | self.writeFinished.connect(self.__onWriteFinished) 51 | 52 | self._initToken() 53 | 54 | self._progress = PrintJobUploadProgressMessage(self) 55 | self._need_auth = PrintJobNeedAuthMessage(self) 56 | 57 | def _setInterfaceElements(self) -> None: 58 | self.setPriority(2) 59 | self.setShortDescription("Send to {}".format(self._address)) 60 | self.setDescription("Send to {}".format(self.getId())) 61 | self.setConnectionText("Connected to {}".format(self.getId())) 62 | 63 | def _initToken(self) -> None: 64 | saved_token = HTTPTokenManager.getInstance().getToken(self.getId()) 65 | if saved_token: 66 | self._token = saved_token 67 | Logger.debug("Use saved token for device: {}".format(self.getId())) 68 | 69 | def _onConnectionStateChanged(self, id) -> None: 70 | if self.connectionState == ConnectionState.Connected: 71 | if self.authenticationState != AuthState.Authenticated: 72 | return 73 | 74 | # once connected, we send file right away 75 | if not self._progress.visible: 76 | self._progress.show() 77 | 78 | self._upload() 79 | 80 | def _onAuthenticationStateChanged(self) -> None: 81 | if self.authenticationState == AuthState.Authenticated: 82 | self._need_auth.hide() 83 | elif self.authenticationState == AuthState.AuthenticationRequested: 84 | self._need_auth.show() 85 | elif self.authenticationState == AuthState.AuthenticationDenied: 86 | self._token = "" 87 | self._need_auth.hide() 88 | 89 | def setDeviceStatus(self, status: str): 90 | """Set Device Status 91 | 92 | IDLE, RUNNING, PAUSED, STOPPED 93 | """ 94 | if status == "IDLE": 95 | if self.connectionState != ConnectionState.Connected: 96 | self.setConnectionState(ConnectionState.Connected) 97 | elif status in ("RUNNING", "PAUSED", "STOPPED"): 98 | if self.connectionState != ConnectionState.Busy: 99 | self.setConnectionState(ConnectionState.Connected) 100 | 101 | def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, 102 | limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, 103 | filter_by_machine: bool = False, **kwargs) -> None: 104 | """Custom request in subclass.""" 105 | raise NotImplementedError 106 | 107 | def _writeFileJobFinished(self, job) -> None: 108 | # connect to remote 109 | self.connect() 110 | 111 | def __onWriteFinished(self): 112 | # disconnect from remote 113 | self.disconnect() 114 | 115 | def _queryParams(self) -> List[QHttpPart]: 116 | return [ 117 | self._createFormPart("name=token", self._token.encode()), 118 | self._createFormPart("name=_", "{}".format(time.time()).encode()), 119 | ] 120 | 121 | def connect(self) -> None: 122 | # reset state 123 | self.setConnectionState(ConnectionState.Closed) 124 | self.setAuthenticationState(AuthState.NotAuthenticated) 125 | 126 | self.postFormWithParts("/connect", self._queryParams(), self._onRequestFinished) 127 | 128 | def disconnect(self) -> None: 129 | if self._token: 130 | self.postFormWithParts("/disconnect", self._queryParams(), self._onRequestFinished) 131 | 132 | def checkStatus(self): 133 | url = "/status?token={}&_={}".format(self._token, time.time()) 134 | self.get(url, self._onRequestFinished) 135 | 136 | def _upload(self): 137 | Logger.info("Start to upload G-code file to device {}".format(self.getId())) 138 | if not self._token: 139 | return 140 | 141 | print_info = Application.getInstance().getPrintInformation() 142 | job_name = print_info.jobName.strip() 143 | print_time = print_info.currentPrintTime 144 | material_name = "-".join(print_info.materialNames) 145 | 146 | self._filename = "{}_{}_{}.gcode".format( 147 | job_name, material_name, 148 | "{}h{}m{}s".format(print_time.days * 24 + print_time.hours, print_time.minutes, print_time.seconds)) 149 | 150 | parts = self._queryParams() 151 | parts.append( 152 | self._createFormPart( 153 | 'name=file; filename="{}"'.format(self._filename), 154 | self._stream.getvalue().encode())) 155 | self._stream.close() 156 | self.postFormWithParts("/upload", 157 | parts, 158 | on_finished=self._onRequestFinished, 159 | on_progress=self._onUploadProgress) 160 | 161 | def _jsonReply(self, reply: QNetworkReply): 162 | try: 163 | return json.loads(bytes(reply.readAll()).decode("utf-8")) 164 | except json.decoder.JSONDecodeError: 165 | Logger.warning("Received invalid JSON from snapmaker.") 166 | return {} 167 | 168 | def _onRequestFinished(self, reply: QNetworkReply) -> None: 169 | http_url = reply.url().toString() 170 | 171 | if reply.error() not in ( 172 | QNetworkReply.NetworkError.NoError, 173 | QNetworkReply.NetworkError.AuthenticationRequiredError, # 204 is No Content, not an error 174 | ): 175 | Logger.warning("Error %s from %s", reply.error(), http_url) 176 | self.setConnectionState(ConnectionState.Closed) 177 | Message(title="Error", 178 | text=reply.errorString(), 179 | lifetime=0, 180 | dismissable=True).show() 181 | return 182 | 183 | http_code = reply.attribute( 184 | QNetworkRequest.Attribute.HttpStatusCodeAttribute) 185 | Logger.info("Request: %s - %d", http_url, http_code) 186 | if not http_code: 187 | return 188 | 189 | http_method = reply.operation() 190 | if http_method == QNetworkAccessManager.Operation.GetOperation: 191 | # /api/v1/status 192 | if self._api_prefix + "/status" in http_url: 193 | if http_code == 200: # approved 194 | self.setAuthenticationState(AuthState.Authenticated) 195 | resp = self._jsonReply(reply) 196 | device_status = resp.get("status", "UNKNOWN") 197 | self.setDeviceStatus(device_status) 198 | elif http_code == 401: # denied 199 | self.setAuthenticationState(AuthState.AuthenticationDenied) 200 | elif http_code == 204: # wait for authentication on HMI 201 | self.setAuthenticationState(AuthState.AuthenticationRequested) 202 | else: 203 | self.setAuthenticationState(AuthState.NotAuthenticated) 204 | elif http_method == QNetworkAccessManager.Operation.PostOperation: 205 | # /api/v1/connect 206 | if self._api_prefix + "/connect" in http_url: 207 | if http_code == 200: 208 | # success, got a token to start heartbeat 209 | resp = self._jsonReply(reply) 210 | token = resp.get("token") 211 | if self._token != token: 212 | self._token = token 213 | 214 | # update token 215 | HTTPTokenManager.getInstance().setToken(self.getId(), self._token) 216 | 217 | # check status 218 | self.checkStatus() 219 | 220 | elif http_code == 403 and self._token: 221 | # expired, retry connect 222 | self._token = "" 223 | self.connect() 224 | else: 225 | # failed 226 | self.setConnectionState(ConnectionState.Closed) 227 | Message( 228 | title="Error", 229 | text= 230 | "Please check the touchscreen and try again (Err: {}).".format(http_code), 231 | lifetime=10, 232 | dismissable=True).show() 233 | 234 | # /api/v1/disconnect 235 | elif self._api_prefix + "/disconnect" in http_url: 236 | self.setConnectionState(ConnectionState.Closed) 237 | 238 | # /api/v1/upload 239 | elif self._api_prefix + "/upload" in http_url: 240 | self._progress.hide() 241 | self.writeFinished.emit() 242 | 243 | Message(title="Sent to {}".format(self.getId()), 244 | text="Start print on the touchscreen: {}".format(self._filename), 245 | lifetime=60).show() 246 | 247 | def _onUploadProgress(self, bytes_sent: int, bytes_total: int) -> None: 248 | if bytes_total > 0: 249 | percentage = (bytes_sent / bytes_total) if bytes_total else 0 250 | self._progress.setProgress(percentage * 100) 251 | self.writeProgress.emit() 252 | 253 | 254 | class PrintJobNeedAuthMessage(Message): 255 | 256 | def __init__(self, device: HTTPNetworkedPrinterOutputDevice): 257 | super().__init__( 258 | title="Screen authorization needed", 259 | text="Please tap Yes on Snapmaker touchscreen to continue.", 260 | lifetime=0, 261 | dismissable=True, 262 | use_inactivity_timer=False) 263 | self._device = device 264 | self.setProgress(-1) 265 | self._gTimer = QTimer() 266 | self._gTimer.setInterval(1500) 267 | self._gTimer.timeout.connect(lambda: self._onCheck(None, None)) 268 | self.inactivityTimerStart.connect(self._startTimer) 269 | self.inactivityTimerStop.connect(self._stopTimer) 270 | 271 | def _startTimer(self): 272 | if self._gTimer and not self._gTimer.isActive(): 273 | self._gTimer.start() 274 | 275 | def _stopTimer(self): 276 | if self._gTimer and self._gTimer.isActive(): 277 | self._gTimer.stop() 278 | 279 | def _onCheck(self, *args, **kwargs): 280 | self._device.checkStatus() 281 | 282 | 283 | class PrintJobUploadProgressMessage(Message): 284 | 285 | def __init__(self, device: HTTPNetworkedPrinterOutputDevice): 286 | super().__init__(title="Sending to {}".format(device.getId()), 287 | progress=-1, 288 | lifetime=0, 289 | dismissable=False, 290 | use_inactivity_timer=False) 291 | self._device = device 292 | self._timer = QTimer() 293 | self._timer.setInterval(3 * 1000) 294 | self._timer.timeout.connect(lambda: self._heartbeat()) 295 | self.inactivityTimerStart.connect(self._start) 296 | self.inactivityTimerStop.connect(self._stop) 297 | 298 | def show(self): 299 | self.setProgress(0) 300 | super().show() 301 | 302 | def update(self, percentage: int): 303 | if not self._visible: 304 | super().show() 305 | self.setProgress(percentage) 306 | 307 | def _heartbeat(self): 308 | self._device.checkStatus() 309 | 310 | def _start(self): 311 | if self._timer and not self._timer.isActive(): 312 | self._timer.start() 313 | 314 | def _stop(self): 315 | if self._timer and self._timer.isActive(): 316 | self._timer.stop() 317 | -------------------------------------------------------------------------------- /network_plugin/HTTPTokenManager.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | 3 | from UM.Application import Application 4 | from cura.OAuth2.Models import BaseModel 5 | from cura.OAuth2.KeyringAttribute import KeyringAttribute 6 | 7 | 8 | class HTTPTokenManager(BaseModel): 9 | """Manager for HTTP tokens.""" 10 | 11 | PREFERENCE_KEY_TOKEN = "SnapmakerPlugin/tokens" 12 | 13 | instance = None 14 | 15 | @classmethod 16 | def getInstance(cls) -> "HTTPTokenManager": 17 | if not cls.instance: 18 | cls.instance = HTTPTokenManager() 19 | cls.instance.loadTokens() 20 | 21 | return cls.instance 22 | 23 | def __init__(self) -> None: 24 | self._attributes = {} 25 | 26 | def loadTokens(self) -> None: 27 | preferences = Application.getInstance().getPreferences() 28 | # Remove the preference we used on earlier version (<= 0.9.0) 29 | preferences.removePreference(self.PREFERENCE_KEY_TOKEN) 30 | 31 | def getToken(self, key: str) -> Union[str, None]: 32 | attribute = getattr(self, key, None) # type: Union[KeyringAttribute, None] 33 | return attribute.__get__(self, type(self)) if attribute else None 34 | 35 | def setToken(self, key: str, token: str) -> None: 36 | attribute = getattr(self, key, None) # type: Union[KeyringAttribute, None] 37 | if not attribute: 38 | # Note that we use dynamic descriptors instead static 39 | attribute = KeyringAttribute() 40 | attribute.__set_name__(self, key) 41 | setattr(self, key, attribute) 42 | 43 | # It's a bit tricky to call __get__ and __set__ directly, cuz we 44 | # can not call descriptor by acccess instance.attribute. 45 | saved_token = attribute.__get__(self, type(self)) 46 | if saved_token != token: 47 | attribute.__set__(self, token) 48 | -------------------------------------------------------------------------------- /network_plugin/SACP.py: -------------------------------------------------------------------------------- 1 | """ 2 | TODO: SACP protocol is not well implemented, refactor this. 3 | """ 4 | import struct 5 | 6 | INT8 = 'B' 7 | INT16 = 'H' 8 | INT32 = 'I' 9 | SACP_VERSION = 0x01 10 | SACP_PACK_FORMAT = '<{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}'.format(INT8, INT8, INT16, INT8, INT8, INT8, 11 | INT8, INT8, INT16, INT8, INT8) 12 | SACP_PACKAGE = 60 * 1024 # 60 KiB 13 | 14 | 15 | def SACP_check_head(package_data, length): 16 | crc = 0 17 | poly = 0x07 18 | for i in range(length): 19 | for j in range(8): 20 | bit = ((package_data[i] & 0xff) >> (7 - j) & 0x01) == 1 21 | c07 = (crc >> 7 & 0x01) == 1 22 | crc = crc << 1 23 | if c07 ^ bit: 24 | crc ^= poly 25 | crc = crc & 0xff 26 | return crc 27 | 28 | 29 | def u16_check_data(package_data, length): 30 | check_num = 0 31 | if length > 0: 32 | for i in range(0, (length - 1), 2): 33 | check_num += (((package_data[i] & 0xff) << 8) | (package_data[i + 1] & 0xff)) 34 | check_num &= 0xffffffff 35 | if length % 2 != 0: 36 | check_num += package_data[length - 1] 37 | while check_num > 0xffff: 38 | check_num = ((check_num >> 16) & 0xffff) + (check_num & 0xffff) 39 | check_num = ~check_num 40 | return check_num & 0xffff 41 | 42 | 43 | class ReceiverException(Exception): 44 | def __init__(self, error_info): 45 | self.error_info = error_info 46 | 47 | 48 | class ReceiverData(object): 49 | def __init__(self, command_set, command_id, valid_data, sequence): 50 | self.command_set = command_set 51 | self.command_id = command_id 52 | self.valid_data = valid_data 53 | self.sequence = sequence 54 | 55 | 56 | def SACP_pack(receiver_id, sender_id, attribute, sequence, command_set, command_id, send_data): 57 | """ 58 | receiver_id : 接收者ID 59 | sender_id : 发送者ID 60 | attribute: 0 - 请求, 1 - 应答 61 | sequence : 包的标号 62 | command_set : command_set 63 | command_id : command_id 64 | data : 要发送的数据 65 | """ 66 | data_length = len(send_data) 67 | package_head = struct.pack(SACP_PACK_FORMAT, 68 | 0xAA, 69 | 0x55, 70 | data_length + 6 + 2, 71 | SACP_VERSION, 72 | receiver_id, 73 | 0, # 前6个字节的校验,暂时为0 74 | sender_id, 75 | attribute, 76 | sequence, 77 | command_set, 78 | command_id) 79 | package_head = bytearray(package_head) 80 | package_head[6] = SACP_check_head(package_head, 6) 81 | pack_array = package_head + send_data 82 | check_num = u16_check_data(pack_array[7:], data_length + 6) 83 | pack_array = pack_array + struct.pack(" None: 24 | super().__init__(device_id, address, properties) 25 | 26 | self._setInterfaceElements() 27 | 28 | self._stream = StringIO() 29 | self._data = "" 30 | self._data_md5 = "" 31 | 32 | self._socket = QTcpSocket() 33 | 34 | self.connectionStateChanged.connect(self.__onConnectionStateChanged) 35 | 36 | self.writeFinished.connect(self.__onWriteFinished) 37 | 38 | def _setInterfaceElements(self) -> None: 39 | self.setPriority(2) 40 | self.setShortDescription("Send to {}".format(self._address)) 41 | self.setDescription("Send to {}".format(self.getId())) 42 | self.setConnectionText("Connected to {}".format(self.getId())) 43 | 44 | def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, 45 | limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, 46 | filter_by_machine: bool = False, **kwargs) -> None: 47 | """Custom request in subclass.""" 48 | raise NotImplementedError 49 | 50 | def _writeFileJobFinished(self, job) -> None: 51 | self.connect() 52 | 53 | def connect(self) -> None: 54 | self.disconnect() 55 | 56 | self.setConnectionState(ConnectionState.Connecting) 57 | self._socket.connected.connect(self.__socketConnected) 58 | self._socket.readyRead.connect(self.__socketReadyRead) 59 | self._socket.connectToHost(self._address, 8888) 60 | 61 | Logger.info("Disconnected from output device.") 62 | 63 | def disconnect(self) -> None: 64 | if self._socket.state() == QTcpSocket.SocketState.ConnectedState: 65 | self._socket.connected.disconnect(self.__socketConnected) 66 | self._socket.readyRead.disconnect(self.__socketReadyRead) 67 | self._socket.close() 68 | 69 | def __socketConnected(self) -> None: 70 | if self._socket.state() == QTcpSocket.SocketState.ConnectedState: 71 | self.__sacpConnect() 72 | 73 | def __socketReadyRead(self) -> None: 74 | if self._socket.state() != QTcpSocket.SocketState.ConnectedState: 75 | Logger.debug("Socket not connected, abort read.") 76 | return 77 | 78 | while True: 79 | data = self._socket.read(4) 80 | if not data or len(data) < 4: 81 | break 82 | if data[0] != 0xAA and data[1] != 0x55: 83 | # discard this 4 bytes 84 | continue 85 | 86 | data_len = (data[2] | data[3] << 8) & 0xFFFF 87 | residue_data = self._socket.read(data_len + 3) 88 | data += residue_data 89 | receiver_data = SACP_unpack(data) 90 | 91 | if receiver_data.command_set == 0x01 and receiver_data.command_id == 0x05: 92 | token_length = receiver_data.valid_data[1] 93 | receiver_valid_data = SACP_validData( 94 | receiver_data.valid_data, " None: 124 | if self.connectionState == ConnectionState.Connected: 125 | # once connected, we send file right away 126 | self._sendFile() 127 | 128 | def __onWriteFinished(self): 129 | # disconnect from remote 130 | self.__sacpDisconnect() 131 | 132 | # disconnect socket 133 | self.disconnect() 134 | 135 | def _sendFile(self) -> None: 136 | self._prepareSendFile() 137 | 138 | def _sendFileFinished(self) -> None: 139 | self.writeFinished.emit() 140 | message = Message( 141 | title="Sent G-code file to {}".format(self.getId()), 142 | text="Please start print on the touchscreen.", 143 | lifetime=60, 144 | ) 145 | message.show() 146 | 147 | Logger.info("Send G-code file successfully") 148 | 149 | def _prepareSendFile(self) -> None: 150 | print_info = CuraApplication.getInstance().getPrintInformation() 151 | 152 | job_name = print_info.jobName.strip() 153 | print_time = print_info.currentPrintTime 154 | material_name = "-".join(print_info.materialNames) 155 | 156 | self._data = self._stream.getvalue() 157 | self._data_md5 = hashlib.md5(self._data.encode("utf-8")).hexdigest() 158 | package_count = int(len(self._data) / SACP_PACKAGE) + 1 159 | 160 | filename = "{}_{}_{}.gcode".format( 161 | job_name, 162 | material_name, 163 | "{}h{}m{}s".format( 164 | print_time.days * 24 + print_time.hours, 165 | print_time.minutes, 166 | print_time.seconds) 167 | ) 168 | 169 | # TODO: upload 170 | self.__sacpPrepareSendGcode( 171 | self._data, filename, self._data_md5, package_count) 172 | 173 | def __sacpString(self, s: str) -> bytes: 174 | s_utf = s.encode("utf-8") 175 | return struct.pack(" None: 178 | # device name, client name, token 179 | data = self.__sacpString( 180 | "Destop") + self.__sacpString("Cura") + self.__sacpString("") 181 | # struct.pack(" None: 193 | packet = SACP_pack(receiver_id=2, 194 | sender_id=0, 195 | attribute=0, 196 | sequence=1, 197 | command_set=0x01, 198 | command_id=0x06, 199 | send_data=b'') 200 | self._socket.write(packet) 201 | 202 | def __sacpPrepareSendGcode(self, data: str, gcode_name, file_md5, package_count) -> None: 203 | data = data.encode("utf-8") 204 | gcode_name = gcode_name.encode("utf-8") 205 | file_md5 = file_md5.encode("utf-8") 206 | 207 | gcode_name_length = len(gcode_name) 208 | file_md5_length = len(file_md5) 209 | data_format = "H{0}sIHH{1}s".format(gcode_name_length, file_md5_length) 210 | packet_data = struct.pack( 211 | '<{0}'.format(data_format), 212 | gcode_name_length, 213 | gcode_name, 214 | len(data), 215 | package_count, 216 | file_md5_length, 217 | file_md5, 218 | ) 219 | packet = SACP_pack(receiver_id=2, 220 | sender_id=0, 221 | attribute=0, 222 | sequence=1, 223 | command_set=0xb0, 224 | command_id=0x00, 225 | send_data=packet_data) 226 | self._socket.write(packet) 227 | 228 | def __sacpSendGcodoFile(self, file_md5, data: str, index, sequence): 229 | gcode_data_length = len(data.encode('utf-8')) 230 | file_md5_length = len(file_md5.encode('utf-8')) 231 | data_format = "BH{0}sHH{1}s".format(file_md5_length, gcode_data_length) 232 | data = struct.pack('<{0}'.format(data_format), 233 | 0, 234 | file_md5_length, 235 | file_md5.encode('utf-8'), 236 | index, 237 | gcode_data_length, 238 | data.encode('utf-8'), 239 | ) 240 | packet = SACP_pack(receiver_id=2, 241 | sender_id=0, 242 | attribute=1, 243 | sequence=sequence, 244 | command_set=0xb0, 245 | command_id=0x01, 246 | send_data=data) 247 | self._socket.write(packet) 248 | -------------------------------------------------------------------------------- /network_plugin/Snapamker2OutputDevice.py: -------------------------------------------------------------------------------- 1 | from io import StringIO 2 | from typing import TYPE_CHECKING, Dict, List, Optional 3 | 4 | from UM.FileHandler.WriteFileJob import WriteFileJob 5 | from UM.Message import Message 6 | from UM.Mesh.MeshWriter import MeshWriter 7 | 8 | from cura.PrinterOutput.PrinterOutputDevice import ConnectionState 9 | from ..gcode_writer.SnapmakerGCodeWriter import SnapmakerGCodeWriter 10 | from .HTTPNetworkedPrinterOutputDevice import HTTPNetworkedPrinterOutputDevice 11 | 12 | if TYPE_CHECKING: 13 | from UM.FileHandler.FileHandler import FileHandler 14 | from UM.Scene.SceneNode import SceneNode 15 | 16 | 17 | class Snapmaker2OutputDevice(HTTPNetworkedPrinterOutputDevice): 18 | 19 | def __init__(self, device_id: str, address: str, properties: Dict[str, str]) -> None: 20 | super().__init__(device_id, address, properties) 21 | 22 | self._setInterfaceElements() 23 | 24 | def _setInterfaceElements(self) -> None: 25 | self.setPriority(2) 26 | self.setShortDescription("Send to {}".format(self._address)) 27 | self.setDescription("Send to {}".format(self.getId())) 28 | self.setConnectionText("Connected to {}".format(self.getId())) 29 | 30 | def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, 31 | limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, 32 | filter_by_machine: bool = False, **kwargs) -> None: 33 | if self.connectionState == ConnectionState.Busy: 34 | Message(title="Unable to send request", 35 | text="Machine {} is busy".format(self.getId())).show() 36 | return 37 | 38 | self.writeStarted.emit(self) 39 | 40 | message = Message( 41 | text="Preparing to upload", 42 | progress=-1, 43 | lifetime=0, 44 | dismissable=False, 45 | use_inactivity_timer=False, 46 | ) 47 | message.show() 48 | 49 | self._stream = StringIO() # create a new io stream 50 | 51 | writer = SnapmakerGCodeWriter() 52 | 53 | job = WriteFileJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode) 54 | job.finished.connect(self._writeFileJobFinished) 55 | job.setMessage(message) 56 | job.start() 57 | -------------------------------------------------------------------------------- /network_plugin/SnapmakerArtisanOutputDevice.py: -------------------------------------------------------------------------------- 1 | from io import StringIO 2 | from typing import TYPE_CHECKING, List, Optional 3 | 4 | from cura.PrinterOutput.PrinterOutputDevice import ConnectionState 5 | from UM.FileHandler.WriteFileJob import WriteFileJob 6 | from UM.Mesh.MeshWriter import MeshWriter 7 | from UM.Message import Message 8 | 9 | from ..gcode_writer.SnapmakerGCodeWriter import SnapmakerGCodeWriter 10 | from .SACPNetworkedPrinterOutputDevice import SACPNetworkedPrinterOutputDevice 11 | 12 | if TYPE_CHECKING: 13 | from UM.FileHandler.FileHandler import FileHandler 14 | from UM.Scene.SceneNode import SceneNode 15 | 16 | 17 | class SnapmakerArtisanOutputDevice(SACPNetworkedPrinterOutputDevice): 18 | 19 | def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, 20 | limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, 21 | filter_by_machine: bool = False, **kwargs) -> None: 22 | if self.connectionState == ConnectionState.Busy: 23 | Message(title="Unable to send request", 24 | text="Machine {} is busy".format(self.getId())).show() 25 | return 26 | 27 | self.writeStarted.emit(self) 28 | 29 | message = Message( 30 | text="Preparing to upload", 31 | progress=-1, 32 | lifetime=0, 33 | dismissable=False, 34 | use_inactivity_timer=False, 35 | ) 36 | message.show() 37 | 38 | self._stream = StringIO() # create a new io stream 39 | 40 | writer = SnapmakerGCodeWriter() 41 | 42 | job = WriteFileJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode) 43 | job.finished.connect(self._writeFileJobFinished) 44 | job.setMessage(message) 45 | job.start() 46 | -------------------------------------------------------------------------------- /network_plugin/SnapmakerJ1OutputDevice.py: -------------------------------------------------------------------------------- 1 | from io import StringIO 2 | from typing import TYPE_CHECKING, List, Optional 3 | 4 | from cura.PrinterOutput.PrinterOutputDevice import ConnectionState 5 | from UM.FileHandler.WriteFileJob import WriteFileJob 6 | from UM.Mesh.MeshWriter import MeshWriter 7 | from UM.Message import Message 8 | 9 | from ..gcode_writer.SnapmakerGCodeWriter import SnapmakerGCodeWriter 10 | from .SACPNetworkedPrinterOutputDevice import SACPNetworkedPrinterOutputDevice 11 | 12 | if TYPE_CHECKING: 13 | from UM.FileHandler.FileHandler import FileHandler 14 | from UM.Scene.SceneNode import SceneNode 15 | 16 | 17 | class SnapmakerJ1OutputDevice(SACPNetworkedPrinterOutputDevice): 18 | 19 | def requestWrite(self, nodes: List["SceneNode"], file_name: Optional[str] = None, 20 | limit_mimetypes: bool = False, file_handler: Optional["FileHandler"] = None, 21 | filter_by_machine: bool = False, **kwargs) -> None: 22 | if self.connectionState == ConnectionState.Busy: 23 | Message(title="Unable to send request", 24 | text="Machine {} is busy".format(self.getId())).show() 25 | return 26 | 27 | self.writeStarted.emit(self) 28 | 29 | message = Message( 30 | text="Preparing to upload", 31 | progress=-1, 32 | lifetime=0, 33 | dismissable=False, 34 | use_inactivity_timer=False, 35 | ) 36 | message.show() 37 | 38 | self._stream = StringIO() # create a new io stream 39 | 40 | writer = SnapmakerGCodeWriter() 41 | writer.setExtruderMode("IDEX Full Control") # only support IDEX Full Control in Cura 42 | 43 | job = WriteFileJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode) 44 | job.finished.connect(self._writeFileJobFinished) 45 | job.setMessage(message) 46 | job.start() 47 | -------------------------------------------------------------------------------- /network_plugin/SnapmakerOutputDevicePlugin.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from PyQt6.QtCore import QTimer 4 | from PyQt6.QtNetwork import QNetworkInterface, QAbstractSocket 5 | 6 | from UM.Application import Application 7 | from UM.Logger import Logger 8 | from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin 9 | 10 | from .DiscoverSocket import DiscoverSocket 11 | from .SnapmakerJ1OutputDevice import SnapmakerJ1OutputDevice 12 | from .SnapmakerArtisanOutputDevice import SnapmakerArtisanOutputDevice 13 | from .Snapamker2OutputDevice import Snapmaker2OutputDevice 14 | from .HTTPTokenManager import HTTPTokenManager 15 | from ..config import ( 16 | is_machine_discover_supported, 17 | SNAPMAKER_J1, 18 | SNAPMAKER_ARTISAN, 19 | SNAPMAKER_2_A150, 20 | SNAPMAKER_2_A250, 21 | SNAPMAKER_2_A350, 22 | SNAPMAKER_2_A150_DUAL_EXTRUDER, 23 | SNAPMAKER_2_A250_DUAL_EXTRUDER, 24 | SNAPMAKER_2_A350_DUAL_EXTRUDER, 25 | SNAPMAKER_DISCOVER_MACHINES, 26 | ) 27 | 28 | 29 | class SnapmakerOutputDevicePlugin(OutputDevicePlugin): 30 | """Output device plugin that detects networked Snapmaker printers. 31 | 32 | Start discovering only when active machine is a Snapmaker machine. 33 | """ 34 | 35 | def __init__(self) -> None: 36 | super().__init__() 37 | 38 | self._discover_timer = QTimer() 39 | self._discover_timer.setInterval(16000) # 16 seconds 40 | self._discover_timer.setSingleShot(False) 41 | self._discover_timer.timeout.connect(self.__discover) 42 | 43 | self._discover_sockets = [] # type: List[DiscoverSocket] 44 | 45 | self._active_machine_name = "" 46 | self._active_machine = None 47 | 48 | self._http_token_manager = HTTPTokenManager.getInstance() 49 | 50 | Application.getInstance().globalContainerStackChanged.connect( 51 | self._onGlobalContainerStackChanged) 52 | Application.getInstance().applicationShuttingDown.connect(self.stop) 53 | 54 | def __prepare(self) -> None: 55 | self._discover_sockets = [] 56 | for interface in QNetworkInterface.allInterfaces(): 57 | for address_entry in interface.addressEntries(): 58 | address = address_entry.ip() 59 | if address.isLoopback(): 60 | continue 61 | if address.protocol() != QAbstractSocket.NetworkLayerProtocol.IPv4Protocol: 62 | continue 63 | 64 | sock = DiscoverSocket(address_entry) 65 | if sock.bind(): 66 | Logger.info( 67 | "Discovering printers on network interface: %s", address.toString()) 68 | sock.dataReady.connect(self.__onData) 69 | self._discover_sockets.append(sock) 70 | 71 | def __discover(self) -> None: 72 | if not self._discover_sockets: 73 | self.__prepare() 74 | 75 | for sock in self._discover_sockets: 76 | Logger.info( 77 | "Discovering networked printer... (interface: %s)", sock.address.toString()) 78 | sock.discover(b"discover") 79 | 80 | # TODO: remove output devices that not reply message for a period of time 81 | 82 | def __onData(self, msg: str) -> None: 83 | """Parse message. 84 | 85 | e.g. Snapmaker J1@172.18.0.2|model:Snapmaker J1|status:IDLE 86 | """ 87 | # Logger.debug("Discovered printer: %s", msg) 88 | 89 | parts = msg.split("|") 90 | if len(parts) < 1 or "@" not in parts[0]: 91 | # invalid message 92 | return 93 | 94 | device_id = parts[0] 95 | name, address = device_id.rsplit("@", 1) 96 | 97 | properties = {} 98 | for part in parts[1:]: 99 | if ":" not in part: 100 | continue 101 | 102 | key, value = part.split(":") 103 | properties[key] = value 104 | 105 | # only accept current active machine 106 | model = properties.get("model", "") 107 | if self._active_machine and model != self._active_machine['model']: 108 | return 109 | 110 | device = self.getOutputDeviceManager().getOutputDevice(device_id) 111 | if not device: 112 | Logger.info("Discovered %s printer: %s@%s", 113 | self._active_machine_name, name, address) 114 | 115 | if model == SNAPMAKER_J1['name']: 116 | # J1 117 | device = SnapmakerJ1OutputDevice(device_id, address, properties) 118 | self.getOutputDeviceManager().addOutputDevice(device) 119 | elif model == SNAPMAKER_ARTISAN['name']: 120 | # Artisan 121 | device = SnapmakerArtisanOutputDevice(device_id, address, properties) 122 | self.getOutputDeviceManager().addOutputDevice(device) 123 | elif model in [SNAPMAKER_2_A150['model'], 124 | SNAPMAKER_2_A250['model'], 125 | SNAPMAKER_2_A350['model'], 126 | SNAPMAKER_2_A150_DUAL_EXTRUDER['model'], 127 | SNAPMAKER_2_A250_DUAL_EXTRUDER['model'], 128 | SNAPMAKER_2_A350_DUAL_EXTRUDER['model'], ]: 129 | # Snapmaker 2.0 Dual Extruder 130 | device = Snapmaker2OutputDevice(device_id, address, properties) 131 | self.getOutputDeviceManager().addOutputDevice(device) 132 | 133 | def start(self) -> None: 134 | if not is_machine_discover_supported(self._active_machine_name): 135 | return 136 | 137 | if not self._discover_timer.isActive(): 138 | self._discover_timer.start() 139 | Logger.info("Snapmaker printer discovering started.") 140 | 141 | def stop(self) -> None: 142 | if self._discover_timer.isActive(): 143 | self._discover_timer.stop() 144 | 145 | for sock in self._discover_sockets: 146 | sock.abort() 147 | 148 | # clear all discover sockets 149 | self._discover_sockets.clear() 150 | 151 | Logger.info("Snapmaker printer discovering stopped.") 152 | 153 | def startDiscovery(self) -> None: 154 | self.__discover() 155 | 156 | def _updateActiveMachine(self) -> None: 157 | # check for current global container 158 | global_stack = Application.getInstance().getGlobalContainerStack() 159 | if global_stack is None: 160 | # First time launch, global stack could be None 161 | return 162 | 163 | machine_name = global_stack.getProperty("machine_name", "value") 164 | self._active_machine_name = machine_name 165 | 166 | for machine in SNAPMAKER_DISCOVER_MACHINES: 167 | if machine['name'] == machine_name: 168 | self._active_machine = machine 169 | break 170 | 171 | def _onGlobalContainerStackChanged(self) -> None: 172 | self._updateActiveMachine() 173 | 174 | # Start timer when active machine is supported 175 | if is_machine_discover_supported(self._active_machine_name): 176 | self.start() 177 | else: 178 | self.stop() 179 | -------------------------------------------------------------------------------- /network_plugin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapmaker/SnapmakerCuraPlugin/717cd07ec4a18d6d4fb345e1f328a091f1dac4e3/network_plugin/__init__.py -------------------------------------------------------------------------------- /plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker Plugin", 3 | "author": "Snapmaker", 4 | "version": "0.9.4", 5 | "description": "Provides support for Snapmaker Machines.", 6 | "api": 8, 7 | "supported_sdk_versions": ["8.0.0", "8.1.0", "8.2.0", "8.3.0", "8.4.0", "8.5.0"], 8 | "i18n-catalog": "cura" 9 | } 10 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_abs_black.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | ABS 7 | Black 8 | 9 | 10 | 1 11 | 52a5c200-6c94-412f-a655-6cac096999b3 12 | #0000000 13 | Snapmaker ABS Black material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 255 22 | 100 23 | 210 24 | 28 25 | 1.0 26 | 30.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_breakaway_white.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | Breakaway 7 | White 8 | 9 | 10 | 1 11 | 81db14df-2995-45f7-af38-64d291687345 12 | #FFFFFF 13 | Snapmaker Breakaway support material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 225.0 22 | 65.0 23 | 150.0 24 | 0 25 | 100 26 | 28 27 | 6.0 28 | 20.0 29 | 100.0 30 | 31 | 32 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_petg_white.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | PETG 7 | White 8 | 9 | 10 | 1 11 | 8e488b05-b845-411c-af05-09fcbbf2acda 12 | #ffffff 13 | Snapmaker PETG White material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 240 22 | 65 23 | 210 24 | 28 25 | 1.0 26 | 40.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_pla_white.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | PLA 7 | White 8 | 9 | 10 | 1 11 | 5328d6fb-d845-4347-ab13-de90770bef00 12 | #FFFFFF 13 | Snapmaker PLA White material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 215 22 | 65 23 | 180 24 | 28 25 | 1.0 26 | 30.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_pva_white.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | PVA 7 | White 8 | 9 | 10 | 1 11 | 5e2d8b77-5c73-45ce-8f08-62172a8f0a48 12 | #FFFFFF 13 | Snapmaker Breakaway support material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 205 22 | 65 23 | 150 24 | 28 25 | 1.0 26 | 30.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/materials/snapmaker_tpu_white.xml.fdm_material: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Snapmaker 6 | TPU 7 | White 8 | 9 | 10 | 1 11 | e0be1316-689d-4aad-958f-c5f0bfa1e01b 12 | #ffffff 13 | Snapmaker PETG White material. 14 | 15 | 16 | 17 | 1.24 18 | 1.75 19 | 20 | 21 | 220 22 | 65 23 | 150 24 | 28 25 | 1 26 | 30.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/definitions/snapmaker_2_a150_dual_extruder.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker 2 A150 Dual Extruder", 3 | "version": 2, 4 | "inherits": "snapmaker_2_dual_extruder", 5 | "metadata": { 6 | "visible": true 7 | }, 8 | "overrides": { 9 | "machine_name": { 10 | "default_value": "Snapmaker 2.0 A150 Dual Extruder" 11 | }, 12 | "machine_width": { 13 | "default_value": 145 14 | }, 15 | "machine_depth": { 16 | "default_value": 145 17 | }, 18 | "machine_height": { 19 | "default_value": 110 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/definitions/snapmaker_2_a250_dual_extruder.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker 2 A250 Dual Extruder", 3 | "version": 2, 4 | "inherits": "snapmaker_2_dual_extruder", 5 | "metadata": { 6 | "visible": true 7 | }, 8 | "overrides": { 9 | "machine_name": { 10 | "default_value": "Snapmaker 2.0 A250 Dual Extruder" 11 | }, 12 | "machine_width": { 13 | "default_value": 220 14 | }, 15 | "machine_depth": { 16 | "default_value": 235 17 | }, 18 | "machine_height": { 19 | "default_value": 210 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/definitions/snapmaker_2_a350_dual_extruder.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker 2 A350 Dual Extruder", 3 | "version": 2, 4 | "inherits": "snapmaker_2_dual_extruder", 5 | "metadata": { 6 | "visible": true 7 | }, 8 | "overrides": { 9 | "machine_name": { 10 | "default_value": "Snapmaker 2.0 A350 Dual Extruder" 11 | }, 12 | "machine_width": { 13 | "default_value": 310 14 | }, 15 | "machine_depth": { 16 | "default_value": 330 17 | }, 18 | "machine_height": { 19 | "default_value": 290 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/definitions/snapmaker_2_dual_extruder.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker 2 Base Dual Extruder", 3 | "version": 2, 4 | "inherits": "fdmprinter", 5 | "metadata": { 6 | "manufacturer": "Snapmaker", 7 | "author": "Snapmaker", 8 | "file_formats": "text/x-snapmaker-gcode;text/x-gcode", 9 | "machine_extruder_trains": { 10 | "0": "snapmaker_2_dual_extruder_0", 11 | "1": "snapmaker_2_dual_extruder_1" 12 | }, 13 | "has_machine_quality": true, 14 | "has_materials": true, 15 | "quality_definition": "snapmaker_2_dual_extruder", 16 | "preferred_quality_type": "normal", 17 | "preferred_material": "generic_pla", 18 | "exclude_materials": [], 19 | "visible": false 20 | }, 21 | "overrides": { 22 | "machine_heated_bed": { 23 | "default_value": true 24 | }, 25 | "machine_buildplate_type": { 26 | "default_value": "glass" 27 | }, 28 | "machine_extruder_count": { 29 | "default_value": 2 30 | }, 31 | "machine_use_extruder_offset_to_offset_coords": { 32 | "default_value": false 33 | }, 34 | "machine_start_gcode": { 35 | "default_value": ";--- Start G-code Begin ---\nM104 S{material_print_temperature_layer_0} ;Set Hotend Temperature\nM140 S{material_bed_temperature_layer_0} ;Set Bed Temperature\nG28 ;home\nG90 ;absolute positioning\nG1 X-10 Y-10 F3000 ;Move to corner \nG1 Z0 F1800 ;Go to zero offset\nM109 S{material_print_temperature_layer_0} ;Wait for Hotend Temperature\nM190 S{material_bed_temperature_layer_0} ;Wait for Bed Temperature\nG92 E0 ;Zero set extruder position\nG1 E20 F200 ;Feed filament to clear nozzle\nG92 E0 ;Zero set extruder position\n;--- Start G-code End ---\n" 36 | }, 37 | "machine_end_gcode": { 38 | "default_value": ";--- End G-code Begin ---\nM104 S0 ;Extruder heater off\nM140 S0 ;Heated bed heater off\nG90 ;absolute positioning\nG92 E0 ;Retract the filament\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z{machine_height} E-1 F3000 ;move Z up a bit and retract filament even more\nG1 X0 F3000 ;move X to min endstops, so the head is out of the way\nG1 Y{machine_depth} F3000 ;so the head is out of the way and Plate is moved forward\n;--- End G-code End ---\n" 39 | }, 40 | "retraction_amount": { 41 | "default_value": 1.5, 42 | "maximum_value_warning": "2.0" 43 | }, 44 | "switch_extruder_retraction_amount": { 45 | "default_value": 16, 46 | "minimum_value_warning": "15", 47 | "maximum_value_warning": "20" 48 | }, 49 | "switch_extruder_retraction_speeds": { 50 | "default_value": 20 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/extruders/snapmaker_2_dual_extruder_0.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Left Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_2_base_dual_extruder", 10 | "position": "0" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 0 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 0 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/extruders/snapmaker_2_dual_extruder_1.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Right Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_2_base_dual_extruder", 10 | "position": "1" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 1 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 0 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_PLA_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Draft 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 35 27 | speed_print = 70 28 | speed_support = 70 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 35 31 | speed_travel = 84 32 | speed_travel_layer_0 = 60 33 | speed_wall = 35 34 | speed_wall_x = 70 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 30 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_PLA_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fast 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 30 26 | speed_prime_tower = 30 27 | speed_print = 60 28 | speed_support = 60 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 84 32 | speed_travel_layer_0 = 60 33 | speed_wall = 30 34 | speed_wall_x = 60 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_PLA_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fine 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 20 27 | speed_print = 40 28 | speed_support = 40 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 20 31 | speed_travel = 60 32 | speed_travel_layer_0 = 60 33 | speed_wall = 20 34 | speed_wall_x = 40 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_PLA_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Normal 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 25 27 | speed_print = 50 28 | speed_support = 50 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 25 31 | speed_travel = 60 32 | speed_travel_layer_0 = 60 33 | speed_wall = 25 34 | speed_wall_x = 50 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_global_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Draft 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = True 11 | weight = -2 12 | 13 | [values] 14 | acceleration_enabled = False 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 500 17 | acceleration_print = 1000 18 | acceleration_support_interface = 1000 19 | acceleration_topbottom = 1000 20 | acceleration_travel = 1000 21 | acceleration_travel_layer_0 = 500 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 40 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 40 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 3 37 | cool_min_speed = 40 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 12 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.24 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 130 51 | prime_tower_position_y = 130 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 25 65 | speed_prime_tower = 35 66 | speed_print = 70 67 | speed_slowdown_layers = 1 68 | speed_support = 70 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 35 71 | speed_travel = 84 72 | speed_travel_layer_0 = 60 73 | speed_wall = 35 74 | speed_wall_x = 70 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 3 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 2 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 30 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_global_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fast 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = True 11 | weight = -1 12 | 13 | [values] 14 | acceleration_enabled = False 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 500 17 | acceleration_print = 1000 18 | acceleration_support_interface = 1000 19 | acceleration_topbottom = 1000 20 | acceleration_travel = 1000 21 | acceleration_travel_layer_0 = 500 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 40 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 40 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 10 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.2 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 130 51 | prime_tower_position_y = 130 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 30 65 | speed_prime_tower = 30 66 | speed_print = 60 67 | speed_slowdown_layers = 1 68 | speed_support = 60 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 30 71 | speed_travel = 84 72 | speed_travel_layer_0 = 60 73 | speed_wall = 30 74 | speed_wall_x = 60 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_global_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fine 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = True 11 | weight = 1 12 | 13 | [values] 14 | acceleration_enabled = False 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 500 17 | acceleration_print = 1000 18 | acceleration_support_interface = 1000 19 | acceleration_topbottom = 1000 20 | acceleration_travel = 1000 21 | acceleration_travel_layer_0 = 500 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 6 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 40 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 40 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 18 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.12 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 130 51 | prime_tower_position_y = 130 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 25 65 | speed_prime_tower = 20 66 | speed_print = 40 67 | speed_slowdown_layers = 1 68 | speed_support = 40 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 20 71 | speed_travel = 60 72 | speed_travel_layer_0 = 60 73 | speed_wall = 20 74 | speed_wall_x = 40 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 6 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 4 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.6 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_2_dual_extruder/quality/snapmaker_2_dual_extruder/snapmaker_2_dual_extruder_global_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Normal 3 | version = 4 4 | definition = snapmaker_2_dual_extruder 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = True 11 | weight = 0 12 | 13 | [values] 14 | acceleration_enabled = False 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 500 17 | acceleration_print = 1000 18 | acceleration_support_interface = 1000 19 | acceleration_topbottom = 1000 20 | acceleration_travel = 1000 21 | acceleration_travel_layer_0 = 500 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 40 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 40 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.16 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 130 51 | prime_tower_position_y = 130 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 25 65 | speed_prime_tower = 25 66 | speed_print = 50 67 | speed_slowdown_layers = 1 68 | speed_support = 50 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 25 71 | speed_travel = 60 72 | speed_travel_layer_0 = 60 73 | speed_wall = 25 74 | speed_wall_x = 50 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.2 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/definitions/snapmaker_artisan.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker Artisan", 3 | "version": 2, 4 | "inherits": "fdmprinter", 5 | "metadata": { 6 | "manufacturer": "Snapmaker", 7 | "author": "Snapmaker", 8 | "file_formats": "text/x-snapmaker-gcode;text/x-gcode", 9 | "machine_extruder_trains": { 10 | "0": "snapmaker_artisan_extruder_0", 11 | "1": "snapmaker_artisan_extruder_1" 12 | }, 13 | "has_machine_quality": true, 14 | "has_materials": true, 15 | "quality_definition": "snapmaker_artisan", 16 | "preferred_quality_type": "normal", 17 | "preferred_material": "generic_pla", 18 | "exclude_materials": [], 19 | "visible": true 20 | }, 21 | "overrides": { 22 | "machine_name": { 23 | "default_value": "Snapmaker Artisan" 24 | }, 25 | "machine_width": { 26 | "default_value": 400 27 | }, 28 | "machine_depth": { 29 | "default_value": 400 30 | }, 31 | "machine_height": { 32 | "default_value": 400 33 | }, 34 | "machine_heated_bed": { 35 | "default_value": true 36 | }, 37 | "machine_buildplate_type": { 38 | "default_value": "glass" 39 | }, 40 | "machine_extruder_count": { 41 | "default_value": 2 42 | }, 43 | "machine_use_extruder_offset_to_offset_coords": { 44 | "default_value": false 45 | }, 46 | "machine_start_gcode": { 47 | "default_value": ";--- Start G-code Begin ---\nM205 J0.05\nM201 X100000 Y100000 Z100 E10000\nM204 P1000 T2000 R10000\nM900 T0 K0.035\nM900 T1 K0.035\nM104 S{material_print_temperature_layer_0} ;Set Hotend Temperature\nM140 S{material_bed_temperature_layer_0} ;Set Bed Temperature\nM109 S{material_print_temperature_layer_0}\nM190 S{material_bed_temperature_layer_0}\nM107\nM107 P1\nG28\nG0 Z0.5 X0 Y-0.5 F6000\nG92 E0\nG0 X150 E30 F1200\nG92 E0\nG1 Z5 F6000\n;--- Start G-code End ---\n" 48 | }, 49 | "machine_end_gcode": { 50 | "default_value": ";--- End G-code Begin ---\nM104 S0\nM140 S0\nG92 E0\nG1 E-2 F3000 ;Retract the filament\nG92 E0\nG28 Z\nG28 X0 Y0\nM84\n;--- End G-code End ---\n" 51 | }, 52 | "speed_infill": { 53 | "maximum_value_warning": "250" 54 | }, 55 | "retraction_amount": { 56 | "default_value": 1.5, 57 | "maximum_value_warning": "2.0" 58 | }, 59 | "switch_extruder_retraction_amount": { 60 | "default_value": 16, 61 | "minimum_value_warning": "15", 62 | "maximum_value_warning": "20" 63 | }, 64 | "switch_extruder_retraction_speeds": { 65 | "default_value": 20 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/extruders/snapmaker_artisan_extruder_0.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Left Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_artisan", 10 | "position": "0" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 0 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 0 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/extruders/snapmaker_artisan_extruder_1.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Right Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_artisan", 10 | "position": "1" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 1 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 0 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_PLA_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Draft 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 100 28 | speed_support = 60 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 120 32 | speed_travel_layer_0 = 60 33 | speed_wall = 50 34 | speed_wall_x = 100 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 30 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_PLA_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fast 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_PLA_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fine 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 30 26 | speed_prime_tower = 60 27 | speed_print = 60 28 | speed_support = 60 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 72 32 | speed_travel_layer_0 = 30 33 | speed_wall = 30 34 | speed_wall_x = 60 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_PLA_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Normal 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 100 28 | speed_support = 60 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 120 32 | speed_travel_layer_0 = 60 33 | speed_wall = 50 34 | speed_wall_x = 100 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 16 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_global_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Draft 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = True 11 | weight = -2 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 2000 17 | acceleration_print = 2000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 2000 20 | acceleration_travel = 2000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 2000 23 | acceleration_wall_0 = 2000 24 | acceleration_wall_x = 2000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 3 37 | cool_min_speed = 40 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 12 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.24 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 160 66 | speed_print = 160 67 | speed_slowdown_layers = 1 68 | speed_support = 60 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 160 71 | speed_travel = 192 72 | speed_travel_layer_0 = 60 73 | speed_wall = 80 74 | speed_wall_x = 160 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 3 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 2 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 30 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_global_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fast 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = True 11 | weight = -1 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 2000 17 | acceleration_print = 2000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 2000 20 | acceleration_travel = 2000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 2000 23 | acceleration_wall_0 = 2000 24 | acceleration_wall_x = 2000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 75 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 10 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.2 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 100 66 | speed_print = 100 67 | speed_slowdown_layers = 1 68 | speed_support = 60 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 160 71 | speed_travel = 120 72 | speed_travel_layer_0 = 60 73 | speed_wall = 50 74 | speed_wall_x = 100 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_global_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fine 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = True 11 | weight = 1 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 2000 17 | acceleration_print = 2000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 2000 20 | acceleration_travel = 2000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 2000 23 | acceleration_wall_0 = 2000 24 | acceleration_wall_x = 2000 25 | adhesion_type = skirt 26 | bottom_layers = 6 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 18 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.12 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 30 65 | speed_prime_tower = 60 66 | speed_print = 60 67 | speed_slowdown_layers = 1 68 | speed_support = 60 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 30 71 | speed_travel = 72 72 | speed_travel_layer_0 = 30 73 | speed_wall = 30 74 | speed_wall_x = 60 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 6 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 4 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.6 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_artisan/quality/snapmaker_artisan/artisan_global_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Normal 3 | version = 4 4 | definition = snapmaker_artisan 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = True 11 | weight = 0 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 2000 17 | acceleration_print = 2000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 2000 20 | acceleration_travel = 2000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 2000 23 | acceleration_wall_0 = 2000 24 | acceleration_wall_x = 2000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.16 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 100 66 | speed_print = 100 67 | speed_slowdown_layers = 1 68 | speed_support = 60 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 100 71 | speed_travel = 120 72 | speed_travel_layer_0 = 60 73 | speed_wall = 50 74 | speed_wall_x = 100 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 16 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.2 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/definitions/snapmaker_j1.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Snapmaker J1", 3 | "version": 2, 4 | "inherits": "fdmprinter", 5 | "metadata": { 6 | "manufacturer": "Snapmaker", 7 | "author": "Snapmaker", 8 | "file_formats": "text/x-snapmaker-gcode;text/x-gcode", 9 | "machine_extruder_trains": { 10 | "0": "snapmaker_j1_extruder_0", 11 | "1": "snapmaker_j1_extruder_1" 12 | }, 13 | "has_machine_quality": true, 14 | "has_materials": true, 15 | "quality_definition": "snapmaker_j1", 16 | "preferred_quality_type": "normal", 17 | "preferred_material": "generic_pla", 18 | "exclude_materials": [], 19 | "visible": true 20 | }, 21 | "overrides": { 22 | "machine_name": { 23 | "default_value": "Snapmaker J1" 24 | }, 25 | "machine_width": { 26 | "default_value": 324 27 | }, 28 | "machine_depth": { 29 | "default_value": 200 30 | }, 31 | "machine_height": { 32 | "default_value": 200 33 | }, 34 | "machine_heated_bed": { 35 | "default_value": true 36 | }, 37 | "machine_buildplate_type": { 38 | "default_value": "glass" 39 | }, 40 | "machine_extruder_count": { 41 | "default_value": 2 42 | }, 43 | "machine_use_extruder_offset_to_offset_coords": { 44 | "default_value": false 45 | }, 46 | "machine_start_gcode": { 47 | "default_value": ";--- Start G-code Begin ---\nM104 S{material_print_temperature_layer_0} ;Set Hotend Temperature\nM140 S{material_bed_temperature_layer_0} ;Set Bed Temperature\nG28 ;Home\nG1 Z0.8\nM109 S{material_print_temperature_layer_0}\nM190 S{material_bed_temperature_layer_0}\nG1 Z0.8 F6000\nM201 X10000 Y10000 Z500 E5000\nM205 V5\nG92 E0\nG1 F200 E2\nG92 E0\n;--- Start G-code End ---\n" 48 | }, 49 | "machine_end_gcode": { 50 | "default_value": ";--- End G-code Begin ---\nM104 S0\nM140 S0\nG92 E0\nG1 E-1 F300 ;retract the filament\n\nG92 E0\nG28 Z\nG28 X0 Y0\nM84\n;--- End G-code End ---\n" 51 | }, 52 | "speed_infill": { 53 | "maximum_value_warning": "350" 54 | }, 55 | "retraction_amount": { 56 | "default_value": 1, 57 | "maximum_value_warning": "2.0" 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/extruders/snapmaker_j1_extruder_0.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Left Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_j1", 10 | "position": "0" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 0 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 0 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "M2000 S200 V250 A6000" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "M106 P0 S0 ;fan off" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/extruders/snapmaker_j1_extruder_1.def.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Right Extruder", 3 | "version": 2, 4 | "inherits": "fdmextruder", 5 | "metadata": { 6 | "type": "extruder", 7 | "author": "Snapmaker", 8 | "manufacturer": "Snapmaker", 9 | "machine": "snapmaker_j1", 10 | "position": "1" 11 | }, 12 | "overrides": { 13 | "extruder_nr": { 14 | "default_value": 1 15 | }, 16 | "machine_nozzle_size": { 17 | "default_value": 0.4 18 | }, 19 | "material_diameter": { 20 | "default_value": 1.75 21 | }, 22 | "machine_extruder_cooling_fan_number": { 23 | "default_value": 1 24 | }, 25 | "machine_extruder_start_code": { 26 | "default_value": "M2000 S200 V250 A6000" 27 | }, 28 | "machine_extruder_end_code": { 29 | "default_value": "M106 P1 S0 ; fan off" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_ABS_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = ABS Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_abs 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 5 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 105 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 30 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_ABS_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = ABS Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_abs 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 5 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_ABS_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = ABS Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_abs 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 5 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 105 31 | speed_travel = 200 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 60 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_ABS_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = ABS Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_abs 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 5 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_Breakaway_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Breakaway Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = snapmaker_breakaway 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 30 27 | speed_print = 80 28 | speed_support = 65 29 | speed_support_interface = 30 30 | speed_topbottom = 40 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 40 34 | speed_wall_x = 40 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_Breakaway_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Breakaway Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = snapmaker_breakaway 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 30 27 | speed_print = 80 28 | speed_support = 65 29 | speed_support_interface = 30 30 | speed_topbottom = 40 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 40 34 | speed_wall_x = 40 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_Breakaway_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Breakaway Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = snapmaker_breakaway 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 30 27 | speed_print = 80 28 | speed_support = 65 29 | speed_support_interface = 30 30 | speed_topbottom = 40 31 | speed_travel = 200 32 | speed_travel_layer_0 = 100 33 | speed_wall = 40 34 | speed_wall_x = 40 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_Breakaway_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Breakaway Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = snapmaker_breakaway 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 30 27 | speed_print = 80 28 | speed_support = 65 29 | speed_support_interface = 30 30 | speed_topbottom = 40 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 40 34 | speed_wall_x = 40 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PETG_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PETG Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_petg 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 105 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 30 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PETG_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PETG Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_petg 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PETG_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PETG Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_petg 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 200 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 60 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PETG_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PETG Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_petg 13 | 14 | [values] 15 | adhesion_type = brim 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 160 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PLA_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 200 27 | speed_print = 160 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 105 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 30 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PLA_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 200 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PLA_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 200 27 | speed_print = 195 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 105 31 | speed_travel = 200 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 60 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PLA_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PLA Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_pla 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 35 26 | speed_prime_tower = 100 27 | speed_print = 250 28 | speed_support = 100 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 120 31 | speed_travel = 250 32 | speed_travel_layer_0 = 100 33 | speed_wall = 50 34 | speed_wall_x = 105 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PVA_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PVA Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_pva 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 40 27 | speed_print = 40 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 250 32 | speed_travel_layer_0 = 30 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PVA_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PVA Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_pva 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 40 27 | speed_print = 40 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 250 32 | speed_travel_layer_0 = 30 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PVA_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PVA Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_pva 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 40 27 | speed_print = 40 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 200 32 | speed_travel_layer_0 = 30 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_PVA_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = PVA Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_pva 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = True 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 35 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 40 27 | speed_print = 40 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 30 31 | speed_travel = 250 32 | speed_travel_layer_0 = 30 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = True 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_TPU_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = TPU Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = False 11 | weight = -2 12 | material = generic_tpu 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 25 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 30 27 | speed_print = 30 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 25 31 | speed_travel = 250 32 | speed_travel_layer_0 = 70 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_TPU_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = TPU Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = False 11 | weight = -1 12 | material = generic_tpu 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 25 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 30 27 | speed_print = 30 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 25 31 | speed_travel = 250 32 | speed_travel_layer_0 = 70 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_TPU_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = TPU Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = False 11 | weight = 1 12 | material = generic_tpu 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 25 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 30 27 | speed_print = 30 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 25 31 | speed_travel = 200 32 | speed_travel_layer_0 = 70 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_TPU_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = TPU Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = False 11 | weight = 0 12 | material = generic_tpu 13 | 14 | [values] 15 | adhesion_type = skirt 16 | cool_fan_full_layer = 2 17 | initial_layer_line_width_factor = 150 18 | prime_tower_enable = False 19 | retract_at_layer_change = True 20 | retraction_hop_enabled = True 21 | retraction_hop_only_when_collides = True 22 | skirt_brim_speed = 25 23 | skirt_gap = 2 24 | skirt_line_count = 2 25 | speed_layer_0 = 25 26 | speed_prime_tower = 30 27 | speed_print = 30 28 | speed_support = 30 29 | speed_support_interface = =speed_support 30 | speed_topbottom = 25 31 | speed_travel = 250 32 | speed_travel_layer_0 = 70 33 | speed_wall = 30 34 | speed_wall_x = 30 35 | support_enable = False 36 | switch_extruder_extra_prime_amount = 2 37 | switch_extruder_retraction_amount = 1 38 | switch_extruder_retraction_speed = 20 39 | switch_extruder_retraction_speeds = 20 40 | travel_avoid_distance = 2.0 41 | travel_avoid_supports = True 42 | wall_overhang_angle = 30 43 | wall_overhang_speed_factor = 50 44 | 45 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_global_Draft.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Draft 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = draft 10 | global_quality = True 11 | weight = -2 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 8000 17 | acceleration_print = 8000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 8000 20 | acceleration_travel = 8000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 5000 23 | acceleration_wall_0 = 5000 24 | acceleration_wall_x = 5000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 3 37 | cool_min_speed = 40 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 12 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.24 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 200 66 | speed_print = 160 67 | speed_slowdown_layers = 1 68 | speed_support = 125 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 120 71 | speed_travel = 250 72 | speed_travel_layer_0 = 100 73 | speed_wall = 105 74 | speed_wall_x = 105 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 1 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 3 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 2 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 30 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_global_Fast.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fast 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fast 10 | global_quality = True 11 | weight = -1 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 6000 17 | acceleration_print = 6000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 3000 20 | acceleration_travel = 6000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 75 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 10 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150.0 43 | layer_height = 0.2 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 100 66 | speed_print = 200 67 | speed_slowdown_layers = 1 68 | speed_support = 125 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 120 71 | speed_travel = 250 72 | speed_travel_layer_0 = 100 73 | speed_wall = 50 74 | speed_wall_x = 105 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 1 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 0.8 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_global_Fine.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Fine 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = fine 10 | global_quality = True 11 | weight = 1 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 500 16 | acceleration_prime_tower = 2000 17 | acceleration_print = 2000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 2000 20 | acceleration_travel = 2000 21 | acceleration_travel_layer_0 = 500 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 6 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = lines 41 | infill_sparse_density = 18 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.12 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 200 66 | speed_print = 195 67 | speed_slowdown_layers = 1 68 | speed_support = 125 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 105 71 | speed_travel = 200 72 | speed_travel_layer_0 = 100 73 | speed_wall = 50 74 | speed_wall_x = 105 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 1 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 6 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 4 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.6 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /resources/snapmaker_j1_profiles/quality/snapmaker_j1/j1_global_Normal.inst.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | name = Normal 3 | version = 4 4 | definition = snapmaker_j1 5 | 6 | [metadata] 7 | setting_version = 20 8 | type = quality 9 | quality_type = normal 10 | global_quality = True 11 | weight = 0 12 | 13 | [values] 14 | acceleration_enabled = True 15 | acceleration_layer_0 = 1000 16 | acceleration_prime_tower = 6000 17 | acceleration_print = 6000 18 | acceleration_support_interface = 2000 19 | acceleration_topbottom = 3000 20 | acceleration_travel = 6000 21 | acceleration_travel_layer_0 = 1000 22 | acceleration_wall = 1000 23 | acceleration_wall_0 = 1000 24 | acceleration_wall_x = 1000 25 | adhesion_type = skirt 26 | bottom_layers = 3 27 | bottom_thickness = 0.6 28 | bridge_enable_more_layers = False 29 | bridge_settings_enabled = True 30 | bridge_skin_material_flow = 100 31 | bridge_skin_speed = 80 32 | bridge_wall_material_flow = 100 33 | bridge_wall_speed = 50 34 | brim_line_count = 6 35 | cool_fan_full_layer = 2 36 | cool_min_layer_time = 5 37 | cool_min_speed = 30 38 | infill_before_walls = False 39 | infill_overlap = 20 40 | infill_pattern = grid 41 | infill_sparse_density = 15 42 | initial_layer_line_width_factor = 150 43 | layer_height = 0.16 44 | layer_height_0 = 0.28 45 | minimum_interface_area = 20 46 | optimize_wall_printing_order = True 47 | prime_tower_brim_enable = True 48 | prime_tower_enable = False 49 | prime_tower_min_volume = 12 50 | prime_tower_position_x = 175 51 | prime_tower_position_y = 150 52 | prime_tower_size = 35 53 | retract_at_layer_change = True 54 | retraction_combing = no_outer_surfaces 55 | retraction_count_max = 5 56 | retraction_extrusion_window = 1.5 57 | retraction_hop_enabled = True 58 | retraction_hop_only_when_collides = True 59 | skin_overlap = 15 60 | skirt_brim_speed = 35 61 | skirt_gap = 2 62 | skirt_line_count = 2 63 | slicing_tolerance = middle 64 | speed_layer_0 = 35 65 | speed_prime_tower = 100 66 | speed_print = 250 67 | speed_slowdown_layers = 1 68 | speed_support = 125 69 | speed_support_interface = =speed_support 70 | speed_topbottom = 120 71 | speed_travel = 250 72 | speed_travel_layer_0 = 100 73 | speed_wall = 50 74 | speed_wall_x = 105 75 | support_bottom_height = 0.6 76 | support_brim_enable = True 77 | support_enable = False 78 | support_interface_density = 70 79 | support_interface_enable = True 80 | support_interface_offset = 1 81 | support_interface_pattern = zigzag 82 | support_offset = 2 83 | support_roof_height = 1 84 | support_wall_count = 1 85 | support_xy_distance = 0.5 86 | support_z_distance = 0 87 | switch_extruder_extra_prime_amount = 2 88 | switch_extruder_retraction_amount = 1 89 | switch_extruder_retraction_speed = 20 90 | switch_extruder_retraction_speeds = 20 91 | top_bottom_pattern = zigzag 92 | top_bottom_thickness = 0.6 93 | top_layers = 4 94 | travel_avoid_distance = 2.0 95 | travel_avoid_other_parts = True 96 | travel_avoid_supports = True 97 | wall_line_count = 3 98 | wall_overhang_angle = 30 99 | wall_overhang_speed_factor = 50 100 | wall_thickness = 1.2 101 | z_seam_corner = z_seam_corner_weighted 102 | z_seam_type = back 103 | 104 | -------------------------------------------------------------------------------- /settings_plugin/SnapmakerSettingsPlugin.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | import shutil 3 | from typing import Optional 4 | 5 | from UM.Application import Application 6 | from UM.Extension import Extension 7 | from UM.Logger import Logger 8 | from UM.PluginRegistry import PluginRegistry 9 | from UM.Resources import Resources 10 | 11 | from cura.CuraApplication import CuraApplication 12 | from ..PluginPreferences import PluginPreferences 13 | 14 | 15 | class SnapmakerSettingsPlugin(Extension): 16 | """Plugin that install Snapmaker profiles into Cura. 17 | 18 | Profiles for printers: 19 | - Snapmaker J1 20 | - Snapmaker Artisan 21 | """ 22 | 23 | def __init__(self) -> None: 24 | super().__init__() 25 | 26 | self._plugin_path = None # type: Optional[str] 27 | 28 | self._preferences = None # type: Optional[PluginPreferences] 29 | 30 | self._previous_version = "0.0.0" 31 | 32 | Application.getInstance().pluginsLoaded.connect(self._onPluginsLoaded) 33 | Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) 34 | 35 | def _onPluginsLoaded(self) -> None: 36 | # when plugins are loaded, we can actually get plugin id 37 | self._plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) 38 | 39 | self._preferences = PluginPreferences(self.getPluginId()) 40 | self._preferences.addPrefenrece("version", "0.0.0") 41 | 42 | self._previous_version = self._preferences.getValue("version") 43 | self.installResources() 44 | 45 | def _onEngineCreated(self) -> None: 46 | # preferences is initialized, we can set values by now 47 | self._preferences.setValue("version", self.getVersion()) 48 | 49 | def __shouldUpdateResources(self) -> bool: 50 | # debugging mode, always update 51 | if self.getVersion() == "0.0.0": 52 | return True 53 | 54 | # Once plugin version changed, update profiles 55 | if self._previous_version is None or self._previous_version != self.getVersion(): 56 | return True 57 | 58 | return False 59 | 60 | def __installMachineSettings(self, machine_dirname: str) -> None: 61 | """Intall specific machine settings. 62 | 63 | @param machine_dirname: The directory name of the machine resources. 64 | """ 65 | machine_settings_dir = os.path.join(self._plugin_path, "resources", machine_dirname) 66 | plugin_machine_dir = os.path.join(machine_settings_dir, "definitions") 67 | plugin_extruder_dir = os.path.join(machine_settings_dir, "extruders") 68 | plugin_quality_dir = os.path.join(machine_settings_dir, "quality") 69 | 70 | definition_dir = Resources.getStoragePath(Resources.DefinitionContainers) 71 | extruder_dir = Resources.getStoragePath(CuraApplication.ResourceTypes.ExtruderStack) 72 | quality_dir = Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer) 73 | 74 | # copy machine definitions 75 | if os.path.exists(plugin_machine_dir): 76 | for filename in os.listdir(plugin_machine_dir): 77 | if filename.endswith(".def.json"): 78 | file_path = os.path.join(plugin_machine_dir, filename) 79 | shutil.copy2(file_path, definition_dir) 80 | 81 | # copy extruders 82 | if os.path.exists(plugin_extruder_dir): 83 | for filename in os.listdir(plugin_extruder_dir): 84 | if filename.endswith(".def.json"): 85 | file_path = os.path.join(plugin_extruder_dir, filename) 86 | shutil.copy2(file_path, extruder_dir) 87 | 88 | # copy quality files 89 | if os.path.exists(plugin_quality_dir): 90 | for filename in os.listdir(plugin_quality_dir): 91 | file_path = os.path.join(plugin_quality_dir, filename) 92 | if os.path.isdir(file_path): # machine quality folder 93 | shutil.copytree(file_path, os.path.join(quality_dir, filename), dirs_exist_ok=True) 94 | 95 | def __updateMaterials(self) -> None: 96 | plugin_material_dir = os.path.join(self._plugin_path, "resources", "materials") 97 | 98 | material_dir = Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer) 99 | 100 | for filename in os.listdir(plugin_material_dir): 101 | if filename.endswith(".xml.fdm_material"): 102 | file_path = os.path.join(plugin_material_dir, filename) 103 | shutil.copy2(file_path, material_dir) 104 | 105 | def installResources(self) -> None: 106 | if not self.__shouldUpdateResources(): 107 | return 108 | 109 | Logger.info("Installing settings for Snapmaker printers...") 110 | 111 | self.__installMachineSettings("snapmaker_j1_profiles") 112 | self.__installMachineSettings("snapmaker_artisan") 113 | self.__installMachineSettings("snapmaker_2_dual_extruder") 114 | self.__updateMaterials() 115 | 116 | Logger.info("Installation done.") 117 | --------------------------------------------------------------------------------