diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index e700b8d7be..61802167a7 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -37,13 +37,9 @@ class BuildVolume(SceneNode): self.setCalculateBoundingBox(False) - self._active_profile = None - self._active_instance = None - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveInstanceChanged) - self._onActiveInstanceChanged() - - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - self._onActiveProfileChanged() + self._active_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) + self._onGlobalContainerStackChanged() def setWidth(self, width): if width: self._width = width @@ -76,7 +72,7 @@ class BuildVolume(SceneNode): ## Recalculates the build volume & disallowed areas. def rebuild(self): - if self._width == 0 or self._height == 0 or self._depth == 0: + if not self._width or not self._height or not self._depth: return min_w = -self._width / 2 @@ -148,9 +144,9 @@ class BuildVolume(SceneNode): skirt_size = 0.0 - profile = Application.getInstance().getMachineManager().getWorkingProfile() - if profile: - skirt_size = self._getSkirtSize(profile) + container_stack = Application.getInstance().getGlobalContainerStack() + if container_stack: + skirt_size = self._getSkirtSize(container_stack) # As this works better for UM machines, we only add the disallowed_area_size for the z direction. # This is probably wrong in all other cases. TODO! @@ -162,52 +158,49 @@ class BuildVolume(SceneNode): Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds - def _onActiveInstanceChanged(self): - self._active_instance = Application.getInstance().getMachineManager().getActiveMachineInstance() + def _onGlobalContainerStackChanged(self): + if self._active_container_stack: + self._active_container_stack.propertyChanged.disconnect(self._onSettingPropertyChanged) - if self._active_instance: - self._width = self._active_instance.getMachineSettingValue("machine_width") - if Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("print_sequence") == "one_at_a_time": - self._height = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("gantry_height") + self._active_container_stack = Application.getInstance().getGlobalContainerStack() + + if self._active_container_stack: + self._active_container_stack.propertyChanged.connect(self._onSettingPropertyChanged) + + self._width = self._active_container_stack.getProperty("machine_width", "value") + if self._active_container_stack.getProperty("print_sequence", "value") == "one_at_a_time": + self._height = self._active_container_stack.getProperty("gantry_height", "value") else: - self._height = self._active_instance.getMachineSettingValue("machine_height") - self._depth = self._active_instance.getMachineSettingValue("machine_depth") + self._height = self._active_container_stack.getProperty("machine_height", "value") + self._depth = self._active_container_stack.getProperty("machine_depth", "value") self._updateDisallowedAreas() self.rebuild() - def _onActiveProfileChanged(self): - if self._active_profile: - self._active_profile.settingValueChanged.disconnect(self._onSettingValueChanged) + def _onSettingPropertyChanged(self, setting_key, property_name): + if property_name != "value": + return - self._active_profile = Application.getInstance().getMachineManager().getWorkingProfile() - if self._active_profile: - self._active_profile.settingValueChanged.connect(self._onSettingValueChanged) - self._updateDisallowedAreas() - self.rebuild() - - def _onSettingValueChanged(self, setting_key): if setting_key == "print_sequence": - if Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("print_sequence") == "one_at_a_time": - self._height = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("gantry_height") + if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time": + self._height = self._active_container_stack.getProperty("gantry_height", "value") else: - self._height = self._active_instance.getMachineSettingValue("machine_depth") + self._height = self._active_container_stack.getProperty("machine_height", "value") self.rebuild() if setting_key in self._skirt_settings: self._updateDisallowedAreas() self.rebuild() def _updateDisallowedAreas(self): - if not self._active_instance or not self._active_profile: + if not self._active_container_stack: return - disallowed_areas = self._active_instance.getMachineSettingValue("machine_disallowed_areas") + disallowed_areas = self._active_container_stack.getProperty("machine_disallowed_areas", "value") areas = [] skirt_size = 0.0 - if self._active_profile: - skirt_size = self._getSkirtSize(self._active_profile) + skirt_size = self._getSkirtSize(self._active_container_stack) if disallowed_areas: # Extend every area already in the disallowed_areas with the skirt size. @@ -228,8 +221,8 @@ class BuildVolume(SceneNode): # Add the skirt areas around the borders of the build plate. if skirt_size > 0: - half_machine_width = self._active_instance.getMachineSettingValue("machine_width") / 2 - half_machine_depth = self._active_instance.getMachineSettingValue("machine_depth") / 2 + half_machine_width = self._active_container_stack.getProperty("machine_width", "value") / 2 + half_machine_depth = self._active_container_stack.getProperty("machine_depth", "value") / 2 areas.append(Polygon(numpy.array([ [-half_machine_width, -half_machine_depth], @@ -262,24 +255,24 @@ class BuildVolume(SceneNode): self._disallowed_areas = areas ## Convenience function to calculate the size of the bed adhesion. - def _getSkirtSize(self, profile): + def _getSkirtSize(self, container_stack): skirt_size = 0.0 - adhesion_type = profile.getSettingValue("adhesion_type") + adhesion_type = container_stack.getProperty("adhesion_type", "value") if adhesion_type == "skirt": - skirt_distance = profile.getSettingValue("skirt_gap") - skirt_line_count = profile.getSettingValue("skirt_line_count") - skirt_size = skirt_distance + (skirt_line_count * profile.getSettingValue("skirt_line_width")) + skirt_distance = container_stack.getProperty("skirt_gap", "value") + skirt_line_count = container_stack.getProperty("skirt_line_count", "value") + skirt_size = skirt_distance + (skirt_line_count * container_stack.getProperty("skirt_line_width", "value")) elif adhesion_type == "brim": - skirt_size = profile.getSettingValue("brim_line_count") * profile.getSettingValue("skirt_line_width") + skirt_size = container_stack.getProperty("brim_line_count", "value") * container_stack.getProperty("skirt_line_width", "value") elif adhesion_type == "raft": - skirt_size = profile.getSettingValue("raft_margin") + skirt_size = container_stack.getProperty("raft_margin", "value") - if profile.getSettingValue("draft_shield_enabled"): - skirt_size += profile.getSettingValue("draft_shield_dist") + if container_stack.getProperty("draft_shield_enabled", "value"): + skirt_size += container_stack.getProperty("draft_shield_dist", "value") - if profile.getSettingValue("xy_offset"): - skirt_size += profile.getSettingValue("xy_offset") + if container_stack.getProperty("xy_offset", "value"): + skirt_size += container_stack.getProperty("xy_offset", "value") return skirt_size diff --git a/cura/ConvexHullDecorator.py b/cura/ConvexHullDecorator.py index 381b5b2b69..8fb26858a5 100644 --- a/cura/ConvexHullDecorator.py +++ b/cura/ConvexHullDecorator.py @@ -28,9 +28,9 @@ class ConvexHullDecorator(SceneNodeDecorator): self._parent_node = None self._profile = None - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) - self._onActiveProfileChanged() + #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) + #Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineInstanceChanged) + #self._onActiveProfileChanged() def setNode(self, node): super().setNode(node) diff --git a/cura/ConvexHullJob.py b/cura/ConvexHullJob.py index b356cb15f1..449b233b93 100644 --- a/cura/ConvexHullJob.py +++ b/cura/ConvexHullJob.py @@ -68,12 +68,12 @@ class ConvexHullJob(Job): # This is done because of rounding errors. hull = hull.getMinkowskiHull(Polygon(numpy.array([[-0.5, -0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]], numpy.float32))) - profile = Application.getInstance().getMachineManager().getWorkingProfile() - if profile: - if profile.getSettingValue("print_sequence") == "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"): + global_stack = Application.getInstance().getGlobalContainerStack() + if global_stack: + if global_stack.getProperty("print_sequence", "value")== "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"): # Printing one at a time and it's not an object in a group self._node.callDecoration("setConvexHullBoundary", copy.deepcopy(hull)) - head_and_fans = Polygon(numpy.array(profile.getSettingValue("machine_head_with_fans_polygon"), numpy.float32)) + head_and_fans = Polygon(numpy.array(global_stack.getProperty("machine_head_with_fans_polygon", "value"), numpy.float32)) # Full head hull is used to actually check the order. full_head_hull = hull.getMinkowskiHull(head_and_fans) @@ -86,7 +86,7 @@ class ConvexHullJob(Job): # Min head hull is used for the push free min_head_hull = hull.getMinkowskiHull(head_and_fans) self._node.callDecoration("setConvexHullHead", min_head_hull) - hull = hull.getMinkowskiHull(Polygon(numpy.array(profile.getSettingValue("machine_head_polygon"),numpy.float32))) + hull = hull.getMinkowskiHull(Polygon(numpy.array(global_stack.getProperty("machine_head_polygon","value"),numpy.float32))) else: self._node.callDecoration("setConvexHullHead", None) if self._node.getParent() is None: # Node was already deleted before job is done. diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index de922d1984..9691b638a1 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -15,7 +15,7 @@ from UM.Mesh.ReadMeshJob import ReadMeshJob from UM.Logger import Logger from UM.Preferences import Preferences from UM.JobQueue import JobQueue - +from UM.SaveFile import SaveFile from UM.Scene.Selection import Selection from UM.Scene.GroupDecorator import GroupDecorator @@ -25,6 +25,9 @@ from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.SetTransformOperation import SetTransformOperation from cura.SetParentOperation import SetParentOperation +from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType +from UM.Settings.ContainerRegistry import ContainerRegistry + from UM.i18n import i18nCatalog from . import PlatformPhysics @@ -35,16 +38,18 @@ from . import CuraActions from . import MultiMaterialDecorator from . import ZOffsetDecorator from . import CuraSplashScreen +from . import MachineManagerModel from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS from PyQt5.QtGui import QColor, QIcon -from PyQt5.QtQml import qmlRegisterUncreatableType +from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType import platform import sys import os.path import numpy import copy +import urllib numpy.seterr(all="ignore") #WORKAROUND: GITHUB-88 GITHUB-385 GITHUB-612 @@ -65,6 +70,13 @@ class CuraApplication(QtApplication): class ResourceTypes: QmlFiles = Resources.UserType + 1 Firmware = Resources.UserType + 2 + QualityInstanceContainer = Resources.UserType + 3 + MaterialInstanceContainer = Resources.UserType + 4 + VariantInstanceContainer = Resources.UserType + 5 + UserInstanceContainer = Resources.UserType + 6 + MachineStack = Resources.UserType + 7 + ExtruderInstanceContainer = Resources.UserType + 8 + Q_ENUMS(ResourceTypes) def __init__(self): @@ -74,6 +86,9 @@ class CuraApplication(QtApplication): self._open_file_queue = [] # Files to open when plug-ins are loaded. + # Need to do this before ContainerRegistry tries to load the machines + SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) + super().__init__(name = "cura", version = CuraVersion) self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png"))) @@ -102,15 +117,28 @@ class CuraApplication(QtApplication): self._camera_animation = None self._cura_actions = None - self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged) - self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested) self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity) self.getController().toolOperationStopped.connect(self._onToolOperationStopped) Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") - Preferences.getInstance().addPreference("cura/active_machine", "") + ## Add the 4 types of profiles to storage. + Resources.addStorageType(self.ResourceTypes.QualityInstanceContainer, "quality") + Resources.addStorageType(self.ResourceTypes.VariantInstanceContainer, "variants") + Resources.addStorageType(self.ResourceTypes.MaterialInstanceContainer, "materials") + Resources.addStorageType(self.ResourceTypes.ExtruderInstanceContainer, "extruders") + Resources.addStorageType(self.ResourceTypes.UserInstanceContainer, "user") + Resources.addStorageType(self.ResourceTypes.MachineStack, "machine_instances") + + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.QualityInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.VariantInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MaterialInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) + ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + + ContainerRegistry.getInstance().load() + Preferences.getInstance().addPreference("cura/active_mode", "simple") Preferences.getInstance().addPreference("cura/recent_files", "") Preferences.getInstance().addPreference("cura/categories_expanded", "") @@ -120,8 +148,43 @@ class CuraApplication(QtApplication): Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) Preferences.getInstance().setDefault("local_file/last_used_type", "text/x-gcode") + Preferences.getInstance().setDefault("general/visible_settings", """ + resolution + layer_height + shell + wall_thickness + top_bottom_thickness + infill + infill_sparse_density + material + material_print_temperature + material_bed_temperature + material_diameter + material_flow + retraction_enable + speed + speed_print + speed_travel + cooling + cool_fan_enabled + support + support_enable + support_type + support_roof_density + platform_adhesion + adhesion_type + brim_width + raft_airgap + layer_0_z_overlap + raft_surface_layers + blackmagic + print_sequence + """) + JobQueue.getInstance().jobFinished.connect(self._onJobFinished) + self.applicationShuttingDown.connect(self._onExit) + self._recent_files = [] files = Preferences.getInstance().getValue("cura/recent_files").split(";") for f in files: @@ -130,6 +193,54 @@ class CuraApplication(QtApplication): self._recent_files.append(QUrl.fromLocalFile(f)) + ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. + def _onExit(self): + for instance in ContainerRegistry.getInstance().findInstanceContainers(): + if not instance.isDirty(): + continue + + try: + data = instance.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + + file_name = urllib.parse.quote_plus(instance.getId()) + ".inst.cfg" + instance_type = instance.getMetaDataEntry("type") + path = None + if instance_type == "material": + path = Resources.getStoragePath(self.ResourceTypes.MaterialInstanceContainer, file_name) + elif instance_type == "quality": + path = Resources.getStoragePath(self.ResourceTypes.QualityInstanceContainer, file_name) + elif instance_type == "user": + path = Resources.getStoragePath(self.ResourceTypes.UserInstanceContainer, file_name) + elif instance_type == "variant": + path = Resources.getStoragePath(self.ResourceTypes.VariantInstanceContainer, file_name) + + if path: + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + for stack in ContainerRegistry.getInstance().findContainerStacks(): + if not stack.isDirty(): + continue + + try: + data = stack.serialize() + except NotImplementedError: + continue + except Exception: + Logger.logException("e", "An exception occurred when serializing container %s", instance.getId()) + continue + + file_name = urllib.parse.quote_plus(stack.getId()) + ".stack.cfg" + path = Resources.getStoragePath(self.ResourceTypes.MachineStack, file_name) + with SaveFile(path, "wt", -1, "utf-8") as f: + f.write(data) + + @pyqtSlot(result = QUrl) def getDefaultPath(self): return QUrl.fromLocalFile(os.path.expanduser("~/")) @@ -137,6 +248,7 @@ class CuraApplication(QtApplication): ## Handle loading of all plugin types (and the backend explicitly) # \sa PluginRegistery def _loadPlugins(self): + self._plugin_registry.addType("profile_reader", self._addProfileReader) self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura")) if not hasattr(sys, "frozen"): self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins")) @@ -199,6 +311,9 @@ class CuraApplication(QtApplication): self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface...")) + qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", + MachineManagerModel.createMachineManagerModel) + self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self.initializeEngine() @@ -511,20 +626,6 @@ class CuraApplication(QtApplication): def expandedCategories(self): return Preferences.getInstance().getValue("cura/categories_expanded").split(";") - @pyqtSlot(str, result = "QVariant") - def getSettingValue(self, key): - if not self.getMachineManager().getWorkingProfile(): - return None - return self.getMachineManager().getWorkingProfile().getSettingValue(key) - - ## Change setting by key value pair - @pyqtSlot(str, "QVariant") - def setSettingValue(self, key, value): - if not self.getMachineManager().getWorkingProfile(): - return - - self.getMachineManager().getWorkingProfile().setSettingValue(key, value) - @pyqtSlot() def mergeSelected(self): self.groupSelected() @@ -630,5 +731,6 @@ class CuraApplication(QtApplication): job.finished.connect(self._onFileLoaded) job.start() - def _onAddMachineRequested(self): - self.requestAddPrinter.emit() + def _addProfileReader(self, profile_reader): + # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. + pass diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py new file mode 100644 index 0000000000..8354f3a140 --- /dev/null +++ b/cura/MachineManagerModel.py @@ -0,0 +1,263 @@ + +from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal +from UM.Application import Application +from UM.Preferences import Preferences + +import UM.Settings + +class MachineManagerModel(QObject): + def __init__(self, parent = None): + super().__init__(parent) + + self._global_container_stack = None + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged) + self._onGlobalContainerChanged() + + ## When the global container is changed, active material probably needs to be updated. + self.globalContainerChanged.connect(self.activeMaterialChanged) + self.globalContainerChanged.connect(self.activeVariantChanged) + self.globalContainerChanged.connect(self.activeQualityChanged) + + Preferences.getInstance().addPreference("cura/active_machine", "") + + active_machine_id = Preferences.getInstance().getValue("cura/active_machine") + + if active_machine_id != "": + # An active machine was saved, so restore it. + self.setActiveMachine(active_machine_id) + pass + + + globalContainerChanged = pyqtSignal() + activeMaterialChanged = pyqtSignal() + activeVariantChanged = pyqtSignal() + activeQualityChanged = pyqtSignal() + + def _onGlobalContainerChanged(self): + if self._global_container_stack: + self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) + + self._global_container_stack = Application.getInstance().getGlobalContainerStack() + self.globalContainerChanged.emit() + + if self._global_container_stack: + Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId()) + self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged) + + def _onInstanceContainersChanged(self, container): + container_type = container.getMetaDataEntry("type") + if container_type == "material": + self.activeMaterialChanged.emit() + elif container_type == "variant": + self.activeVariantChanged.emit() + elif container_type == "quality": + self.activeQualityChanged.emit() + + @pyqtSlot(str) + def setActiveMachine(self, stack_id): + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = stack_id) + if containers: + Application.getInstance().setGlobalContainerStack(containers[0]) + + @pyqtSlot(str, str) + def addMachine(self,name, definition_id): + definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id) + if definitions: + definition = definitions[0] + + new_global_stack = UM.Settings.ContainerStack(name) + new_global_stack.addMetaDataEntry("type", "machine") + UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) + + empty_container = UM.Settings.ContainerRegistry.getInstance().getEmptyInstanceContainer() + + variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) + if variants: + new_global_stack.addMetaDataEntry("has_variants", True) + + preferred_variant_id = definitions[0].getMetaDataEntry("preferred_variant") + variant_instance_container = empty_container + if preferred_variant_id: + preferred_variant_id = preferred_variant_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id) + if container: + variant_instance_container = container[0] + + if variants and variant_instance_container == empty_container: + variant_instance_container = variants[0] + + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) + if materials: + new_global_stack.addMetaDataEntry("has_materials", True) + + preferred_material_id = definitions[0].getMetaDataEntry("preferred_material") + material_instance_container = empty_container + if preferred_material_id: + preferred_material_id = preferred_material_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_material_id) + if container: + material_instance_container = container[0] + + if materials and material_instance_container == empty_container: + material_instance_container = materials[0] + + preferred_quality_id = definitions[0].getMetaDataEntry("preferred_quality") + quality_instance_container = empty_container + if preferred_quality_id: + preferred_quality_id = preferred_quality_id.lower() + container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = preferred_quality_id) + if container: + quality_instance_container = container[0] + + current_settings_instance_container = UM.Settings.InstanceContainer(name + "_current_settings") + current_settings_instance_container.addMetaDataEntry("machine", name) + current_settings_instance_container.addMetaDataEntry("type", "user") + current_settings_instance_container.setDefinition(definitions[0]) + UM.Settings.ContainerRegistry.getInstance().addContainer(current_settings_instance_container) + + # If a definition is found, its a list. Should only have one item. + new_global_stack.addContainer(definitions[0]) + if variant_instance_container: + new_global_stack.addContainer(variant_instance_container) + if material_instance_container: + new_global_stack.addContainer(material_instance_container) + if quality_instance_container: + new_global_stack.addContainer(quality_instance_container) + new_global_stack.addContainer(current_settings_instance_container) + + Application.getInstance().setGlobalContainerStack(new_global_stack) + + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineName(self): + if self._global_container_stack: + return self._global_container_stack.getName() + + return "" + + @pyqtProperty(str, notify = globalContainerChanged) + def activeMachineId(self): + if self._global_container_stack: + return self._global_container_stack.getId() + + return "" + + @pyqtProperty(str, notify = activeMaterialChanged) + def activeMaterialName(self): + if self._global_container_stack: + material = self._global_container_stack.findContainer({"type":"material"}) + if material: + return material.getName() + + return "" + + @pyqtProperty(str, notify=activeMaterialChanged) + def activeMaterialId(self): + if self._global_container_stack: + material = self._global_container_stack.findContainer({"type": "material"}) + if material: + return material.getId() + + return "" + + @pyqtProperty(str, notify=activeQualityChanged) + def activeQualityName(self): + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getName() + return "" + + @pyqtProperty(str, notify=activeQualityChanged) + def activeQualityId(self): + if self._global_container_stack: + quality = self._global_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getId() + return "" + + @pyqtSlot(str) + def setActiveMaterial(self, material_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=material_id) + if not containers or not self._global_container_stack: + return + + old_material = self._global_container_stack.findContainer({"type":"material"}) + if old_material: + material_index = self._global_container_stack.getContainerIndex(old_material) + self._global_container_stack.replaceContainer(material_index, containers[0]) + + @pyqtSlot(str) + def setActiveVariant(self, variant_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=variant_id) + if not containers or not self._global_container_stack: + return + + old_variant = self._global_container_stack.findContainer({"type": "variant"}) + if old_variant: + variant_index = self._global_container_stack.getContainerIndex(old_variant) + self._global_container_stack.replaceContainer(variant_index, containers[0]) + + @pyqtSlot(str) + def setActiveQuality(self, quality_id): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id) + if not containers or not self._global_container_stack: + return + + old_quality = self._global_container_stack.findContainer({"type": "quality"}) + if old_quality: + quality_index = self._global_container_stack.getContainerIndex(old_quality) + self._global_container_stack.replaceContainer(quality_index, containers[0]) + + @pyqtProperty(str, notify = activeVariantChanged) + def activeVariantName(self): + if self._global_container_stack: + variant = self._global_container_stack.findContainer({"type": "variant"}) + if variant: + return variant.getName() + + return "" + + @pyqtProperty(str, notify = activeVariantChanged) + def activeVariantId(self): + if self._global_container_stack: + variant = self._global_container_stack.findContainer({"type": "variant"}) + if variant: + return variant.getId() + + return "" + + @pyqtProperty(str, notify = globalContainerChanged) + def activeDefinitionId(self): + if self._global_container_stack: + definition = self._global_container_stack.getBottom() + if definition: + return definition.id + + return "" + + @pyqtSlot(str, str) + def renameMachine(self, machine_id, new_name): + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(id = machine_id) + if containers: + containers[0].setName(new_name) + + @pyqtSlot(str) + def removeMachine(self, machine_id): + UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) + + @pyqtProperty(bool, notify = globalContainerChanged) + def hasMaterials(self): + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("has_materials", False) + + return False + + @pyqtProperty(bool, notify = globalContainerChanged) + def hasVariants(self): + if self._global_container_stack: + return self._global_container_stack.getMetaDataEntry("has_variants", False) + + return False + +def createMachineManagerModel(engine, script_engine): + return MachineManagerModel() diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index d3eaab662c..2663cab5a0 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -63,6 +63,6 @@ class PrintInformation(QObject): self.currentPrintTimeChanged.emit() # Material amount is sent as an amount of mm^3, so calculate length from that - r = Application.getInstance().getMachineManager().getWorkingProfile().getSettingValue("material_diameter") / 2 + r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2 self._material_amount = round((amount / (math.pi * r ** 2)) / 1000, 2) self.materialAmountChanged.emit() diff --git a/cura/ProfileReader.py b/cura/ProfileReader.py new file mode 100644 index 0000000000..36bb2c7177 --- /dev/null +++ b/cura/ProfileReader.py @@ -0,0 +1,17 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from UM.PluginObject import PluginObject + +## A type of plug-ins that reads profiles from a file. +# +# The profile is then stored as instance container of the type user profile. +class ProfileReader(PluginObject): + def __init__(self): + super().__init__() + + ## Read profile data from a file and return a filled profile. + # + # \return \type{Profile} The profile that was obtained from the file. + def read(self, file_name): + raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.") \ No newline at end of file diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py new file mode 100644 index 0000000000..826970c51f --- /dev/null +++ b/cura/SettingOverrideDecorator.py @@ -0,0 +1,29 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. +from UM.Scene.SceneNodeDecorator import SceneNodeDecorator + +from UM.Settings.ContainerStack import ContainerStack +from UM.Settings.InstanceContainer import InstanceContainer +from UM.Settings.ContainerRegistry import ContainerRegistry + +from UM.Application import Application + +## A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding +# the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by +# this stack still resolve. +class SettingOverrideDecorator(SceneNodeDecorator): + def __init__(self): + super().__init__() + self._stack = ContainerStack(id = "SettingOverrideStack") + self._instance = InstanceContainer(id = "SettingOverrideInstanceContainer") + self._stack.addContainer(self._instance) + + Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) + self._onGlobalContainerStackChanged() + + def _onGlobalContainerStackChanged(self): + ## Ensure that the next stack is always the global stack. + self._stack.setNextStack(Application.getInstance().getGlobalContainerStack()) + + def getStack(self): + return self._stack \ No newline at end of file diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index b6ece7e85f..d088288391 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -11,6 +11,7 @@ from UM.Qt.Bindings.BackendProxy import BackendState #To determine the state of from UM.Message import Message from UM.PluginRegistry import PluginRegistry from UM.Resources import Resources +from UM.Settings.Validator import ValidatorState #To find if a setting is in an error state. We can't slice then. from cura.OneAtATimeIterator import OneAtATimeIterator from . import ProcessSlicedLayersJob @@ -29,6 +30,10 @@ catalog = i18nCatalog("cura") class CuraEngineBackend(Backend): + ## Starts the back-end plug-in. + # + # This registers all the signal listeners and prepares for communication + # with the back-end in general. def __init__(self): super().__init__() @@ -50,19 +55,19 @@ class CuraEngineBackend(Backend): self._onActiveViewChanged() self._stored_layer_data = [] - # When there are current settings and machine instance is changed, there is no profile changed event. We should - # pretend there is though. - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveProfileChanged) - - self._profile = None - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged) - self._onActiveProfileChanged() + #Triggers for when to (re)start slicing: + if Application.getInstance().getGlobalContainerStack(): + Application.getInstance().getGlobalContainerStack().propertyChanged.connect(self._onSettingChanged) #Note: Only starts slicing when the value changed. + #When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired. + #This timer will group them up, and only slice for the last setting changed signal. + #TODO: Properly group propertyChanged signals by whether they are triggered by the same user interaction. self._change_timer = QTimer() self._change_timer.setInterval(500) self._change_timer.setSingleShot(True) self._change_timer.timeout.connect(self.slice) + #Listeners for receiving messages from the back-end. self._message_handlers["cura.proto.Layer"] = self._onLayerMessage self._message_handlers["cura.proto.Progress"] = self._onProgressMessage self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage @@ -70,39 +75,35 @@ class CuraEngineBackend(Backend): self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage - self._slicing = False self._start_slice_job = None - self._restart = False - self._enabled = True - self._always_restart = True + self._slicing = False #Are we currently slicing? + self._restart = False #Back-end is currently restarting? + self._enabled = True #Should we be slicing? Slicing might be paused when, for instance, the user is dragging the mesh around. + self._always_restart = True #Always restart the engine when starting a new slice. Don't keep the process running. TODO: Fix engine statelessness. self._process_layers_job = None #The currently active job to process layers, or None if it is not processing layers. - self._message = None + self._message = None #Pop-up message that shows the slicing progress bar (or an error message). self.backendQuit.connect(self._onBackendQuit) - self.backendConnected.connect(self._onBackendConnected) + + #When a tool operation is in progress, don't slice. So we need to listen for tool operations. Application.getInstance().getController().toolOperationStarted.connect(self._onToolOperationStarted) Application.getInstance().getController().toolOperationStopped.connect(self._onToolOperationStopped) - Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onInstanceChanged) - + ## Called when closing the application. + # + # This function should terminate the engine process. def close(self): # Terminate CuraEngine if it is still running at this point self._terminate() super().close() ## Get the command that is used to call the engine. - # This is usefull for debugging and used to actually start the engine + # This is useful for debugging and used to actually start the engine. # \return list of commands and args / parameters. def getEngineCommand(self): - active_machine = Application.getInstance().getMachineManager().getActiveMachineInstance() - json_path = "" - if not active_machine: - json_path = Resources.getPath(Resources.MachineDefinitions, "fdmprinter.json") - else: - json_path = active_machine.getMachineDefinition().getPath() - + json_path = Resources.getPath(Resources.DefinitionContainers, "fdmprinter.def.json") return [Preferences.getInstance().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), "-j", json_path, "-vv"] def close(self): @@ -116,45 +117,51 @@ class CuraEngineBackend(Backend): ## Emitted when the slicing process starts. slicingStarted = Signal() - ## Emitted whne the slicing process is aborted forcefully. + ## Emitted when the slicing process is aborted forcefully. slicingCancelled = Signal() ## Perform a slice of the scene. def slice(self): self._stored_layer_data = [] - if not self._enabled: + if not self._enabled: #We shouldn't be slicing. return - if self._slicing: + if self._slicing: #We were already slicing. Stop the old job. self._terminate() - if self._message: - self._message.hide() - self._message = None - - return - - if self._process_layers_job: + if self._process_layers_job: #We were processing layers. Stop that, the layers are going to change soon. self._process_layers_job.abort() self._process_layers_job = None - if self._profile.hasErrorValue(): - Logger.log("w", "Profile has error values. Aborting slicing") - if self._message: - self._message.hide() - self._message = None - self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) - self._message.show() - return #No slicing if we have error values since those are by definition illegal values. + #Don't slice if there is a setting with an error value. + stack = Application.getInstance().getGlobalContainerStack() + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + #Only setting instances have a validation state, so settings which + #are not overwritten by any instance will have none. The property + #then, and only then, evaluates to None. We make the assumption that + #the definition defines the setting with a default value that is + #valid. Therefore we can allow both ValidatorState.Valid and None as + #allowable validation states. + #TODO: This assumption is wrong! If the definition defines an inheritance function that through inheritance evaluates to a disallowed value, a setting is still invalid even though it's default! + #TODO: Therefore we must also validate setting definitions. + if validation_state != None and validation_state != ValidatorState.Valid: + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + if self._message: #Hide any old message before creating a new one. + self._message.hide() + self._message = None + self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) + self._message.show() + return self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NOT_STARTED) if self._message: self._message.setProgress(-1) - #else: - # self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) - # self._message.show() + else: + self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1) + self._message.show() self._scene.gcode_list = [] self._slicing = True @@ -162,10 +169,11 @@ class CuraEngineBackend(Backend): slice_message = self._socket.createMessage("cura.proto.Slice") settings_message = self._socket.createMessage("cura.proto.SettingList"); - self._start_slice_job = StartSliceJob.StartSliceJob(self._profile, slice_message, settings_message) + self._start_slice_job = StartSliceJob.StartSliceJob(slice_message, settings_message) self._start_slice_job.start() self._start_slice_job.finished.connect(self._onStartSliceCompleted) + ## Terminate the engine process. def _terminate(self): self._slicing = False self._restart = True @@ -182,10 +190,21 @@ class CuraEngineBackend(Backend): self._process.terminate() Logger.log("d", "Engine process is killed. Received return code %s", self._process.wait()) self._process = None - #self._createSocket() # Re create the socket except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this. - Logger.log("d", "Exception occured while trying to kill the engine %s", str(e)) + Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e)) + if self._message: + self._message.hide() + self._message = None + + ## Event handler to call when the job to initiate the slicing process is + # completed. + # + # When the start slice job is successfully completed, it will be happily + # slicing. This function handles any errors that may occur during the + # bootstrapping of a slice job. + # + # \param job The start slice job that was just finished. def _onStartSliceCompleted(self, job): # Note that cancelled slice jobs can still call this method. if self._start_slice_job is job: @@ -200,6 +219,11 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(job.getSettingsMessage()) self._socket.sendMessage(job.getSliceMessage()) + ## Listener for when the scene has changed. + # + # This should start a slice if the scene is now ready to slice. + # + # \param source The scene node that was changed. def _onSceneChanged(self, source): if type(source) is not SceneNode: return @@ -215,6 +239,9 @@ class CuraEngineBackend(Backend): self._onChanged() + ## Called when an error occurs in the socket connection towards the engine. + # + # \param error The exception that occurred. def _onSocketError(self, error): if Application.getInstance().isShuttingDown(): return @@ -225,22 +252,23 @@ class CuraEngineBackend(Backend): if error.getErrorCode() not in [Arcus.ErrorCode.BindFailedError, Arcus.ErrorCode.ConnectionResetError, Arcus.ErrorCode.Debug]: Logger.log("e", "A socket error caused the connection to be reset") - def _onActiveProfileChanged(self): - if self._profile: - self._profile.settingValueChanged.disconnect(self._onSettingChanged) - - self._profile = Application.getInstance().getMachineManager().getWorkingProfile() - if self._profile: - self._profile.settingValueChanged.connect(self._onSettingChanged) + ## A setting has changed, so check if we must reslice. + # + # \param instance The setting instance that has changed. + # \param property The property of the setting instance that has changed. + def _onSettingChanged(self, instance, property): + if property == "value": #Only reslice if the value has changed. self._onChanged() - def _onSettingChanged(self, setting): - self._onChanged() - + ## Called when a sliced layer data message is received from the engine. + # + # \param message The protobuf message containing sliced layer data. def _onLayerMessage(self, message): self._stored_layer_data.append(message) - + ## Called when a progress message is received from the engine. + # + # \param message The protobuf message containing the slicing progress. def _onProgressMessage(self, message): if self._message: self._message.setProgress(round(message.amount * 100)) @@ -248,6 +276,9 @@ class CuraEngineBackend(Backend): self.processingProgress.emit(message.amount) self.backendStateChange.emit(BackendState.PROCESSING) + ## Called when the engine sends a message that slicing is finished. + # + # \param message The protobuf message signalling that slicing is finished. def _onSlicingFinishedMessage(self, message): self.backendStateChange.emit(BackendState.DONE) self.processingProgress.emit(1.0) @@ -264,15 +295,27 @@ class CuraEngineBackend(Backend): self._process_layers_job.start() self._stored_layer_data = [] + ## Called when a g-code message is received from the engine. + # + # \param message The protobuf message containing g-code, encoded as UTF-8. def _onGCodeLayerMessage(self, message): self._scene.gcode_list.append(message.data.decode("utf-8", "replace")) + ## Called when a g-code prefix message is received from the engine. + # + # \param message The protobuf message containing the g-code prefix, + # encoded as UTF-8. def _onGCodePrefixMessage(self, message): self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace")) + ## Called when a print time message is received from the engine. + # + # \param message The protobuf message containing the print time and + # material amount. def _onObjectPrintTimeMessage(self, message): self.printDurationMessage.emit(message.time, message.material_amount) + ## Creates a new socket connection. def _createSocket(self): super()._createSocket(os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto"))) @@ -280,28 +323,41 @@ class CuraEngineBackend(Backend): def forceSlice(self): self._change_timer.start() + ## Called when anything has changed to the stuff that needs to be sliced. + # + # This indicates that we should probably re-slice soon. def _onChanged(self): - if not self._profile: - return - self._change_timer.start() + ## Called when the back-end connects to the front-end. def _onBackendConnected(self): if self._restart: self._onChanged() self._restart = False + ## Called when the user starts using some tool. + # + # When the user starts using a tool, we should pause slicing to prevent + # continuously slicing while the user is dragging some tool handle. + # + # \param tool The tool that the user is using. def _onToolOperationStarted(self, tool): self._terminate() # Do not continue slicing once a tool has started self._enabled = False # Do not reslice when a tool is doing it's 'thing' + ## Called when the user stops using some tool. + # + # This indicates that we can safely start slicing again. + # + # \param tool The tool that the user was using. def _onToolOperationStopped(self, tool): self._enabled = True # Tool stop, start listening for changes again. + ## Called when the user changes the active view mode. def _onActiveViewChanged(self): if Application.getInstance().getController().getActiveView(): view = Application.getInstance().getController().getActiveView() - if view.getPluginId() == "LayerView": + if view.getPluginId() == "LayerView": #If switching to layer view, we should process the layers if that hasn't been done yet. self._layer_view_active = True # There is data and we're not slicing at the moment # if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment. @@ -312,9 +368,9 @@ class CuraEngineBackend(Backend): else: self._layer_view_active = False - def _onInstanceChanged(self): - self._terminate() - + ## Called when the back-end self-terminates. + # + # We should reset our state and start listening for new connections. def _onBackendQuit(self): if not self._restart and self._process: Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index 6a947866d3..59feec0fc2 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -62,8 +62,6 @@ class ProcessSlicedLayersJob(Job): self._progress.hide() return - settings = Application.getInstance().getMachineManager().getWorkingProfile() - mesh = MeshData() layer_data = LayerData.LayerData() layer_count = len(self._layers) @@ -132,8 +130,9 @@ class ProcessSlicedLayersJob(Job): new_node.setMeshData(mesh) new_node.setParent(self._scene.getRoot()) # Note: After this we can no longer abort! - if not settings.getSettingValue("machine_center_is_zero"): - new_node.setPosition(Vector(-settings.getSettingValue("machine_width") / 2, 0.0, settings.getSettingValue("machine_depth") / 2)) + settings = Application.getInstance().getGlobalContainerStack() + if not settings.getProperty("machine_center_is_zero", "value"): + new_node.setPosition(Vector(-settings.getProperty("machine_width", "value") / 2, 0.0, settings.getProperty("machine_depth", "value") / 2)) if self._progress: self._progress.setProgress(100) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 174f453bf8..6e0da0cb34 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -30,11 +30,10 @@ class GcodeStartEndFormatter(Formatter): ## Job class that builds up the message of scene data to send to CuraEngine. class StartSliceJob(Job): - def __init__(self, profile, slice_message, settings_message): + def __init__(self, slice_message, settings_message): super().__init__() self._scene = Application.getInstance().getController().getScene() - self._profile = profile self._slice_message = slice_message self._settings_message = settings_message self._is_cancelled = False @@ -45,18 +44,27 @@ class StartSliceJob(Job): def getSliceMessage(self): return self._slice_message + ## Runs the job that initiates the slicing. def run(self): + stack = Application.getInstance().getGlobalContainerStack() + if not stack: + self.setResult(False) + return + with self._scene.getSceneLock(): + # Remove old layer data. for node in DepthFirstIterator(self._scene.getRoot()): if node.callDecoration("getLayerData"): node.getParent().removeChild(node) break + # Get the objects in their groups to print. object_groups = [] - if self._profile.getSettingValue("print_sequence") == "one_at_a_time": + if stack.getProperty("print_sequence", "value") == "one_at_a_time": for node in OneAtATimeIterator(self._scene.getRoot()): temp_list = [] + # Node can't be printed, so don't bother sending it. if getattr(node, "_outside_buildarea", False): continue @@ -85,7 +93,7 @@ class StartSliceJob(Job): if not object_groups: return - self._buildSettingsMessage(self._profile) + self._buildGlobalSettingsMessage(stack) for group in object_groups: group_message = self._slice_message.addRepeatedMessage("object_lists") @@ -97,8 +105,10 @@ class StartSliceJob(Job): obj = group_message.addRepeatedMessage("objects") obj.id = id(object) verts = numpy.array(mesh_data.getVertices()) - verts[:,[1,2]] = verts[:,[2,1]] - verts[:,1] *= -1 + + # Convert from Y up axes to Z up axes. Equals a 90 degree rotation. + verts[:, [1, 2]] = verts[:, [2, 1]] + verts[:, 1] *= -1 obj.vertices = verts @@ -124,18 +134,27 @@ class StartSliceJob(Job): Logger.log("w", "Unabled to do token replacement on start/end gcode %s", traceback.format_exc()) return str(value).encode("utf-8") - def _buildSettingsMessage(self, profile): - settings = profile.getAllSettingValues(include_machine = True) + ## Sends all global settings to the engine. + # + # The settings are taken from the global stack. This does not include any + # per-extruder settings or per-object settings. + def _buildGlobalSettingsMessage(self, stack): + keys = stack.getAllKeys() + settings = {} + for key in keys: + settings[key] = stack.getProperty(key, "value") + start_gcode = settings["machine_start_gcode"] - settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode + settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode #Pre-compute material material_bed_temp_prepend and material_print_temp_prepend settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode - for key, value in settings.items(): - s = self._settings_message.addRepeatedMessage("settings") - s.name = key - if key == "machine_start_gcode" or key == "machine_end_gcode": - s.value = self._expandGcodeTokens(key, value, settings) + + for key, value in settings.items(): #Add all submessages for each individual setting. + setting_message = self._settings_message.addRepeatedMessage("settings") + setting_message.name = key + if key == "machine_start_gcode" or key == "machine_end_gcode": #If it's a g-code message, use special formatting. + setting_message.value = self._expandGcodeTokens(key, value, settings) else: - s.value = str(value).encode("utf-8") + setting_message.value = str(value).encode("utf-8") def _handlePerObjectSettings(self, node, message): profile = node.callDecoration("getProfile") diff --git a/plugins/CuraEngineBackend/__init__.py b/plugins/CuraEngineBackend/__init__.py index 86a53d3ada..2e652ae845 100644 --- a/plugins/CuraEngineBackend/__init__.py +++ b/plugins/CuraEngineBackend/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "name": catalog.i18nc("@label", "CuraEngine Backend"), "author": "Ultimaker", "description": catalog.i18nc("@info:whatsthis", "Provides the link to the CuraEngine slicing backend."), - "api": 2 + "api": 3 } } diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index ee766ef221..d304f0d046 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -1,13 +1,22 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. from UM.Mesh.MeshWriter import MeshWriter from UM.Logger import Logger from UM.Application import Application +from UM.Settings.InstanceContainer import InstanceContainer #To create a complete setting profile to store in the g-code. import re #For escaping characters in the settings. -import copy - +## Writes g-code to a file. +# +# While this poses as a mesh writer, what this really does is take the g-code +# in the entire scene and write it to an output device. Since the g-code of a +# single mesh isn't separable from the rest what with rafts and travel moves +# and all, it doesn't make sense to write just a single mesh. +# +# So this plug-in takes the g-code that is stored in the root of the scene +# node tree, adds a bit of extra information about the profiles and writes +# that to the output device. class GCodeWriter(MeshWriter): ## The file format version of the serialised g-code. # @@ -32,7 +41,7 @@ class GCodeWriter(MeshWriter): def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode): if mode != MeshWriter.OutputMode.TextMode: - Logger.log("e", "GCode Writer does not support non-text mode") + Logger.log("e", "GCode Writer does not support non-text mode.") return False scene = Application.getInstance().getController().getScene() @@ -40,26 +49,30 @@ class GCodeWriter(MeshWriter): if gcode_list: for gcode in gcode_list: stream.write(gcode) - # Serialise the profile and put them at the end of the file. - profile = self._serialiseProfile(Application.getInstance().getMachineManager().getWorkingProfile()) - stream.write(profile) + # Serialise the current container stack and put it at the end of the file. + settings = self._serialiseSettings(Application.getInstance().getGlobalContainerStack()) + stream.write(settings) return True return False - ## Serialises the profile to prepare it for saving in the g-code. + ## Serialises a container stack to prepare it for writing at the end of the + # g-code. # - # The profile are serialised, and special characters (including newline) + # The settings are serialised, and special characters (including newline) # are escaped. # - # \param profile The profile to serialise. - # \return A serialised string of the profile. - def _serialiseProfile(self, profile): + # \param settings A container stack to serialise. + # \return A serialised string of the settings. + def _serialiseSettings(self, settings): prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line. prefix_length = len(prefix) - # Serialise a deepcopy to remove the defaults from the profile - serialised = copy.deepcopy(profile).serialise() + all_settings = InstanceContainer("G-code-imported-profile") #Create a new 'profile' with ALL settings so that the slice can be precisely reproduced. + all_settings.setDefinition(settings.getBottom()) + for key in settings.getAllKeys(): + all_settings.setProperty(key, "value", settings.getProperty(key, "value")) #Just copy everything over to the setting instance. + serialised = all_settings.serialize() # Escape characters that have a special meaning in g-code comments. pattern = re.compile("|".join(GCodeWriter.escape_characters.keys())) diff --git a/plugins/GCodeWriter/__init__.py b/plugins/GCodeWriter/__init__.py index cd8a5d3418..efe3368c61 100644 --- a/plugins/GCodeWriter/__init__.py +++ b/plugins/GCodeWriter/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Writes GCode to a file."), - "api": 2 + "api": 3 }, "mesh_writer": { diff --git a/plugins/LayerView/__init__.py b/plugins/LayerView/__init__.py index 3d43532126..67750fb562 100644 --- a/plugins/LayerView/__init__.py +++ b/plugins/LayerView/__init__.py @@ -14,7 +14,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides the Layer view."), - "api": 2 + "api": 3 }, "view": { "name": catalog.i18nc("@item:inlistbox", "Layers"), diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 3daf360ee6..19154c9c5a 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -9,8 +9,9 @@ import os.path #For concatenating the path to the plugin and the relative path t from UM.Application import Application #To get the machine manager to create the new profile in. from UM.Logger import Logger #Logging errors. from UM.PluginRegistry import PluginRegistry #For getting the path to this plugin's directory. -from UM.Settings.Profile import Profile -from UM.Settings.ProfileReader import ProfileReader +from UM.Settings.DefinitionContainer import DefinitionContainer #For getting the current machine's defaults. +from UM.Settings.InstanceContainer import InstanceContainer #The new profile to make. +from cura.ProfileReader import ProfileReader #The plug-in type to implement. ## A plugin that reads profile data from legacy Cura versions. # @@ -66,7 +67,7 @@ class LegacyProfileReader(ProfileReader): if file_name.split(".")[-1] != "ini": return None Logger.log("i", "Importing legacy profile from file " + file_name + ".") - profile = Profile(machine_manager = Application.getInstance().getMachineManager(), read_only = False) #Create an empty profile. + profile = InstanceContainer("Imported Legacy Profile") #Create an empty profile. parser = configparser.ConfigParser(interpolation = None) try: @@ -103,23 +104,24 @@ class LegacyProfileReader(ProfileReader): if "target_version" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") return None - if Profile.ProfileVersion != dict_of_doom["target_version"]: - Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the profile version (version %s)!", dict_of_doom["target_version"], str(Profile.ProfileVersion)) + if InstanceContainer.Version != dict_of_doom["target_version"]: + Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") return None + current_printer = Application.getInstance().getGlobalContainerStack().findContainer({ }, DefinitionContainer) for new_setting in dict_of_doom["translation"]: #Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval(compiled, {"math": math}, legacy_settings) #Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval(compiled, {"math": math}, defaults) #Evaluate again using only the default values to try to see if they are default. - except Exception as e: #Probably some setting name that was missing or something else that went wrong in the ini file. + except Exception: #Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue - if new_value != value_using_defaults and profile.getSettingValue(new_setting) != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. + if new_value != value_using_defaults and current_printer.findDefinitions(key = new_setting).default_value != new_value: #Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setSettingValue(new_setting, new_value) #Store the setting in the profile! if len(profile.getChangedSettings()) == 0: diff --git a/plugins/LegacyProfileReader/__init__.py b/plugins/LegacyProfileReader/__init__.py index e671f02571..f8b1f5c156 100644 --- a/plugins/LegacyProfileReader/__init__.py +++ b/plugins/LegacyProfileReader/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides support for importing profiles from legacy Cura versions."), - "api": 2 + "api": 3 }, "profile_reader": [ { diff --git a/plugins/PerObjectSettingsTool/PerObjectCategory.qml b/plugins/PerObjectSettingsTool/PerObjectCategory.qml new file mode 100644 index 0000000000..2113a623a0 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectCategory.qml @@ -0,0 +1,29 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.1 as UM + +import ".." + +Button { + id: base; + + style: UM.Theme.styles.sidebar_category; + + signal showTooltip(string text); + signal hideTooltip(); + signal contextMenuRequested() + + text: definition.label + iconSource: UM.Theme.getIcon(definition.icon) + + checkable: true + checked: definition.expanded + + onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) +} diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml new file mode 100644 index 0000000000..d2243ab562 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -0,0 +1,29 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM + +UM.TooltipArea +{ + x: model.depth * UM.Theme.getSize("default_margin").width; + text: model.description; + + width: childrenRect.width; + height: childrenRect.height; + + Button + { + id: check + + text: definition.label + + //onClicked: delegateItem.settingsModel.setSettingVisible(model.key, checked); + } +} + + diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py index 7f7cef049b..cbe22d129e 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py @@ -7,8 +7,8 @@ from UM.Application import Application from UM.Qt.ListModel import ListModel from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Scene.SceneNode import SceneNode -from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator -from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator +#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator +#from UM.Settings.ProfileOverrideDecorator import ProfileOverrideDecorator from . import SettingOverrideModel @@ -35,7 +35,7 @@ class PerObjectSettingsModel(ListModel): self.setProperty(self.find("id", object_id), "profile", profile_name) profile = None - if profile_name != "global": + '''if profile_name != "global": profile = Application.getInstance().getMachineManager().findProfile(profile_name) node = self._scene.findObject(object_id) @@ -45,7 +45,7 @@ class PerObjectSettingsModel(ListModel): node.callDecoration("setProfile", profile) else: if node.getDecorator(ProfileOverrideDecorator): - node.removeDecorator(ProfileOverrideDecorator) + node.removeDecorator(ProfileOverrideDecorator)''' @pyqtSlot("quint64", str) def addSettingOverride(self, object_id, key): @@ -54,8 +54,8 @@ class PerObjectSettingsModel(ListModel): return node = self._scene.findObject(object_id) - if not node.getDecorator(SettingOverrideDecorator): - node.addDecorator(SettingOverrideDecorator()) + #if not node.getDecorator(SettingOverrideDecorator): + # node.addDecorator(SettingOverrideDecorator()) node.callDecoration("addSetting", key) @@ -64,8 +64,8 @@ class PerObjectSettingsModel(ListModel): node = self._scene.findObject(object_id) node.callDecoration("removeSetting", key) - if len(node.callDecoration("getAllSettings")) == 0: - node.removeDecorator(SettingOverrideDecorator) + #if len(node.callDecoration("getAllSettings")) == 0: + # node.removeDecorator(SettingOverrideDecorator) def _updateModel(self): self.clear() diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index c664aeaeef..9b78116d24 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -6,7 +6,10 @@ import QtQuick.Controls 1.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Window 2.2 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura +import ".." + Item { id: base; @@ -133,6 +136,7 @@ Item { id: settingPickDialog title: catalog.i18nc("@title:window", "Pick a Setting to Customize") + property string labelFilter: "" TextField { id: filter; @@ -145,123 +149,61 @@ Item { placeholderText: catalog.i18nc("@label:textbox", "Filter..."); - onTextChanged: settingCategoriesModel.filter(text); + onTextChanged: + { + if(text != "") + { + listview.model.filter = {"global_only": false, "label": "*" + text} + } + else + { + listview.model.filter = {"global_only": false} + } + } } - ScrollView { - id: view; - anchors { + ScrollView + { + id: scrollView + + anchors + { top: filter.bottom; left: parent.left; right: parent.right; bottom: parent.bottom; } + ListView + { + id:listview + model: UM.SettingDefinitionsModel + { + id: definitionsModel; + containerId: Cura.MachineManager.activeDefinitionId + filter: + { + "global_only": false + } + } + delegate:Loader + { + id: loader - Column { - width: view.width - UM.Theme.getSize("default_margin").width * 2; - height: childrenRect.height; + width: parent.width + height: model.type != undefined ? UM.Theme.getSize("section").height : 0; - Repeater { - id: settingList; + property var definition: model + property var settingDefinitionsModel: definitionsModel - model: UM.SettingCategoriesModel { id: settingCategoriesModel; } - - delegate: Item { - id: delegateItem; - - width: parent.width; - height: childrenRect.height; - visible: model.visible && settingsColumn.childrenHeight != 0 //If all children are hidden, the height is 0, and then the category header must also be hidden. - - ToolButton { - id: categoryHeader; - text: model.name; - checkable: true; - width: parent.width; - onCheckedChanged: settingsColumn.state != "" ? settingsColumn.state = "" : settingsColumn.state = "collapsed"; - - style: ButtonStyle { - background: Rectangle - { - width: control.width; - height: control.height; - color: control.hovered ? palette.highlight : "transparent"; - } - label: Row - { - spacing: UM.Theme.getSize("default_margin").width; - Image - { - anchors.verticalCenter: parent.verticalCenter; - source: control.checked ? UM.Theme.getIcon("arrow_right") : UM.Theme.getIcon("arrow_bottom"); - } - Label - { - text: control.text; - font.bold: true; - color: control.hovered ? palette.highlightedText : palette.text; - } - } - } - } - - property variant settingsModel: model.settings; - - Column { - id: settingsColumn; - - anchors.top: categoryHeader.bottom; - - property real childrenHeight: - { - var h = 0.0; - for(var i in children) - { - var item = children[i]; - h += children[i].height; - if(item.settingVisible) - { - if(i > 0) - { - h += spacing; - } - } - } - return h; - } - - width: childrenRect.width; - height: childrenHeight; - Repeater { - model: delegateItem.settingsModel; - - delegate: ToolButton { - id: button; - x: model.visible_depth * UM.Theme.getSize("default_margin").width; - text: model.name; - tooltip: model.description; - visible: !model.global_only - height: model.global_only ? 0 : undefined - - onClicked: { - var object_id = UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id; - UM.ActiveTool.properties.getValue("Model").addSettingOverride(object_id, model.key); - settingPickDialog.visible = false; - } - - states: State { - name: "filtered" - when: model.filtered || !model.visible || !model.enabled - PropertyChanges { target: button; height: 0; opacity: 0; } - } - } - } - - states: State { - name: "collapsed"; - - PropertyChanges { target: settingsColumn; opacity: 0; height: 0; } - } + asynchronous: true + source: + { + switch(model.type) + { + case "category": + return "PerObjectCategory.qml" + default: + return "PerObjectItem.qml" } } } diff --git a/plugins/PerObjectSettingsTool/SettingOverrideModel.py b/plugins/PerObjectSettingsTool/SettingOverrideModel.py index 860650015c..d4bebfdfee 100644 --- a/plugins/PerObjectSettingsTool/SettingOverrideModel.py +++ b/plugins/PerObjectSettingsTool/SettingOverrideModel.py @@ -5,7 +5,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QUrl from UM.Application import Application from UM.Qt.ListModel import ListModel -from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator +#from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator class SettingOverrideModel(ListModel): KeyRole = Qt.UserRole + 1 @@ -29,9 +29,9 @@ class SettingOverrideModel(ListModel): self._node.decoratorsChanged.connect(self._onDecoratorsChanged) self._onDecoratorsChanged(None) - self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes. - self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) - Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged) + #self._activeProfile = Application.getInstance().getMachineManager().getWorkingProfile() #To be able to get notified when a setting changes. + #self._activeProfile.settingValueChanged.connect(self._onProfileSettingValueChanged) + #Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onProfileChanged) self.addRoleName(self.KeyRole, "key") self.addRoleName(self.LabelRole, "label") @@ -53,7 +53,8 @@ class SettingOverrideModel(ListModel): self._decorator.setSettingValue(key, value) def _onDecoratorsChanged(self, node): - if not self._node.getDecorator(SettingOverrideDecorator): + return + '''if not self._node.getDecorator(SettingOverrideDecorator): self.clear() return @@ -61,7 +62,7 @@ class SettingOverrideModel(ListModel): self._decorator.settingAdded.connect(self._onSettingsChanged) self._decorator.settingRemoved.connect(self._onSettingsChanged) self._decorator.settingValueChanged.connect(self._onSettingValueChanged) - self._onSettingsChanged() + self._onSettingsChanged()''' def _createOptionsModel(self, options): if not options: diff --git a/plugins/PerObjectSettingsTool/__init__.py b/plugins/PerObjectSettingsTool/__init__.py index 0d49b2c892..d5d249b430 100644 --- a/plugins/PerObjectSettingsTool/__init__.py +++ b/plugins/PerObjectSettingsTool/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": i18n_catalog.i18nc("@info:whatsthis", "Provides the Per Object Settings."), - "api": 2 + "api": 3 }, "tool": { "name": i18n_catalog.i18nc("@label", "Per Object Settings"), diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index 27859bd145..c6fc277234 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -29,17 +29,26 @@ class RemovableDriveOutputDevice(OutputDevice): if self._writing: raise OutputDeviceError.DeviceBusyError() - file_formats = Application.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() #Formats supported by this application. + # Formats supported by this application (File types that we can actually write) + file_formats = Application.getInstance().getMeshFileHandler().getSupportedFileTypesWrite() if filter_by_machine: - machine_file_formats = Application.getInstance().getMachineManager().getActiveMachineInstance().getMachineDefinition().getFileFormats() - file_formats = list(filter(lambda file_format: file_format["mime_type"] in machine_file_formats, file_formats)) #Take the intersection between file_formats and machine_file_formats. + container = Application.getInstance().getGlobalContainerStack().findContainer({"file_formats": "*"}) + + # Create a list from supported file formats string + machine_file_formats = [file_type.strip() for file_type in container.getMetaDataEntry("file_formats").split(";")] + + # Take the intersection between file_formats and machine_file_formats. + file_formats = list(filter(lambda file_format: file_format["mime_type"] in machine_file_formats, file_formats)) + if len(file_formats) == 0: Logger.log("e", "There are no file formats available to write with!") raise OutputDeviceError.WriteRequestFailedError() - writer = Application.getInstance().getMeshFileHandler().getWriterByMimeType(file_formats[0]["mime_type"]) #Just take the first file format available. + + # Just take the first file format available. + writer = Application.getInstance().getMeshFileHandler().getWriterByMimeType(file_formats[0]["mime_type"]) extension = file_formats[0]["extension"] - if file_name == None: + if file_name is None: for n in BreadthFirstIterator(node): if n.getMeshData(): file_name = n.getName() @@ -50,7 +59,7 @@ class RemovableDriveOutputDevice(OutputDevice): Logger.log("e", "Could not determine a proper file name when trying to write to %s, aborting", self.getName()) raise OutputDeviceError.WriteRequestFailedError() - if extension: #Not empty string. + if extension: # Not empty string. extension = "." + extension file_name = os.path.join(self.getId(), os.path.splitext(file_name)[0] + extension) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 8719e9c6e4..71b29c8186 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -34,12 +34,10 @@ class SolidView(View): self._disabled_shader.setUniformValue("u_diffuseColor", [0.68, 0.68, 0.68, 1.0]) self._disabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) - if Application.getInstance().getMachineManager().getWorkingProfile(): - profile = Application.getInstance().getMachineManager().getWorkingProfile() - + if Application.getInstance().getGlobalContainerStack(): if Preferences.getInstance().getValue("view/show_overhang"): - angle = profile.getSettingValue("support_angle") - if angle != None: + angle = Application.getInstance().getGlobalContainerStack().getProperty("support_angle", "value") + if angle is not None: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle))) else: self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang. diff --git a/plugins/SolidView/__init__.py b/plugins/SolidView/__init__.py index 0317648e6e..945ccba8f6 100644 --- a/plugins/SolidView/__init__.py +++ b/plugins/SolidView/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": i18n_catalog.i18nc("@info:whatsthis", "Provides a normal solid mesh view."), - "api": 2 + "api": 3 }, "view": { "name": i18n_catalog.i18nc("@item:inmenu", "Solid"), diff --git a/plugins/XRayView/__init__.py b/plugins/XRayView/__init__.py index 277dc69b92..34e4761863 100644 --- a/plugins/XRayView/__init__.py +++ b/plugins/XRayView/__init__.py @@ -13,7 +13,7 @@ def getMetaData(): "author": "Ultimaker", "version": "1.0", "description": catalog.i18nc("@info:whatsthis", "Provides the X-Ray view."), - "api": 2 + "api": 3 }, "view": { "name": catalog.i18nc("@item:inlistbox", "X-Ray"), diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py new file mode 100644 index 0000000000..50c39238fd --- /dev/null +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -0,0 +1,135 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import math +import copy +import xml.etree.ElementTree as ET + +from UM.Logger import Logger + +import UM.Settings + +# The namespace is prepended to the tag name but between {}. +# We are only interested in the actual tag name, so discard everything +# before the last } +def _tag_without_namespace(element): + return element.tag[element.tag.rfind("}") + 1:] + +class XmlMaterialProfile(UM.Settings.InstanceContainer): + def __init__(self, container_id, *args, **kwargs): + super().__init__(container_id, *args, **kwargs) + + def serialize(self): + raise NotImplementedError("Writing material profiles has not yet been implemented") + + def deserialize(self, serialized): + data = ET.fromstring(serialized) + + self.addMetaDataEntry("type", "material") + + # TODO: Add material verfication + self.addMetaDataEntry("status", "Unknown") + + metadata = data.iterfind("./um:metadata/*", self.__namespaces) + for entry in metadata: + tag_name = _tag_without_namespace(entry) + + if tag_name == "name": + brand = entry.find("./um:brand", self.__namespaces) + material = entry.find("./um:material", self.__namespaces) + color = entry.find("./um:color", self.__namespaces) + + self.setName("{0} {1} ({2})".format(brand.text, material.text, color.text)) + + self.addMetaDataEntry("brand", brand.text) + self.addMetaDataEntry("material", material.text) + self.addMetaDataEntry("color_name", color.text) + + self.addMetaDataEntry(tag_name, entry.text) + + property_values = {} + properties = data.iterfind("./um:properties/*", self.__namespaces) + for entry in properties: + tag_name = _tag_without_namespace(entry) + property_values[tag_name] = entry.text + + diameter = float(property_values.get("diameter", 2.85)) # In mm + density = float(property_values.get("density", 1.3)) # In g/cm3 + + weight_per_cm = (math.pi * (diameter / 20) ** 2 * 0.1) * density + + spool_weight = property_values.get("spool_weight") + spool_length = property_values.get("spool_length") + if spool_weight: + length = float(spool_weight) / weight_per_cm + property_values["spool_length"] = str(length / 100) + elif spool_length: + weight = (float(spool_length) * 100) * weight_per_cm + property_values["spool_weight"] = str(weight) + + self.addMetaDataEntry("properties", property_values) + + global_setting_values = {} + settings = data.iterfind("./um:settings/um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_property_setting_map: + self.setProperty(self.__material_property_setting_map[key], "value", entry.text, self._definition) + global_setting_values[key] = entry.text + + machines = data.iterfind("./um:settings/um:machine", self.__namespaces) + for machine in machines: + machine_setting_values = {} + settings = machine.iterfind("./um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_property_setting_map: + machine_setting_values[self.__material_property_setting_map[key]] = entry.text + + identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces) + for identifier in identifiers: + machine_id = self.__product_id_map.get(identifier.get("product"), None) + if machine_id is None: + Logger.log("w", "Cannot create material for unknown machine %s", machine_id) + continue + + definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id) + if not definitions: + Logger.log("w", "No definition found for machine ID %s", machine_id) + continue + + new_material = XmlMaterialProfile(self.id + "_" + machine_id) + new_material.setName(self.getName()) + new_material.setMetaData(self.getMetaData()) + new_material.setDefinition(definitions[0]) + + for key, value in global_setting_values.items(): + new_material.setProperty(key, "value", value, definitions[0]) + + for key, value in machine_setting_values.items(): + new_material.setProperty(key, "value", value, definitions[0]) + + new_material._dirty = False + + UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) + + + __material_property_setting_map = { + "print temperature": "material_print_temperature", + "heated bed temperature": "material_bed_temperature", + "standby temperature": "material_standby_temperature", + } + + __product_id_map = { + "Ultimaker2": "ultimaker2", + "Ultimaker2+": "ultimaker2_plus", + "Ultimaker2go": "ultimaker2_go", + "Ultimaker2extended": "ultimaker2_extended", + "Ultimaker2extended+": "ultimaker2_extended_plus", + "Ultimaker Original": "ultimaker_original", + "Ultimaker Original+": "ultimaker_original_plus" + } + + __namespaces = { + "um": "http://www.ultimaker.com/material" + } diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py new file mode 100644 index 0000000000..041a3f6346 --- /dev/null +++ b/plugins/XmlMaterialProfile/__init__.py @@ -0,0 +1,32 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from . import XmlMaterialProfile + +from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + +def getMetaData(): + return { + "plugin": { + "name": catalog.i18nc("@label", "Material Profiles"), + "author": "Ultimaker", + "version": "1.0", + "description": catalog.i18nc("@info:whatsthis", "Provides capabilities to read and write XML-based material profiles."), + "api": 3 + }, + "settings_container": { + "mimetype": "application/x-ultimaker-material-profile" + } + } + +def register(app): + mime_type = MimeType( + name = "application/x-ultimaker-material-profile", + comment = "Ultimaker Material Profile", + suffixes = [ "xml.fdm_material" ] + ) + MimeTypeDatabase.addMimeType(mime_type) + return { "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile") } + diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json new file mode 100644 index 0000000000..65d6fc38a3 --- /dev/null +++ b/resources/definitions/bq_hephestos.def.json @@ -0,0 +1,93 @@ +{ + "id": "bq_hephestos", + "name": "BQ Prusa i3 Hephestos", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "bq_hephestos_platform.stl", + "platform_offset": { + "value": [ + 0, + -82, + 0 + ] + } + }, + + "overrides": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 215 + }, + "machine_depth": { + "default_value": 210 + }, + "machine_height": { + "default_value": 180 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "layer_height": { + "default_value": 0.2 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1 + }, + "top_bottom_thickness": { + "default_value": 1 + }, + "bottom_thickness": { + "default_value": 1 + }, + "material_print_temperature": { + "default_value": 220 + }, + "material_bed_temperature": { + "default_value": 0 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + } + } +} \ No newline at end of file diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json new file mode 100644 index 0000000000..8afd4135f1 --- /dev/null +++ b/resources/definitions/bq_hephestos_2.def.json @@ -0,0 +1,47 @@ +{ + "id": "bq_hephestos_2", + "version": 2, + "name": "BQ Hephestos 2", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "platform": "bq_hephestos_2_platform.stl", + "platform_offset": { "value": [6, 1320, 0 ] }, + "file_formats": "text/x-gcode" + }, + + "overrides": { + "machine_start_gcode": { "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" }, + "machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" }, + "machine_width": { "default_value": 210 }, + "machine_depth": { "default_value": 297 }, + "machine_height": { "default_value": 220 }, + "machine_heated_bed": { "default_value": false }, + "machine_center_is_zero": { "default_value": false }, + "material_print_temperature": { "default_value": 210 }, + "material_bed_temperature": { "default_value": 0 }, + "material_diameter": { "default_value": 1.75 }, + "layer_height": { "default_value": 0.2 }, + "layer_height_0": { "default_value": 0.2 }, + "wall_line_count": { "default_value": 3 }, + "wall_thickness": { "default_value": 1.2 }, + "top_bottom_thickness": { "default_value": 1.2 }, + "infill_sparse_density": { "default_value": 20 }, + "infill_overlap": { "default_value": 15 }, + "speed_print": { "default_value": 60 }, + "speed_travel": { "default_value": 160 }, + "speed_layer_0": { "default_value": 30 }, + "speed_wall_x": { "default_value": 35 }, + "speed_wall_0": { "default_value": 30 }, + "speed_infill": { "default_value": 80 }, + "speed_topbottom": { "default_value": 35 }, + "skirt_speed": { "default_value": 35 }, + "skirt_line_count": { "default_value": 4 }, + "skirt_minimal_length": { "default_value": 30 }, + "skirt_gap": { "default_value": 6 }, + "cool_fan_full_at_height": { "default_value": 0.4 } + } +} diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json new file mode 100644 index 0000000000..9cf5b685db --- /dev/null +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -0,0 +1,93 @@ +{ + "id": "bq_hephestos_xl", + "version": 2, + "name": "BQ Prusa i3 Hephestos XL", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "manufacturer": "BQ", + "author": "BQ", + "category": "Other", + "file_formats": "text/x-code", + "platform": "bq_hephestos_platform.stl", + "platform_offset": { + "value": [ + 0, + -82, + 0 + ] + } + }, + + "overrides": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_height": { + "default_value": 180 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "layer_height": { + "default_value": 0.2 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1 + }, + "top_bottom_thickness": { + "default_value": 1 + }, + "bottom_thickness": { + "default_value": 1 + }, + "material_print_temperature": { + "default_value": 220 + }, + "material_bed_temperature": { + "default_value": 0 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + } + } +} \ No newline at end of file diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json new file mode 100644 index 0000000000..77826a1576 --- /dev/null +++ b/resources/definitions/bq_witbox.def.json @@ -0,0 +1,94 @@ +{ + "id": "bq_witbox", + "version": 2, + "name": "BQ Witbox", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "bq_witbox_platform.stl", + "platform_offset": { + "value": [ + 0, + -145, + -38 + ] + } + }, + + "overrides": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 297 + }, + "machine_depth": { + "default_value": 210 + }, + "machine_height": { + "default_value": 200 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "layer_height": { + "default_value": 0.2 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 1 + }, + "top_bottom_thickness": { + "default_value": 1 + }, + "bottom_thickness": { + "default_value": 1 + }, + "material_print_temperature": { + "default_value": 220 + }, + "material_bed_temperature": { + "default_value": 0 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 40 + }, + "speed_infill": { + "default_value": 40 + }, + "speed_wall": { + "default_value": 35 + }, + "speed_topbottom": { + "default_value": 35 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "support_enable": { + "default_value": true + } + + } +} \ No newline at end of file diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json new file mode 100644 index 0000000000..b9d9b497cd --- /dev/null +++ b/resources/definitions/bq_witbox_2.def.json @@ -0,0 +1,111 @@ +{ + "id": "bq_witbox_2", + "version": 2, + "name": "BQ Witbox 2", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "BQ", + "manufacturer": "BQ", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "bq_witbox_platform.stl", + "platform_offset": [0, -145, -38] + }, + + "overrides": { + "machine_start_gcode": { + "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" + }, + "machine_end_gcode": { + "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" + }, + "machine_width": { + "default_value": 297 + }, + "machine_depth": { + "default_value": 210 + }, + "machine_height": { + "default_value": 200 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "material_print_temperature": { + "default_value": 210 + }, + "material_bed_temperature": { + "default_value": 0 + }, + "material_diameter": { + "default_value": 1.75 + }, + "layer_height": { + "default_value": 0.2 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_line_count": { + "default_value": 3 + }, + "wall_thickness": { + "default_value": 1.2 + }, + "top_bottom_thickness": { + "default_value": 1.2 + }, + "infill_sparse_density": { + "default_value": 20 + }, + "infill_overlap": { + "default_value": 15 + }, + "speed_print": { + "default_value": 60 + }, + "speed_travel": { + "default_value": 160 + }, + "speed_layer_0": { + "default_value": 30 + }, + "speed_wall_x": { + "default_value": 35 + }, + "speed_wall_0": { + "default_value": 30 + }, + "speed_infill": { + "default_value": 80 + }, + "speed_topbottom": { + "default_value": 35 + }, + "skirt_speed": { + "default_value": 35 + }, + "skirt_line_count": { + "default_value": 4 + }, + "skirt_minimal_length": { + "default_value": 30 + }, + "skirt_gap": { + "default_value": 6 + }, + "cool_fan_full_at_height": { + "default_value": 0.4 + }, + "support_enable": { + "default_value": false + } + } +} \ No newline at end of file diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json new file mode 100644 index 0000000000..150fbbdffc --- /dev/null +++ b/resources/definitions/fdmprinter.def.json @@ -0,0 +1,2900 @@ +{ + "id": "fdmprinter", + "name": "FDM Printer Base Description", + "version": 2, + "metadata": + { + "author": "Ultimaker B.V.", + "category": "Ultimaker", + "manufacturer": "Ultimaker", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", + "visible": false, + "preferred_material": "pla", + "preferred_quality": "normal" + }, + "settings": + { + "machine_settings": + { + "label": "Machine", + "type": "category", + "description": "Machine specific settings", + "children": + { + "machine_show_variants": + { + "description": "Whether to show the different variants of this machine, which are described in separate json files.", + "default_value": false, + "type": "bool", + "label": "Show machine variants" + }, + "machine_start_gcode": + { + "description": "Gcode commands to be executed at the very start - separated by \\n.", + "default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0", + "label": "Start GCode", + "global_only": true, + "type": "str" + }, + "machine_end_gcode": + { + "description": "Gcode commands to be executed at the very end - separated by \\n.", + "default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84", + "label": "End GCode", + "global_only": true, + "type": "str" + }, + "material_bed_temp_wait": + { + "description": "Whether to insert a command to wait until the bed temperature is reached at the start.", + "label": "Wait for bed heatup", + "default_value": true, + "global_only": true, + "type": "bool" + }, + "material_print_temp_prepend": + { + "description": "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting.", + "default_value": true, + "global_only": true, + "type": "bool", + "label": "Wait for material heatup" + }, + "machine_width": + { + "description": "The width (X-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine width" + }, + "machine_depth": + { + "description": "The depth (Y-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine depth" + }, + "machine_height": + { + "description": "The height (Z-direction) of the printable area.", + "default_value": 100, + "global_only": true, + "type": "float", + "label": "Machine height" + }, + "machine_heated_bed": + { + "description": "Whether the machine has a heated bed present.", + "default_value": false, + "global_only": true, + "label": "Has heated bed", + "type": "bool" + }, + "machine_center_is_zero": + { + "description": "Whether the X/Y coordinates of the zero position of the printer is at the center of the printable area.", + "default_value": false, + "global_only": true, + "type": "bool", + "label": "Is center origin" + }, + "machine_extruder_count": + { + "description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.", + "default_value": 1, + "global_only": true, + "type": "bool", + "label": "Number extruders" + }, + "machine_nozzle_tip_outer_diameter": + { + "description": "The outer diameter of the tip of the nozzle.", + "label": "Outer nozzle diameter", + "default_value": 1, + "global_only": true, + "type": "float" + }, + "machine_nozzle_head_distance": + { + "description": "The height difference between the tip of the nozzle and the lowest part of the print head.", + "default_value": 3, + "global_only": true, + "type": "float", + "label": "Nozzle length" + }, + "machine_nozzle_expansion_angle": + { + "description": "The angle between the horizontal plane and the conical part right above the tip of the nozzle.", + "default_value": 45, + "global_only": true, + "type": "int", + "label": "Nozzle angle" + }, + "machine_heat_zone_length": + { + "description": "The distance from the tip of the nozzle in which heat from the nozzle is transfered to the filament.", + "default_value": 16, + "global_only": true, + "type": "float", + "label": "Heat zone length" + }, + "machine_nozzle_heat_up_speed": + { + "description": "The speed (°C/s) by which the nozzle heats up averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Heat up speed" + }, + "machine_nozzle_cool_down_speed": + { + "description": "The speed (°C/s) by which the nozzle cools down averaged over the window of normal printing temperatures and the standby temperature.", + "default_value": 2.0, + "global_only": true, + "type": "float", + "label": "Cool down speed" + }, + "machine_gcode_flavor": + { + "description": "The type of gcode to be generated.", + "default_value": "RepRap", + "global_only": true, + "type": "str", + "label": "Gcode flavour" + }, + "machine_disallowed_areas": + { + "description": "A list of polygons with areas the print head is not allowed to enter.", + "type": "polygons", + "default_value": [], + "global_only": true, + "label": "Disallowed areas" + }, + "machine_head_polygon": + { + "description": "A 2D silhouette of the print head (fan caps excluded).", + "type": "polygon", + "default_value": + [ + [ + -1, + 1 + ], + [ + -1, + -1 + ], + [ + 1, + -1 + ], + [ + 1, + 1 + ] + ], + "global_only": true, + "label": "Machine head polygon" + }, + "machine_head_with_fans_polygon": + { + "description": "A 2D silhouette of the print head (fan caps included).", + "type": "polygon", + "default_value": + [ + [ + -20, + 10 + ], + [ + 10, + 10 + ], + [ + 10, + -10 + ], + [ + -20, + -10 + ] + ], + "global_only": true, + "label": "Machine head & Fan polygon" + }, + "gantry_height": + { + "description": "The height difference between the tip of the nozzle and the gantry system (X and Y axes).", + "default_value": 99999999999, + "global_only": true, + "label": "Gantry height", + "type": "float" + }, + "machine_nozzle_size": + { + "label": "Nozzle Diameter", + "description": "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0.001", + "maximum_value_warning": "10" + }, + "machine_nozzle_offset_x": + { + "label": "Nozzle X Offset", + "description": "The x-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_nozzle_offset_y": + { + "label": "Nozzle Y Offset", + "description": "The y-coordinate of the offset of the nozzle.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_code": + { + "label": "Extruder Start G-Code", + "description": "Start g-code to execute whenever turning the extruder on.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_start_pos_abs": + { + "label": "Extruder Start Position Absolute", + "description": "Make the extruder starting position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_start_pos_x": + { + "label": "Extruder Start Position X", + "description": "The x-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_start_pos_y": + { + "label": "Extruder Start Position Y", + "description": "The y-coordinate of the starting position when turning the extruder on.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_code": + { + "label": "Extruder End G-Code", + "description": "End g-code to execute whenever turning the extruder off.", + "type": "str", + "default_value": "", + "global_only": "True" + }, + "machine_extruder_end_pos_abs": + { + "label": "Extruder End Position Absolute", + "description": "Make the extruder ending position absolute rather than relative to the last-known location of the head.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "machine_extruder_end_pos_x": + { + "label": "Extruder End Position X", + "description": "The x-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_extruder_end_pos_y": + { + "label": "Extruder End Position Y", + "description": "The y-coordinate of the ending position when turning the extruder off.", + "type": "float", + "unit": "mm", + "default_value": 0, + "global_only": "True" + }, + "machine_use_extruder_offset_to_offset_coords": + { + "label": "Offset With Extruder", + "description": "Apply the extruder offset to the coordinate system.", + "type": "bool", + "default_value": true + } + } + }, + "resolution": + { + "label": "Quality", + "type": "category", + "icon": "category_layer_height", + "description": "All settings that influence the resolution of the print. These settings have a large impact on the quality (and print time)", + "children": + { + "layer_height": + { + "label": "Layer Height", + "description": "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "layer_height_0": + { + "label": "Initial Layer Height", + "description": "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.001", + "minimum_value_warning": "0.04", + "maximum_value_warning": "0.8 * machine_nozzle_size", + "global_only": "True" + }, + "line_width": + { + "label": "Line Width", + "description": "Width of a single line. Generally, the width of each line should correspond to the width of the nozzle. However, slightly reducing this value could produce better prints.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "2 * machine_nozzle_size", + "default_value": 0.4, + "type": "float", + "value": "machine_nozzle_size", + "children": + { + "wall_line_width": + { + "label": "Wall Line Width", + "description": "Width of a single wall line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "value":"line_width", + "default_value": 0.4, + "type": "float", + "children": + { + "wall_line_width_0": + { + "label": "Outer Wall Line Width", + "description": "Width of the outermost wall line. By lowering this value, higher levels of detail can be printed.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "value":"wall_line_width", + "type": "float" + }, + "wall_line_width_x": + { + "label": "Inner Wall(s) Line Width", + "description": "Width of a single wall line for all wall lines except the outermost one.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "value":"wall_line_width", + "type": "float" + } + } + }, + "skin_line_width": + { + "label": "Top/bottom Line Width", + "description": "Width of a single top/bottom line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "value": "line_width" + }, + "infill_line_width": + { + "label": "Infill Line Width", + "description": "Width of a single infill line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "value": "line_width" + }, + "skirt_line_width": + { + "label": "Skirt Line Width", + "description": "Width of a single skirt line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "global_only": true, + "value": "line_width" + }, + "support_line_width": + { + "label": "Support Line Width", + "description": "Width of a single support structure line.", + "unit": "mm", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "default_value": 0.4, + "type": "float", + "enabled": "support_enable", + "global_only": true, + "value": "line_width" + }, + "support_roof_line_width": + { + "label": "Support Roof Line Width", + "description": "Width of a single support roof line.", + "unit": "mm", + "default_value": 0.4, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "type": "float", + "enabled": "support_roof_enable", + "global_only": true, + "value": "line_width" + }, + "prime_tower_line_width": + { + "label": "Prime Tower Line Width", + "description": "Width of a single prime tower line.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 0.4, + "value": "line_width", + "minimum_value": "0.0001", + "minimum_value_warning": "0.2", + "maximum_value_warning": "5", + "global_only": "True" + } + } + } + } + }, + "shell": + { + "label": "Shell", + "icon": "category_shell", + "description": "Shell", + "type": "category", + "children": + { + "wall_thickness": + { + "label": "Wall Thickness", + "description": "The thickness of the outside walls in the horizontal direction. This value divided by the wall line width defines the number of walls.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "minimum_value_warning": "line_width", + "maximum_value_warning": "5 * line_width", + "type": "float", + "children": + { + "wall_line_count": + { + "label": "Wall Line Count", + "description": "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number.", + "default_value": 2, + "minimum_value": "0", + "type": "int", + "value": "1 if magic_spiralize else max(1, round((wall_thickness - wall_line_width_0) / wall_line_width_x) + 1)" + } + } + }, + "top_bottom_thickness": + { + "label": "Top/Bottom Thickness", + "description": "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value": "5", + "minimum_value_warning": "0.6", + "type": "float", + "children": + { + "top_thickness": + { + "label": "Top Thickness", + "description": "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers.", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "value": "top_bottom_thickness", + "children": + { + "top_layers": + { + "label": "Top Layers", + "description": "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number.", + "default_value": 8, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / layer_height, 4))" + } + } + }, + "bottom_thickness": + { + "label": "Bottom Thickness", + "description": "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers.", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "type": "float", + "value": "top_bottom_thickness", + "children": + { + "bottom_layers": + { + "label": "Bottom Layers", + "description": "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number.", + "minimum_value": "0", + "default_value": 6, + "type": "int", + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / layer_height, 4))" + } + } + } + } + }, + "top_bottom_pattern": + { + "label": "Top/Bottom Pattern", + "description": "The pattern of the top/bottom layers.", + "type": "enum", + "options": + { + "lines": "Lines", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "lines" + }, + "wall_0_inset": + { + "label": "Outer Wall Inset", + "description": "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the object.", + "unit": "mm", + "type": "float", + "default_value": 0.0, + "value": "(machine_nozzle_size - wall_line_width_0) / 2 if wall_line_width_0 < machine_nozzle_size else 0", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "alternate_extra_perimeter": + { + "label": "Alternate Extra Wall", + "description": "Prints an extra wall at every other layer. This way infill gets caught between these extra walls, resulting in stronger prints.", + "type": "bool", + "default_value": false + }, + "travel_compensate_overlapping_walls_enabled": + { + "label": "Compensate Wall Overlaps", + "description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.", + "type": "bool", + "default_value": true, + "children": + { + "travel_compensate_overlapping_walls_0_enabled": { + "label": "Compensate Outer Wall Overlaps", + "description": "Compensate the flow for parts of an outer wall being printed where there is already a wall in place.", + "type": "bool", + "default_value": true, + "value": "travel_compensate_overlapping_walls_enabled" + }, + "travel_compensate_overlapping_walls_x_enabled": { + "label": "Compensate Inner Wall Overlaps", + "description": "Compensate the flow for parts of an inner wall being printed where there is already a wall in place.", + "type": "bool", + "default_value": true, + "value": "travel_compensate_overlapping_walls_enabled" + } + } + }, + "xy_offset": + { + "label": "Horizontal Expansion", + "description": "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes.", + "unit": "mm", + "type": "float", + "minimum_value_warning": "-10", + "maximum_value_warning": "10", + "default_value": 0 + }, + "z_seam_type": + { + "label": "Z Seam Alignment", + "description": "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these at the back, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker.", + "type": "enum", + "options": + { + "back": "Back", + "shortest": "Shortest", + "random": "Random" + }, + "default_value": "shortest" + }, + "skin_no_small_gaps_heuristic": + { + "label": "Ignore Small Z Gaps", + "description": "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting.", + "type": "bool", + "default_value": true + } + } + }, + "infill": + { + "label": "Infill", + "icon": "category_infill", + "description": "Infill", + "type": "category", + "children": + { + "infill_sparse_density": + { + "label": "Infill Density", + "description": "Adjusts the density of infill of the print.", + "unit": "%", + "type": "float", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "100", + "children": + { + "infill_line_distance": + { + "label": "Infill Line Distance", + "description": "Distance between the printed infill lines. This setting is calculated by the infill density and the infill line width.", + "unit": "mm", + "type": "float", + "default_value": 2, + "minimum_value": "0", + "value": "0 if infill_sparse_density == 0 else (infill_line_width * 100) / infill_sparse_density * (2 if infill_pattern == \"grid\" else (3 if infill_pattern == \"triangles\" else 1))" + } + } + }, + "infill_pattern": + { + "label": "Infill Pattern", + "description": "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle and concentric patterns are fully printed every layer.", + "type": "enum", + "options": + { + "grid": "Grid", + "lines": "Lines", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "grid", + "value": "'lines' if infill_sparse_density > 25 else 'grid'" + }, + "infill_overlap": + { + "label": "Infill Overlap Percentage", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "%", + "type": "float", + "default_value": 10, + "value": "10 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0", + "minimum_value_warning": "-50", + "maximum_value_warning": "100", + "enabled": "infill_pattern != 'concentric'", + "children": + { + "infill_overlap_mm": + { + "label": "Infill Overlap", + "description": "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "minimum_value_warning": "-0.5 * machine_nozzle_size", + "maximum_value_warning": "machine_nozzle_size", + "value": "infill_line_width * infill_overlap / 100 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0", + "enabled": "infill_pattern != 'concentric'" + } + } + }, + "skin_overlap": { + "label": "Skin Overlap Percentage", + "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", + "unit": "%", + "type": "float", + "default_value": 5, + "minimum_value_warning": "-50", + "maximum_value_warning": "100", + "value": "5 if top_bottom_pattern != 'concentric' else 0", + "enabled": "top_bottom_pattern != 'concentric'", + "children": { + "skin_overlap_mm": { + "label": "Skin Overlap", + "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", + "unit": "mm", + "type": "float", + "default_value": 0.02, + "minimum_value_warning": "-0.5 * machine_nozzle_size", + "maximum_value_warning": "machine_nozzle_size", + "value": "skin_line_width * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0", + "enabled": "top_bottom_pattern != 'concentric'" + } + } + }, + "infill_wipe_dist": + { + "label": "Infill Wipe Distance", + "description": "Distance of a travel move inserted after every infill line, to make the infill stick to the walls better. This option is similar to infill overlap, but without extrusion and only on one end of the infill line.", + "unit": "mm", + "type": "float", + "default_value": 0.04, + "value": "wall_line_width_0 / 4 if wall_line_count == 1 else wall_line_width_x / 4", + "minimum_value_warning": "0", + "maximum_value_warning": "machine_nozzle_size" + }, + "infill_sparse_thickness": + { + "label": "Infill Layer Thickness", + "description": "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0.0001", + "maximum_value_warning": "0.32", + "maximum_value": "layer_height * 8", + "value": "layer_height" + }, + "infill_before_walls": + { + "label": "Infill Before Walls", + "description": "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface.", + "type": "bool", + "default_value": true + } + } + }, + "material": + { + "label": "Material", + "icon": "category_material", + "description": "Material", + "type": "category", + "children": + { + "material_flow_dependent_temperature": + { + "label": "Auto Temperature", + "description": "Change the temperature for each layer automatically with the average flow speed of that layer.", + "type": "bool", + "default_value": false, + "enabled": "False", + "global_only": true + }, + "material_print_temperature": + { + "label": "Printing Temperature", + "description": "The temperature used for printing. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 210, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "not (material_flow_dependent_temperature)" + }, + "material_flow_temp_graph": + { + "label": "Flow Temperature Graph", + "description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).", + "unit": "", + "type": "str", + "default_value": "[[3.5,200],[7.0,240]]", + "enabled": "False", + "comments": "old enabled function: material_flow_dependent_temperature", + "global_only": true + }, + "material_extrusion_cool_down_speed": { + "label": "Extrusion Cool Down Speed Modifier", + "description": "The extra speed by which the nozzle cools while extruding. The same value is used to signify the heat up speed lost when heating up while extruding.", + "unit": "°C/s", + "type": "float", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "enabled": "False", + "comments": "old enabled function: material_flow_dependent_temperature or machine_extruder_count > 1" + }, + "material_bed_temperature": { + "label": "Bed Temperature", + "description": "The temperature used for the heated bed. Set at 0 to pre-heat the printer manually.", + "unit": "°C", + "type": "float", + "default_value": 60, + "minimum_value": "0", + "maximum_value_warning": "260", + "enabled": "machine_heated_bed", + "global_only": "True" + }, + "material_diameter": { + "label": "Diameter", + "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", + "unit": "mm", + "type": "float", + "default_value": 2.85, + "minimum_value": "0.0001", + "minimum_value_warning": "0.4", + "maximum_value_warning": "3.5", + "global_only": "True" + }, + "material_flow": { + "label": "Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value.", + "unit": "%", + "default_value": 100, + "type": "float", + "minimum_value": "5", + "minimum_value_warning": "50", + "maximum_value_warning": "150" + }, + "retraction_enable": { + "label": "Enable Retraction", + "description": "Retract the filament when the nozzle is moving over a non-printed area. ", + "type": "bool", + "default_value": true + }, + "retraction_amount": { + "label": "Retraction Distance", + "description": "The length of material retracted during a retraction move.", + "unit": "mm", + "type": "float", + "default_value": 6.5, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10.0", + "enabled": "retraction_enable" + }, + "retraction_speed": { + "label": "Retraction Speed", + "description": "The speed at which the filament is retracted and primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "children": { + "retraction_retract_speed": { + "label": "Retraction Retract Speed", + "description": "The speed at which the filament is retracted during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "value": "retraction_speed" + }, + "retraction_prime_speed": { + "label": "Retraction Prime Speed", + "description": "The speed at which the filament is primed during a retraction move.", + "unit": "mm/s", + "type": "float", + "default_value": 25, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "retraction_enable", + "value": "retraction_speed" + } + } + }, + "retraction_extra_prime_amount": { + "label": "Retraction Extra Prime Amount", + "description": "Some material can ooze away during a travel move, which can be compensated for here.", + "unit": "mm³", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "5.0", + "enabled": "retraction_enable" + }, + "retraction_min_travel": { + "label": "Retraction Minimum Travel", + "description": "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area.", + "unit": "mm", + "type": "float", + "default_value": 1.5, + "value": "line_width * 2", + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "retraction_enable" + }, + "retraction_count_max": { + "label": "Maximum Retraction Count", + "description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.", + "default_value": 45, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "int", + "enabled": "retraction_enable" + }, + "retraction_extrusion_window": { + "label": "Minimum Extrusion Distance Window", + "description": "The window in which the maximum retraction count is enforced. This value should be approximately the same as the retraction distance, so that effectively the number of times a retraction passes the same patch of material is limited.", + "unit": "mm", + "type": "float", + "default_value": 4.5, + "minimum_value": "0", + "maximum_value_warning": "retraction_amount * 2", + "value": "retraction_amount", + "enabled": "retraction_enable" + }, + "retraction_hop": { + "label": "Z Hop when Retracting", + "description": "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.", + "unit": "mm", + "type": "float", + "default_value": 0, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10", + "enabled": "retraction_enable" + }, + "material_standby_temperature": + { + "label": "Standby Temperature", + "description": "The temperature of the nozzle when another nozzle is currently used for printing.", + "type": "float", + "unit": "°C", + "default_value": 150, + "minimum_value": "0", + "maximum_value_warning": "260", + "global_only": "True" + }, + "switch_extruder_retraction_amount": + { + "label": "Nozzle Switch Retraction Distance", + "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", + "type": "float", + "unit": "mm", + "enabled": "retraction_enable", + "default_value": 20, + "value": "machine_heat_zone_length", + "minimum_value_warning": "0", + "maximum_value_warning": "100", + "global_only": "True" + }, + "switch_extruder_retraction_speeds": + { + "label": "Nozzle Switch Retraction Speed", + "description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True", + "children": + { + "switch_extruder_retraction_speed": + { + "label": "Nozzle Switch Retract Speed", + "description": "The speed at which the filament is retracted during a nozzle switch retract.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "value": "switch_extruder_retraction_speeds", + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True" + }, + "switch_extruder_prime_speed": + { + "label": "Nozzle Switch Prime Speed", + "description": "The speed at which the filament is pushed back after a nozzle switch retraction.", + "type": "float", + "unit": "mm/s", + "enabled": "retraction_enable", + "default_value": 20, + "value": "switch_extruder_retraction_speeds", + "minimum_value": "0.1", + "maximum_value_warning": "300", + "global_only": "True" + } + } + }, + "switch_extruder_retraction_hop": + { + "label": "Nozzle Switch Z Hop", + "description": "Whenever the machine switches to another nozzle, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle which has been unused for a while from oozing material on the outside of the print.", + "type": "float", + "unit": "mm", + "default_value": 1, + "minimum_value_warning": "-0.0001", + "maximum_value_warning": "10", + "enabled": "retraction_enable" + } + } + }, + "speed": + { + "label": "Speed", + "icon": "category_speed", + "description": "Speed", + "type": "category", + "children": + { + "speed_print": + { + "label": "Print Speed", + "description": "The speed at which printing happens.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value_warning": "150", + "maximum_value": "299792458000", + "default_value": 60, + "children": + { + "speed_infill": + { + "label": "Infill Speed", + "description": "The speed at which infill is printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_print" + }, + "speed_wall": + { + "label": "Wall Speed", + "description": "The speed at which the walls are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_print / 2", + "children": + { + "speed_wall_0": + { + "label": "Outer Wall Speed", + "description": "The speed at which the outermost walls are printed. Printing the outer wall at a lower speed improves the final skin quality. However, having a large difference between the inner wall speed and the outer wall speed will effect quality in a negative way.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_wall" + }, + "speed_wall_x": + { + "label": "Inner Wall Speed", + "description": "The speed at which all inner walls are printed Printing the inner wall faster than the outer wall will reduce printing time. It works well to set this in between the outer wall speed and the infill speed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_wall * 2" + } + } + }, + "speed_topbottom": + { + "label": "Top/Bottom Speed", + "description": "The speed at which top/bottom layers are printed.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 30, + "value": "speed_print / 2" + }, + "speed_support": + { + "label": "Support Speed", + "description": "The speed at which the support structure is printed. Printing support at higher speeds can greatly reduce printing time. The surface quality of the support structure is not important since it is removed after printing.", + "unit": "mm/s", + "type": "float", + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "default_value": 60, + "value": "speed_print", + "enabled": "support_roof_enable", + "children": + { + "speed_support_infill": + { + "label": "Support Infill Speed", + "description": "The speed at which the infill of support is printed. Printing the infill at lower speeds improves stability.", + "unit": "mm/s", + "type": "float", + "default_value": 60, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "value": "speed_support", + "enabled": "support_enable", + "global_only": true + }, + "speed_support_roof": + { + "label": "Support Roof Speed", + "description": "The speed at which the roofs of support are printed. Printing the support roof at lower speeds can improve overhang quality.", + "unit": "mm/s", + "type": "float", + "default_value": 40, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "support_roof_enable", + "value": "speed_support / 1.5", + "global_only": true + } + } + }, + "speed_prime_tower": + { + "label": "Prime Tower Speed", + "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", + "type": "float", + "unit": "mm/s", + "enabled": "prime_tower_enable", + "default_value": 60, + "value": "speed_print", + "minimum_value": "0.1", + "maximum_value_warning": "150", + "global_only": "True" + } + } + }, + "speed_travel": + { + "label": "Travel Speed", + "description": "The speed at which travel moves are made.", + "unit": "mm/s", + "type": "float", + "default_value": 120, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "value": "speed_print if magic_spiralize else 120", + "global_only": true + }, + "speed_layer_0": { + "label": "Initial Layer Speed", + "description": "The print speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300" + }, + "skirt_speed": { + "label": "Skirt Speed", + "description": "The speed at which the skirt and brim are printed. Normally this is done at the initial layer speed, but sometimes you might want to print the skirt at a different speed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "value": "speed_layer_0", + "global_only": true + }, + "speed_slowdown_layers": + { + "label": "Number of Slower Layers", + "description": "The first few layers are printed slower than the rest of the object, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value": "299792458000", + "maximum_value_warning": "300", + "global_only": true + } + } + }, + "travel": + { + "label": "Travel", + "icon": "category_travel", + "description": "travel", + "type": "category", + "children": + { + "retraction_combing": + { + "label": "Combing Mode", + "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", + "type": "enum", + "options": + { + "off": "Off", + "all": "All", + "noskin": "No Skin" + }, + "default_value": "all", + "global_only": true + }, + "travel_avoid_other_parts": + { + "label": "Avoid Printed Parts when Traveling", + "description": "The nozzle avoids already printed parts when traveling. This option is only available when combing is enabled.", + "type": "bool", + "default_value": true, + "enabled": "retraction_combing != \"off\"", + "global_only": "True" + }, + "travel_avoid_distance": + { + "label": "Travel Avoid Distance", + "description": "The distance between the nozzle and already printed parts when avoiding during travel moves.", + "unit": "mm", + "type": "float", + "default_value": 1.5, + "value": "machine_nozzle_tip_outer_diameter / 2 * 1.25", + "minimum_value": "0", + "maximum_value_warning": "machine_nozzle_tip_outer_diameter * 5", + "enabled": "retraction_combing != \"off\" and travel_avoid_other_parts", + "global_only": "True" + } + } + }, + "cooling": + { + "label": "Cooling", + "icon": "category_cool", + "description": "Cooling", + "type": "category", + "children": + { + "cool_fan_enabled": + { + "label": "Enable Cooling Fans", + "description": "Enables the cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs.", + "type": "bool", + "default_value": true, + "global_only": "True" + }, + "cool_fan_speed": + { + "label": "Fan Speed", + "description": "The speed at which the cooling fans spin.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 100, + "value": "100.0 if cool_fan_enabled else 0.0", + "enabled": "cool_fan_enabled", + "global_only": "True", + "children": + { + "cool_fan_speed_min": + { + "label": "Regular Fan Speed", + "description": "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "value": "cool_fan_speed", + "default_value": 100, + "enabled": "cool_fan_enabled", + "global_only": "True" + }, + "cool_fan_speed_max": + { + "label": "Maximum Fan Speed", + "description": "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit.", + "unit": "%", + "type": "float", + "minimum_value": "max(0, cool_fan_speed_min)", + "maximum_value": "100", + "default_value": 100, + "enabled": "cool_fan_enabled", + "global_only": "True", + "value": "cool_fan_speed" + } + } + }, + "cool_min_layer_time_fan_speed_max": + { + "label": "Regular/Maximum Fan Speed Threshold", + "description": "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed.", + "unit": "sec", + "type": "float", + "default_value": 10, + "minimum_value": "cool_min_layer_time", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_fan_full_at_height": + { + "label": "Regular Fan Speed at Height", + "description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.", + "unit": "mm", + "type": "float", + "default_value": 0.5, + "value": "layer_height_0", + "minimum_value": "0", + "maximum_value_warning": "10.0", + "global_only": "True", + "children": + { + "cool_fan_full_layer": + { + "label": "Regular Fan Speed at Layer", + "description": "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "100", + "value": "max(0, int(round((cool_fan_full_at_height - layer_height_0) / layer_height, 0)))", + "global_only": "True" + } + } + }, + "cool_min_layer_time": + { + "label": "Minimum Layer Time", + "description": "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer.", + "unit": "sec", + "type": "float", + "default_value": 5, + "minimum_value": "0", + "maximum_value_warning": "600", + "global_only": "True" + }, + "cool_min_speed": + { + "label": "Minimum Speed", + "description": "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality.", + "unit": "mm/s", + "type": "float", + "default_value": 10, + "minimum_value": "0", + "maximum_value_warning": "100", + "global_only": "True" + }, + "cool_lift_head": + { + "label": "Lift Head", + "description": "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "support": + { + "label": "Support", + "type": "category", + "icon": "category_support", + "description": "Support", + "children": + { + "support_enable": + { + "label": "Enable Support", + "description": "Enable support structures. These structures support parts of the model with severe overhangs.", + "type": "bool", + "default_value": false + }, + "support_type": + { + "label": "Support Placement", + "description": "Adjusts the placement of the support structures. The placement can be set to touching build plate or everywhere. When set to everywhere the support structures will also be printed on the model.", + "type": "enum", + "options": + { + "buildplate": "Touching Buildplate", + "everywhere": "Everywhere" + }, + "default_value": "everywhere", + "enabled": "support_enable" + }, + "support_angle": + { + "label": "Support Overhang Angle", + "description": "The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 50, + "enabled": "support_enable" + }, + "support_pattern": + { + "label": "Support Pattern", + "description": "The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "zigzag", + "enabled": "support_enable", + "global_only": true + }, + "support_connect_zigzags": + { + "label": "Connect Support ZigZags", + "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", + "type": "bool", + "default_value": true, + "enabled": "support_enable and (support_pattern == \"zigzag\")", + "global_only": true + }, + "support_infill_rate": + { + "label": "Support Density", + "description": "Adjusts the density of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 15, + "enabled": "support_enable", + "global_only": true, + "children": { + "support_line_distance": + { + "label": "Support Line Distance", + "description": "Distance between the printed support structure lines. This setting is calculated by the support density.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "default_value": 2.66, + "enabled": "support_enable", + "value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == \"grid\" else (3 if support_pattern == \"triangles\" else 1))", + "global_only": true + } + } + }, + "support_z_distance": + { + "label": "Support Z Distance", + "description": "Distance from the top/bottom of the support structure to the print. This gap provides clearance to remove the supports after the model is printed. This value is rounded down to a multiple of the layer height.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "enabled": "support_enable", + + "children": + { + "support_top_distance": + { + "label": "Support Top Distance", + "description": "Distance from the top of the support to the print.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.15, + "type": "float", + "enabled": "support_enable", + "value": "support_z_distance" + }, + "support_bottom_distance": + { + "label": "Support Bottom Distance", + "description": "Distance from the print to the bottom of the support.", + "unit": "mm", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.1, + "value": "0.1 if support_type == 'everywhere' else 0", + "type": "float", + "enabled": "support_enable and support_type == 'everywhere'" + } + } + }, + "support_xy_distance": + { + "label": "Support X/Y Distance", + "description": "Distance of the support structure from the print in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.7, + "enabled": "support_enable" + }, + "support_xy_overrides_z": { + "label": "Support Distance Priority", + "description": "Whether the Support X/Y Distance overrides the Support Z Distance or vice versa. When X/Y overrides Z the X/Y distance can push away the support from the model, influencing the actual Z distance to the overhang. We can disable this by not applying the X/Y distance around overhangs.", + "type": "enum", + "options": { + "xy_overrides_z": "X/Y overrides Z", + "z_overrides_xy": "Z overrides X/Y" + }, + "default_value": "z_overrides_xy", + "enabled": "support_enable" + }, + "support_xy_distance_overhang": { + "label": "Minimum Support X/Y Distance", + "description": "Distance of the support structure from the overhang in the X/Y directions. ", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "10", + "default_value": 0.2, + "value": "machine_nozzle_size / 2", + "enabled": "support_enable and support_xy_overrides_z=='z_overrides_xy'" + }, + "support_bottom_stair_step_height": + { + "label": "Support Stair Step Height", + "description": "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_join_distance": + { + "label": "Support Join Distance", + "description": "The maximum distance between support structures in the X/Y directions. When seperate structures are closer together than this value, the structures merge into one.", + "unit": "mm", + "type": "float", + "default_value": 2.0, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "support_enable" + }, + "support_offset": + { + "label": "Support Horizontal Expansion", + "description": "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.", + "unit": "mm", + "type": "float", + "default_value": 0.2, + "minimum_value_warning": "-0.5", + "maximum_value_warning": "5.0", + "enabled": "support_enable" + }, + "support_area_smoothing": + { + "label": "Support Area Smoothing", + "description": "Maximum distance in the X/Y directions of a line segment which is to be smoothed out. Ragged lines are introduced by the join distance and support bridge, which cause the machine to resonate. Smoothing the support areas won't cause them to break with the constraints, except it might change the overhang.", + "unit": "mm", + "type": "float", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "support_enable" + }, + "support_roof_enable": + { + "label": "Enable Support Roof", + "description": "Generate a dense top skin at the top of the support on which the model is printed.", + "type": "bool", + "default_value": false, + "enabled": "support_enable" + }, + "support_roof_height": + { + "label": "Support Roof Thickness", + "description": "The thickness of the support roofs.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_roof_enable" + }, + "support_roof_density": + { + "label": "Support Roof Density", + "description": "Adjusts the density of the roof of the support structure. A higher value results in better overhangs, but the supports are harder to remove.", + "unit": "%", + "type": "float", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "enabled":"support_roof_enable", + "global_only": true, + "children": + { + "support_roof_line_distance": + { + "label": "Support Roof Line Distance", + "description": "Distance between the printed support roof lines. This setting is calculated by the support roof Density, but can be adjusted separately.", + "unit": "mm", + "type": "float", + "default_value": 0.4, + "minimum_value": "0", + "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == \"grid\" else (3 if support_roof_pattern == \"triangles\" else 1))", + "enabled": "support_roof_enable", + "global_only": true + } + } + }, + "support_roof_pattern": + { + "label": "Support Roof Pattern", + "description": "The pattern with which the top of the support is printed.", + "type": "enum", + "options": + { + "lines": "Lines", + "grid": "Grid", + "triangles": "Triangles", + "concentric": "Concentric", + "zigzag": "Zig Zag" + }, + "default_value": "concentric", + "enabled": "support_roof_enable", + "global_only": true + }, + "support_use_towers": + { + "label": "Use Towers", + "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", + "type": "bool", + "default_value": true, + "enabled": "support_enable" + }, + "support_tower_diameter": + { + "label": "Tower Diameter", + "description": "The diameter of a special tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "support_enable and support_use_towers" + }, + "support_minimal_diameter": + { + "label": "Minimum Diameter", + "description": "Minimum diameter in the X/Y directions of a small area which is to be supported by a specialized support tower.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0", + "maximum_value_warning": "10", + "maximum_value": "support_tower_diameter", + "enabled": "support_enable and support_use_towers" + }, + "support_tower_roof_angle": + { + "label": "Tower Roof Angle", + "description": "The angle of a rooftop of a tower. A higher value results in pointed tower roofs, a lower value results in flattened tower roofs.", + "unit": "°", + "type": "int", + "minimum_value": "0", + "maximum_value": "90", + "default_value": 65, + "enabled": "support_enable and support_use_towers" + } + } + }, + "platform_adhesion": + { + "label": "Platform Adhesion", + "type": "category", + "icon": "category_adhesion", + "description": "Adhesion", + "children": + { + "adhesion_type": + { + "label": "Platform Adhesion Type", + "description": "Different options that help to improve both priming your extrusion and adhesion to the build plate. Brim adds a single layer flat area around the base of your object to prevent warping. Raft adds a thick grid with a roof below the object. Skirt is a line printed around the object, but not connected to the model.", + "type": "enum", + "options": + { + "skirt": "Skirt", + "brim": "Brim", + "raft": "Raft" + }, + "default_value": "brim", + "global_only": "True" + }, + "skirt_line_count": + { + "label": "Skirt Line Count", + "description": "Multiple skirt lines help to prime your extrusion better for small objects. Setting this to 0 will disable the skirt.", + "type": "int", + "default_value": 1, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_gap": + { + "label": "Skirt Distance", + "description": "The horizontal distance between the skirt and the first layer of the print.\nThis is the minimum distance, multiple skirt lines will extend outwards from this distance.", + "unit": "mm", + "type": "float", + "default_value": 3, + "minimum_value_warning": "0", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "skirt_minimal_length": + { + "label": "Skirt Minimum Length", + "description": "The minimum length of the skirt. If this length is not reached by the skirt line count, more skirt lines will be added until the minimum length is reached. Note: If the line count is set to 0 this is ignored.", + "unit": "mm", + "type": "float", + "default_value": 250, + "minimum_value": "0", + "minimum_value_warning": "25", + "maximum_value_warning": "2500", + "enabled": "adhesion_type == \"skirt\"", + "global_only": "True" + }, + "brim_width": + { + "label": "Brim Width", + "description": "The distance from the model to the outermost brim line. A larger brim enhances adhesion to the build plate, but also reduces the effective print area.", + "type": "float", + "unit": "mm", + "default_value": 8.0, + "minimum_value": "0.0", + "maximum_value_warning": "100.0", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True", + "children": + { + "brim_line_count": + { + "label": "Brim Line Count", + "description": "The number of lines used for a brim. More brim lines enhance adhesion to the build plate, but also reduces the effective print area.", + "type": "int", + "default_value": 20, + "minimum_value": "0", + "maximum_value_warning": "300", + "value": "math.ceil(brim_width / skirt_line_width)", + "enabled": "adhesion_type == \"brim\"", + "global_only": "True" + } + } + }, + "raft_margin": + { + "label": "Raft Extra Margin", + "description": "If the raft is enabled, this is the extra raft area around the object which is also given a raft. Increasing this margin will create a stronger raft while using more material and leaving less area for your print.", + "unit": "mm", + "type": "float", + "default_value": 5, + "minimum_value_warning": "0", + "maximum_value_warning": "10", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_airgap": + { + "label": "Raft Air Gap", + "description": "The gap between the final raft layer and the first layer of the object. Only the first layer is raised by this amount to lower the bonding between the raft layer and the object. Makes it easier to peel off the raft.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "1.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "layer_0_z_overlap": { + "label": "Initial Layer Z Overlap", + "description": "Make the first and second layer of the object overlap in the Z direction to compensate for the filament lost in the airgap. All models above the first model layer will be shifted down by this amount.", + "unit": "mm", + "type": "float", + "default_value": 0.22, + "value": "raft_airgap / 2", + "minimum_value": "0", + "maximum_value_warning": "layer_height", + "enabled": "adhesion_type == 'raft'", + "global_only": "True" + }, + "raft_surface_layers": + { + "label": "Raft Top Layers", + "description": "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the object sits on. 2 layers result in a smoother top surface than 1.", + "type": "int", + "default_value": 2, + "minimum_value": "0", + "maximum_value_warning": "20", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_thickness": + { + "label": "Raft Top Layer Thickness", + "description": "Layer thickness of the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_width": + { + "label": "Raft Top Line Width", + "description": "Width of the lines in the top surface of the raft. These can be thin lines so that the top of the raft becomes smooth.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_surface_line_spacing": + { + "label": "Raft Top Spacing", + "description": "The distance between the raft lines for the top raft layers. The spacing should be equal to the line width, so that the surface is solid.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0.0001", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "value": "raft_surface_line_width", + "global_only": "True" + }, + "raft_interface_thickness": + { + "label": "Raft Middle Thickness", + "description": "Layer thickness of the middle raft layer.", + "unit": "mm", + "type": "float", + "default_value": 0.27, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_width": + { + "label": "Raft Middle Line Width", + "description": "Width of the lines in the middle raft layer. Making the second layer extrude more causes the lines to stick to the bed.", + "unit": "mm", + "type": "float", + "default_value": 1, + "value": "line_width", + "minimum_value": "0.0001", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_interface_line_spacing": + { + "label": "Raft Middle Spacing", + "description": "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers.", + "unit": "mm", + "type": "float", + "default_value": 1.0, + "minimum_value": "0", + "maximum_value_warning": "15.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_thickness": + { + "label": "Raft Base Thickness", + "description": "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer bed.", + "unit": "mm", + "type": "float", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_width": + { + "label": "Raft Base Line Width", + "description": "Width of the lines in the base raft layer. These should be thick lines to assist in bed adhesion.", + "unit": "mm", + "type": "float", + "default_value": 1, + "minimum_value": "0.0001", + "value": "line_width", + "maximum_value_warning": "machine_nozzle_size * 2", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_base_line_spacing": + { + "label": "Raft Line Spacing", + "description": "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate.", + "unit": "mm", + "type": "float", + "default_value": 3.0, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "global_only": "True" + }, + "raft_speed": + { + "label": "Raft Print Speed", + "description": "The speed at which the raft is printed.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "value": "speed_print / 60 * 30", + "global_only": "True", + "children": + { + "raft_surface_speed": + { + "label": "Raft Surface Print Speed", + "description": "The speed at which the surface raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines.", + "unit": "mm/s", + "type": "float", + "default_value": 30, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "enabled": "adhesion_type == \"raft\"", + "value": "raft_speed", + "global_only": "True" + }, + "raft_interface_speed": + { + "label": "Raft Interface Print Speed", + "description": "The speed at which the interface raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "150", + "enabled": "adhesion_type == \"raft\"", + "value": "0.5 * raft_speed", + "global_only": "True" + }, + "raft_base_speed": + { + "label": "Raft Base Print Speed", + "description": "The speed at which the base raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high.", + "unit": "mm/s", + "type": "float", + "default_value": 15, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "200", + "enabled": "adhesion_type == \"raft\"", + "value": "0.5 * raft_speed", + "global_only": "True" + } + } + }, + "raft_fan_speed": + { + "label": "Raft Fan Speed", + "description": "The fan speed for the raft.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 0, + "global_only": "True", + "enabled": "adhesion_type == \"raft\"", + "children": + { + "raft_surface_fan_speed": + { + "label": "Raft Surface Fan Speed", + "description": "The fan speed for the surface raft layers.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 0, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + }, + "raft_interface_fan_speed": + { + "label": "Raft Interface Fan Speed", + "description": "The fan speed for the interface raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 0, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + }, + "raft_base_fan_speed": + { + "label": "Raft Base Fan Speed", + "description": "The fan speed for the base raft layer.", + "unit": "%", + "type": "float", + "minimum_value": "0", + "maximum_value": "100", + "default_value": 0, + "global_only": "True", + "value": "raft_fan_speed", + "enabled": "adhesion_type == \"raft\"" + } + } + } + } + }, + "meshfix": + { + "label": "Mesh Fixes", + "type": "category", + "icon": "category_fixes", + "description": "category_fixes", + "children": + { + "meshfix_union_all": + { + "label": "Union Overlapping Volumes", + "description": "Ignore the internal geometry arising from overlapping volumes and print the volumes as one. This may cause internal cavities to disappear.", + "type": "bool", + "default_value": true + }, + "meshfix_union_all_remove_holes": + { + "label": "Remove All Holes", + "description": "Remove the holes in each layer and keep only the outside shape. This will ignore any invisible internal geometry. However, it also ignores layer holes which can be viewed from above or below.", + "type": "bool", + "default_value": false + }, + "meshfix_extensive_stitching": + { + "label": "Extensive Stitching", + "description": "Extensive stitching tries to stitch up open holes in the mesh by closing the hole with touching polygons. This option can introduce a lot of processing time.", + "type": "bool", + "default_value": false + }, + "meshfix_keep_open_polygons": + { + "label": "Keep Disconnected Faces", + "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.", + "type": "bool", + "default_value": false + } + } + }, + "blackmagic": + { + "label": "Special Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "category_blackmagic", + "children": + { + "print_sequence": + { + "label": "Print Sequence", + "description": "Whether to print all objects one layer at a time or to wait for one object to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.", + "type": "enum", + "options": + { + "all_at_once": "All at Once", + "one_at_a_time": "One at a Time" + }, + "default_value": "all_at_once", + "global_only": true + }, + "magic_mesh_surface_mode": + { + "label": "Surface Mode", + "description": "Treat the model as a surface only, a volume, or volumes with loose surfaces. The normal print mode only prints enclosed volumes. \"Surface\" prints a single wall tracing the mesh surface with no infill and no top/bottom skin. \"Both\" prints enclosed volumes like normal and any remaining polygons as surfaces.", + "type": "enum", + "options": + { + "normal": "Normal", + "surface": "Surface", + "both": "Both" + }, + "default_value": "normal" + }, + "magic_spiralize": + { + "label": "Spiralize Outer Contour", + "description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid object into a single walled print with a solid bottom. This feature used to be called Joris in older versions.", + "type": "bool", + "default_value": false, + "global_only": "True" + } + } + }, + "dual": + { + "label": "Dual Extrusion", + "type": "category", + "icon": "category_dual", + "description": "Settings used for printing with multiple extruders.", + "children": + { + "extruder_nr": + { + "label": "Extruder", + "description": "The extruder train used for printing. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1" + }, + "adhesion_extruder_nr": + { + "label": "Platform Adhesion Extruder", + "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_extruder_nr": + { + "label": "Support Extruder", + "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True", + "children": { + "support_infill_extruder_nr": + { + "label": "Support Infill Extruder", + "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_extruder_nr_layer_0": + { + "label": "First Layer Support Extruder", + "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + }, + "support_roof_extruder_nr": + { + "label": "Support Roof Extruder", + "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", + "type": "int", + "default_value": 0, + "value": "support_extruder_nr", + "minimum_value": "0", + "maximum_value": "machine_extruder_count - 1", + "global_only": "True" + } + } + }, + "prime_tower_enable": + { + "label": "Enable Prime Tower", + "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "prime_tower_size": + { + "label": "Prime Tower Size", + "description": "The width of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 15, + "value": "15 if prime_tower_enable else 0", + "minimum_value": "0", + "maximum_value_warning": "20", + "global_only": "True" + }, + "prime_tower_position_x": + { + "label": "Prime Tower X Position", + "description": "The x coordinate of the position of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 200, + "minimum_value_warning": "-1000", + "maximum_value_warning": "1000", + "global_only": "True" + }, + "prime_tower_position_y": + { + "label": "Prime Tower Y Position", + "description": "The y coordinate of the position of the prime tower.", + "type": "float", + "unit": "mm", + "enabled": "prime_tower_enable", + "default_value": 200, + "minimum_value_warning": "-1000", + "maximum_value_warning": "1000", + "global_only": "True" + }, + "prime_tower_flow": + { + "label": "Prime Tower Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value.", + "type": "float", + "unit": "%", + "enabled": "prime_tower_enable", + "default_value": 100, + "minimum_value": "0.0001", + "minimum_value_warning": "50", + "maximum_value_warning": "150", + "global_only": "True" + }, + "prime_tower_wipe_enabled": + { + "label": "Wipe Nozzle on Prime Tower", + "description": "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", + "type": "bool", + "enabled": "prime_tower_enable", + "default_value": false, + "global_only": "True" + }, + "multiple_mesh_overlap": + { + "label": "Dual Extrusion Overlap", + "description": "Make the objects printed with different extruder trains overlap a bit. This makes the different materials bond together better.", + "type": "float", + "unit": "mm", + "default_value": 0.15, + "minimum_value": "0", + "maximum_value_warning": "1.0" + }, + "ooze_shield_enabled": + { + "label": "Enable Ooze Shield", + "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "ooze_shield_angle": + { + "label": "Ooze Shield Angle", + "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", + "type": "float", + "unit": "°", + "enabled": "ooze_shield_enabled", + "default_value": 60, + "minimum_value": "0", + "maximum_value": "90", + "global_only": "True" + }, + "ooze_shield_dist": + { + "label": "Ooze Shield Distance", + "description": "Distance of the ooze shield from the print, in the X/Y directions.", + "type": "float", + "unit": "mm", + "enabled": "ooze_shield_enabled", + "default_value": 2, + "minimum_value": "0", + "maximum_value_warning": "30", + "global_only": "True" + } + } + }, + "experimental": + { + "label": "Experimental Modes", + "type": "category", + "icon": "category_blackmagic", + "description": "experimental!", + "children": + { + "draft_shield_enabled": + { + "label": "Enable Draft Shield", + "description": "This will create a wall around the object, which traps (hot) air and shields against exterior airflow. Especially useful for materials which warp easily.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "draft_shield_dist": + { + "label": "Draft Shield X/Y Distance", + "description": "Distance of the draft shield from the print, in the X/Y directions.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "100", + "default_value": 10, + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height_limitation": + { + "label": "Draft Shield Limitation", + "description": "Set the height of the draft shield. Choose to print the draft shield at the full height of the object or at a limited height.", + "type": "enum", + "options": + { + "full": "Full", + "limited": "Limited" + }, + "default_value": "full", + "enabled": "draft_shield_enabled", + "global_only": true + }, + "draft_shield_height": + { + "label": "Draft Shield Height", + "description": "Height limitation of the draft shield. Above this height no draft shield will be printed.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "maximum_value_warning": "9999", + "default_value": 0, + "value": "9999 if draft_shield_height_limitation == 'full' and draft_shield_enabled else 0.0", + "enabled": "draft_shield_height_limitation == \"limited\"", + "global_only": true + }, + "conical_overhang_enabled": { + "label": "Make Overhang Printable", + "description": "Change the geometry of the printed model such that minimal support is required. Steep overhangs will become shallow overhangs. Overhanging areas will drop down to become more vertical.", + "type": "bool", + "default_value": false + }, + "conical_overhang_angle": { + "label": "Maximum Model Angle", + "description": "The maximum angle of overhangs after the they have been made printable. At a value of 0° all overhangs are replaced by a piece of model connected to the build plate, 90° will not change the model in any way.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "89", + "default_value": 50, + "enabled": "conical_overhang_enabled" + }, + "coasting_enable": + { + "label": "Enable Coasting", + "description": "Coasting replaces the last part of an extrusion path with a travel path. The oozed material is used to print the last piece of the extrusion path in order to reduce stringing.", + "type": "bool", + "default_value": false, + "global_only": true + }, + "coasting_volume": + { + "label": "Coasting Volume", + "description": "The volume otherwise oozed. This value should generally be close to the nozzle diameter cubed.", + "unit": "mm³", + "type": "float", + "default_value": 0.064, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_min_volume": + { + "label": "Minimum Volume Before Coasting", + "description": "The smallest volume an extrusion path should have before allowing coasting. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", + "unit": "mm³", + "type": "float", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10.0", + "enabled": "coasting_enable", + "global_only": true + }, + "coasting_speed": + { + "label": "Coasting Speed", + "description": "The speed by which to move during coasting, relative to the speed of the extrusion path. A value slightly under 100% is advised, since during the coasting move the pressure in the bowden tube drops.", + "unit": "%", + "type": "float", + "default_value": 90, + "minimum_value": "0.0001", + "maximum_value_warning": "100", + "enabled": "coasting_enable", + "global_only": true + }, + "skin_outline_count": + { + "label": "Extra Skin Wall Count", + "description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "10", + "type": "int" + }, + "skin_alternate_rotation": + { + "label": "Alternate Skin Rotation", + "description": "Alternate the direction in which the top/bottom layers are printed. Normally they are printed diagonally only. This setting adds the X-only and Y-only directions.", + "type": "bool", + "default_value": false, + "enabled": "top_bottom_pattern != \"concentric\"" + }, + "support_conical_enabled": + { + "label": "Enable Conical Support", + "description": "Experimental feature: Make support areas smaller at the bottom than at the overhang.", + "type": "bool", + "default_value": false, + "enabled": "support_enable" + }, + "support_conical_angle": + { + "label": "Conical Support Angle", + "description": "The angle of the tilt of conical support. With 0 degrees being vertical, and 90 degrees being horizontal. Smaller angles cause the support to be more sturdy, but consist of more material. Negative angles cause the base of the support to be wider than the top.", + "unit": "°", + "type": "float", + "minimum_value": "-90", + "minimum_value_warning": "-45", + "maximum_value_warning": "45", + "maximum_value": "90", + "default_value": 30, + "enabled": "support_conical_enabled and support_enable" + }, + "support_conical_min_width": + { + "label": "Conical Support Minimum Width", + "description": "Minimum width to which the base of the conical support area is reduced. Small widths can lead to unstable support structures.", + "unit": "mm", + "default_value": 5.0, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size * 3", + "maximum_value_warning": "100.0", + "type": "float", + "enabled": "support_conical_enabled and support_enable" + }, + "magic_fuzzy_skin_enabled": + { + "label": "Fuzzy Skin", + "description": "Randomly jitter while printing the outer wall, so that the surface has a rough and fuzzy look.", + "type": "bool", + "default_value": false + }, + "magic_fuzzy_skin_thickness": + { + "label": "Fuzzy Skin Thickness", + "description": "The width within which to jitter. It's advised to keep this below the outer wall width, since the inner walls are unaltered.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0.001", + "maximum_value_warning": "wall_line_width_0", + "enabled": "magic_fuzzy_skin_enabled" + }, + "magic_fuzzy_skin_point_density": + { + "label": "Fuzzy Skin Density", + "description": "The average density of points introduced on each polygon in a layer. Note that the original points of the polygon are discarded, so a low density results in a reduction of the resolution.", + "type": "float", + "unit": "1/mm", + "default_value": 1.25, + "minimum_value": "0.008", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "maximum_value": "2 / magic_fuzzy_skin_thickness", + "enabled": "magic_fuzzy_skin_enabled", + "children": + { + "magic_fuzzy_skin_point_dist": + { + "label": "Fuzzy Skin Point Distance", + "description": "The average distance between the random points introduced on each line segment. Note that the original points of the polygon are discarded, so a high smoothness results in a reduction of the resolution. This value must be higher than half the Fuzzy Skin Thickness.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "magic_fuzzy_skin_thickness / 2", + "minimum_value_warning": "0.1", + "maximum_value_warning": "10", + "value": "10000 if magic_fuzzy_skin_point_density == 0 else 1 / magic_fuzzy_skin_point_density", + "enabled": "magic_fuzzy_skin_enabled" + } + } + }, + "wireframe_enabled": + { + "label": "Wire Printing", + "description": "Print only the outside surface with a sparse webbed structure, printing 'in thin air'. This is realized by horizontally printing the contours of the model at given Z intervals which are connected via upward and diagonally downward lines.", + "type": "bool", + "default_value": false, + "global_only": "True" + }, + "wireframe_height": + { + "label": "WP Connection Height", + "description": "The height of the upward and diagonally downward lines between two horizontal parts. This determines the overall density of the net structure. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0.0001", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_inset": + { + "label": "WP Roof Inset Distance", + "description": "The distance covered when making a connection from a roof outline inward. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 3, + "minimum_value": "0", + "minimum_value_warning": "machine_nozzle_size", + "maximum_value_warning": "20", + "enabled": "wireframe_enabled", + "value": "wireframe_height", + "global_only": "True" + }, + "wireframe_printspeed": + { + "label": "WP Speed", + "description": "Speed at which the nozzle moves when extruding material. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_printspeed_bottom": + { + "label": "WP Bottom Printing Speed", + "description": "Speed of printing the first layer, which is the only layer touching the build platform. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_up": + { + "label": "WP Upward Printing Speed", + "description": "Speed of printing a line upward 'in thin air'. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_down": + { + "label": "WP Downward Printing Speed", + "description": "Speed of printing a line diagonally downward. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "50", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_printspeed" + }, + "wireframe_printspeed_flat": + { + "label": "WP Horizontal Printing Speed", + "description": "Speed of printing the horizontal contours of the object. Only applies to Wire Printing.", + "unit": "mm/s", + "type": "float", + "default_value": 5, + "minimum_value": "0.1", + "maximum_value": "299792458000", + "maximum_value_warning": "100", + "value": "wireframe_printspeed", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + }, + "wireframe_flow": + { + "label": "WP Flow", + "description": "Flow compensation: the amount of material extruded is multiplied by this value. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "children": + { + "wireframe_flow_connection": + { + "label": "WP Connection Flow", + "description": "Flow compensation when going up or down. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_flow" + }, + "wireframe_flow_flat": + { + "label": "WP Flat Flow", + "description": "Flow compensation when printing flat lines. Only applies to Wire Printing.", + "unit": "%", + "default_value": 100, + "minimum_value": "0", + "maximum_value_warning": "100", + "type": "float", + "enabled": "wireframe_enabled", + "global_only": "True", + "value": "wireframe_flow" + } + } + }, + "wireframe_top_delay": + { + "label": "WP Top Delay", + "description": "Delay time after an upward move, so that the upward line can harden. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_bottom_delay": + { + "label": "WP Bottom Delay", + "description": "Delay time after a downward move. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0, + "minimum_value": "0", + "maximum_value_warning": "1", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_flat_delay": + { + "label": "WP Flat Delay", + "description": "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing.", + "unit": "sec", + "type": "float", + "default_value": 0.1, + "minimum_value": "0", + "maximum_value_warning": "0.5", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_up_half_speed": + { + "label": "WP Ease Upward", + "description": "Distance of an upward move which is extruded with half speed.\nThis can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.3, + "minimum_value": "0", + "maximum_value_warning": "5.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_top_jump": + { + "label": "WP Knot Size", + "description": "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_fall_down": + { + "label": "WP Fall Down", + "description": "Distance with which the material falls down after an upward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.5, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_drag_along": + { + "label": "WP Drag Along", + "description": "Distance with which the material of an upward extrusion is dragged along with the diagonally downward extrusion. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.6, + "minimum_value": "0", + "maximum_value_warning": "wireframe_height", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_strategy": + { + "label": "WP Strategy", + "description": "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted.", + "type": "enum", + "options": + { + "compensate": "Compensate", + "knot": "Knot", + "retract": "Retract" + }, + "default_value": "compensate", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_straight_before_down": + { + "label": "WP Straighten Downward Lines", + "description": "Percentage of a diagonally downward line which is covered by a horizontal line piece. This can prevent sagging of the top most point of upward lines. Only applies to Wire Printing.", + "type": "float", + "unit": "%", + "default_value": 20, + "minimum_value": "0", + "maximum_value": "100", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_fall_down": + { + "label": "WP Roof Fall Down", + "description": "The distance which horizontal roof lines printed 'in thin air' fall down when being printed. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 2, + "minimum_value_warning": "0", + "maximum_value_warning": "wireframe_roof_inset", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_drag_along": + { + "label": "WP Roof Drag Along", + "description": "The distance of the end piece of an inward line which gets dragged along when going back to the outer outline of the roof. This distance is compensated for. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 0.8, + "minimum_value": "0", + "maximum_value_warning": "10", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_roof_outer_delay": + { + "label": "WP Roof Outer Delay", + "description": "Time spent at the outer perimeters of hole which is to become a roof. Longer times can ensure a better connection. Only applies to Wire Printing.", + "type": "float", + "unit": "sec", + "default_value": 0.2, + "minimum_value": "0", + "maximum_value_warning": "2.0", + "enabled": "wireframe_enabled", + "global_only": "True" + }, + "wireframe_nozzle_clearance": + { + "label": "WP Nozzle Clearance", + "description": "Distance between the nozzle and horizontally downward lines. Larger clearance results in diagonally downward lines with a less steep angle, which in turn results in less upward connections with the next layer. Only applies to Wire Printing.", + "type": "float", + "unit": "mm", + "default_value": 1, + "minimum_value_warning": "0", + "maximum_value_warning": "10.0", + "enabled": "wireframe_enabled", + "global_only": "True" + } + } + } + } +} diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json new file mode 100644 index 0000000000..563bdd1a67 --- /dev/null +++ b/resources/definitions/grr_neo.def.json @@ -0,0 +1,59 @@ +{ + "id": "grr_neo", + "version": 2, + "name": "German RepRap Neo", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Simon Cor", + "manufacturer": "German RepRap", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "grr_neo_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 150 + }, + "machine_height": { + "default_value": 150 + }, + "machine_depth": { + "default_value": 150 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.5 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json new file mode 100644 index 0000000000..9ba8d0d44b --- /dev/null +++ b/resources/definitions/innovo_inventor.def.json @@ -0,0 +1,99 @@ +{ + "id": "innovo-inventor", + "version": 2, + "name": "Innovo INVENTOR", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Adam Rumjahn", + "manufacturer": "Innovo", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "inventor_platform.stl", + "platform_offset": [-180, -0.25, 160] + }, + + "overrides": { + "machine_width": { + "default_value": 340 + }, + "machine_height": { + "default_value": 290 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_head_polygon": { + "default_value": [ + [-43.7, -19.2], + [-43.7, 55], + [43.7, 55], + [43.7, -19.2] + ] + }, + "gantry_height": { + "default_value": 82.3 + }, + "machine_nozzle_offset_x": { + "default_value": 0 + }, + "machine_nozzle_offset_y": { + "default_value": 15 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position" + }, + "machine_end_gcode": { + "default_value": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors" + }, + "layer_height": { + "default_value": 0.15 + }, + "wall_thickness": { + "default_value": 0.8 + }, + "top_bottom_thickness": { + "default_value": 0.3 + }, + "material_print_temperature": { + "default_value": 215 + }, + "material_bed_temperature": { + "default_value": 60 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 100 + }, + "speed_topbottom": { + "default_value": 30 + }, + "speed_travel": { + "default_value": 150 + }, + "speed_layer_0": { + "default_value": 30.0, + "minimum_value": 0.1 + }, + "infill_overlap": { + "default_value": 10.0 + } + } +} \ No newline at end of file diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json new file mode 100644 index 0000000000..bb027d33bc --- /dev/null +++ b/resources/definitions/m180.def.json @@ -0,0 +1,57 @@ +{ + "id": "m180", + "version": 2, + "name": "Malyan M180", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Ruben Dulek", + "manufacturer": "Malyan", + "category": "Other", + "file_formats": "application/x3g" + }, + + "overrides": { + "machine_width": { + "default_value": 230 + }, + "machine_height": { + "default_value": 165 + }, + "machine_depth": { + "default_value": 145 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4, + "minimum_value": "0.001" + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [ -75, 35 ], + [ -75, -18 ], + [ 18, -18 ], + [ 18, 35 ] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" + }, + "machine_end_gcode": { + "default_value": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" + }, + "material_diameter": { + "default_value": 1.75, + "minimum_value_warning": "1.5", + "maximum_value_warning": "2.0" + } + } +} \ No newline at end of file diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json new file mode 100644 index 0000000000..a26ca058f0 --- /dev/null +++ b/resources/definitions/maker_starter.def.json @@ -0,0 +1,176 @@ +{ + "id": "maker_starter", + "version": 2, + "name": "3DMaker Starter", + "inherits": "fdmprinter", + "metadata": { + "author": "tvlgiao", + "manufacturer": "3DMaker", + "category": "Other", + "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", + "icon": "icon_ultimaker2.png", + "platform": "makerstarter_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 210 + }, + "machine_depth": { + "default_value": 185 + }, + "machine_height": { + "default_value": 200 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "machine_disallowed_areas": { + "default_value": [] + }, + "machine_nozzle_tip_outer_diameter": { + "default_value": 1 + }, + "machine_nozzle_head_distance": { + "default_value": 3 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "layer_height": { + "default_value": 0.2 + }, + "layer_height_0": { + "default_value": 0.2 + }, + "wall_line_count": { + "default_value": 2 + }, + "top_layers": { + "default_value": 4 + }, + "bottom_layers": { + "default_value": 4 + }, + "speed_print": { + "default_value": 50 + }, + "speed_wall": { + "default_value": 30 + }, + "speed_wall_0": { + "default_value": 30 + }, + "speed_wall_x": { + "default_value": 30 + }, + "speed_topbottom": { + "default_value": 50 + }, + "speed_support": { + "default_value": 50 + }, + "speed_travel": { + "default_value": 120 + }, + "speed_layer_0": { + "default_value": 20 + }, + "skirt_speed": { + "default_value": 15 + }, + "speed_slowdown_layers": { + "default_value": 4 + }, + "infill_sparse_density": { + "default_value": 20 + }, + "cool_fan_speed_min": { + "default_value": 50 + }, + "cool_fan_speed_max": { + "default_value": 100 + }, + "cool_fan_full_layer": { + "default_value": 4 + }, + "cool_min_layer_time": { + "default_value": 5 + }, + "cool_min_layer_time_fan_speed_max": { + "default_value": 10 + }, + "support_type": { + "default_value": "Everywhere" + }, + "support_angle": { + "default_value": 45 + }, + "support_xy_distance": { + "default_value": 1 + }, + "support_z_distance": { + "default_value": 0.2 + }, + "support_top_distance": { + "default_value": 0.2 + }, + "support_bottom_distance": { + "default_value": 0.24 + }, + "support_pattern": { + "default_value": "ZigZag" + }, + "support_infill_rate": { + "default_value": 15 + }, + "adhesion_type": { + "default_value": "Raft" + }, + "skirt_minimal_length": { + "default_value": 100 + }, + "raft_base_line_spacing": { + "default_value": 2 + }, + "raft_base_thickness": { + "default_value": 0.3 + }, + "raft_base_line_width": { + "default_value": 2 + }, + "raft_base_speed": { + "default_value": 15 + }, + "raft_interface_thickness": { + "default_value": 0.24 + }, + "raft_interface_line_width": { + "default_value": 0.6 + }, + "raft_airgap": { + "default_value": 0.2 + }, + "raft_surface_layers": { + "default_value": 2 + } + } +} \ No newline at end of file diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json new file mode 100644 index 0000000000..12e7054694 --- /dev/null +++ b/resources/definitions/prusa_i3.def.json @@ -0,0 +1,65 @@ +{ + "id": "prusa_i3", + "version": 2, + "name": "Prusa i3", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Quillford", + "manufacturer": "Prusajr", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2", + "platform": "prusai3_platform.stl" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + }, + "machine_width": { + "default_value": 200 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 200 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json new file mode 100644 index 0000000000..819a93b860 --- /dev/null +++ b/resources/definitions/prusa_i3_xl.def.json @@ -0,0 +1,65 @@ +{ + "id": "prusa_i3_xl", + "version": 2, + "name": "Prusa i3 xl", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "guigashm", + "manufacturer": "Prusajr", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "prusai3_xl_platform.stl" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + }, + "machine_width": { + "default_value": 200 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 270 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2.0 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2.0 + }, + "machine_head_polygon": { + "default_value": [ + [-75, -18], + [-75, 35], + [18, 35], + [18, -18] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} \ No newline at end of file diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json new file mode 100644 index 0000000000..ace8300d5d --- /dev/null +++ b/resources/definitions/rigidbot.def.json @@ -0,0 +1,102 @@ +{ + "id": "rigidbot", + "version": 2, + "name": "RigidBot", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "RBC", + "manufacturer": "RigidBot", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "rigidbot_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 254 + }, + "machine_depth": { + "default_value": 254 + }, + "machine_height": { + "default_value": 254 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "gantry_height": { + "default_value": 0 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + }, + "machine_end_gcode": { + "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + }, + "layer_height": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 0.8 + }, + "top_bottom_thickness": { + "default_value": 0.3 + }, + "material_print_temperature": { + "default_value": 195 + }, + "material_bed_temperature": { + "default_value": 60 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 100 + }, + "speed_topbottom": { + "default_value": 15 + }, + "speed_travel": { + "default_value": 150 + }, + "speed_layer_0": { + "default_value": 15, + "minimum_value": "0.1" + }, + "infill_overlap": { + "default_value": 10 + }, + "cool_fan_enabled": { + "default_value": false + }, + "cool_fan_speed": { + "default_value": 0 + }, + "skirt_line_count": { + "default_value": 3, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_gap": { + "default_value": 4, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_minimal_length": { + "default_value": 200, + "enabled": "adhesion_type == \"Skirt\"" + } + } +} diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json new file mode 100644 index 0000000000..ce27d36745 --- /dev/null +++ b/resources/definitions/rigidbot_big.def.json @@ -0,0 +1,105 @@ +{ + "id": "rigidbotbig", + "version": 2, + "name": "RigidBotBig", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "RBC", + "manufacturer": "RigidBot", + "category": "Other", + "file_formats": "text/x-gcode", + "platform": "rigidbotbig_platform.stl" + }, + + "overrides": { + "machine_width": { + "default_value": 400 + }, + "machine_depth": { + "default_value": 300 + }, + "machine_height": { + "default_value": 254 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "gantry_height": { + "default_value": 0 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + }, + "machine_end_gcode": { + "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" + }, + "layer_height": { + "default_value": 0.2 + }, + "wall_thickness": { + "default_value": 0.8 + }, + "top_bottom_thickness": { + "default_value": 0.3 + }, + "material_print_temperature": { + "default_value": 195 + }, + "material_bed_temperature": { + "default_value": 60 + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_infill": { + "default_value": 100 + }, + "speed_topbottom": { + "default_value": 15 + }, + "speed_travel": { + "default_value": 150 + }, + "speed_layer_0": { + "default_value": 15, + "minimum_value": "0.1" + }, + "infill_overlap": { + "default_value": 10 + }, + "cool_fan_enabled": { + "default_value": false + }, + "cool_fan_speed": { + "default_value": 0 + }, + "skirt_line_count": { + "default_value": 3, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_gap": { + "default_value": 4, + "enabled": "adhesion_type == \"Skirt\"" + }, + "skirt_minimal_length": { + "default_value": 200, + "enabled": "adhesion_type == \"Skirt\"" + } + } +} \ No newline at end of file diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json new file mode 100644 index 0000000000..60e4dbbf40 --- /dev/null +++ b/resources/definitions/ultimaker.def.json @@ -0,0 +1,14 @@ +{ + "id": "ultimaker_base", + "version": 2, + "visible": false, + "name": "Ultimaker", + "inherits": "fdmprinter", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "preferred_profile": "Normal Quality", + "preferred_nozzle": "0.4 mm", + "preferred_material": "PLA" + } +} diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json new file mode 100644 index 0000000000..7b2222e5b3 --- /dev/null +++ b/resources/definitions/ultimaker2.def.json @@ -0,0 +1,108 @@ +{ + "id": "ultimaker2", + "version": 2, + "name": "Ultimaker 2", + "inherits": "ultimaker", + "metadata": { + "visible": true, + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2backplate.png", + "platform_offset": [9, 0, 0] + }, + "overrides": { + "machine_start_gcode" : { + "default_value": "" + }, + "machine_end_gcode" : { + "default_value": "" + }, + "machine_width": { + "default_value": 223 + }, + "machine_depth": { + "default_value": 223 + }, + "machine_height": { + "default_value": 205 + }, + "machine_heated_bed": { + "default_value": true + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -42, 12 ], + [ -42, -32 ], + [ 62, 12 ], + [ 62, -32 ] + ] + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4, + "minimum_value": "0.001" + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "gantry_height": { + "default_value": 55 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": true + }, + "machine_gcode_flavor": { + "default_value": "UltiGCode" + }, + "machine_disallowed_areas": { + "default_value": [ + [[-115, 112.5], [ -82, 112.5], [ -84, 102.5], [-115, 102.5]], + [[ 115, 112.5], [ 115, 102.5], [ 110, 102.5], [ 108, 112.5]], + [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], + [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] + ]}, + "machine_nozzle_tip_outer_diameter": { + "default_value": 1 + }, + "machine_nozzle_head_distance": { + "default_value": 3 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "material_print_temperature": { + "enabled": "False" + }, + "material_bed_temperature": { + "enabled": "False" + }, + "material_diameter": { + "enabled": "False" + }, + "material_flow": { + "enabled": "False" + }, + "retraction_amount": { + "enabled": "False" + }, + "retraction_speed": { + "enabled": "False" + }, + "retraction_retract_speed": { + "enabled": "False" + }, + "retraction_prime_speed": { + "enabled": "False" + } + } +} diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json new file mode 100644 index 0000000000..e3c7d1fd01 --- /dev/null +++ b/resources/definitions/ultimaker2_extended.def.json @@ -0,0 +1,21 @@ +{ + "id": "ultimaker2_extended", + "version": 2, + "name": "Ultimaker 2 Extended", + "inherits": "ultimaker2", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2Extendedbackplate.png" + }, + + "overrides": { + "machine_height": { + "default_value": 315 + } + } +} diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json new file mode 100644 index 0000000000..eae48773b6 --- /dev/null +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -0,0 +1,30 @@ +{ + "id": "ultimaker2_extended_plus", + "version": 2, + "name": "Ultimaker 2 Extended+", + "inherits": "ultimaker2_plus", + "visible": false, + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2ExtendedPlusbackplate.png" + }, + + "overrides": { + "machine_height": { + "default_value": 313 + }, + "machine_show_variants": { + "default_value": true + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + } + } +} diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json new file mode 100644 index 0000000000..d3ef53d633 --- /dev/null +++ b/resources/definitions/ultimaker2_go.def.json @@ -0,0 +1,39 @@ +{ + "id": "ultimaker2_go", + "version": 2, + "name": "Ultimaker 2 Go", + "inherits": "ultimaker2", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png", + "platform": "ultimaker2go_platform.obj", + "platform_texture": "Ultimaker2Gobackplate.png", + "platform_offset": [0, 0, 0] + }, + + "overrides": { + "machine_width": { + "default_value": 120 + }, + "machine_depth": { + "default_value": 120 + }, + "machine_height": { + "default_value": 115 + }, + "machine_heated_bed": { + "default_value": false + }, + "machine_disallowed_areas": { + "default_value": [ + [[-60, 60], [-33, 60], [-35, 52], [-60, 52]], + [[ 60, 60], [ 60, 52], [ 35, 52], [ 33, 60]], + [[-60, -60], [-60, -52], [-35, -52], [-33, -60]], + [[ 60, -60], [ 33, -60], [ 35, -52], [ 60, -52]] + ] + } + } +} diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json new file mode 100644 index 0000000000..9f68c2a16b --- /dev/null +++ b/resources/definitions/ultimaker2_plus.def.json @@ -0,0 +1,74 @@ +{ + "id": "ultimaker2_plus", + "version": 2, + "name": "Ultimaker 2+", + "inherits": "ultimaker2", + "visible": "false", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Ultimaker2Plusbackplate.png", + "preferred_variant": "ultimaker2_plus_0.4", + "preferred_material": "pla", + "preferred_quality": "high" + }, + + "overrides": { + "speed_infill": { + "value": "speed_print" + }, + "speed_wall_x": { + "value": "speed_wall" + }, + "layer_height_0": { + "value": "round(machine_nozzle_size / 1.5, 2)" + }, + "line_width": { + "value": "round(machine_nozzle_size * 0.875, 2)" + }, + "speed_layer_0": { + "default_value": 20 + }, + "speed_support": { + "value": "speed_wall_0" + }, + "machine_height": { + "default_value": 203 + }, + "machine_show_variants": { + "default_value": true + }, + "gantry_height": { + "default_value": 52 + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "machine_heat_zone_length": { + "default_value": 20 + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -44, 14 ], + [ -44, -34 ], + [ 64, 14 ], + [ 64, -34 ] + ] + }, + "machine_disallowed_areas": { + "default_value": [ + [[-115, 112.5], [ -78, 112.5], [ -80, 102.5], [-115, 102.5]], + [[ 115, 112.5], [ 115, 102.5], [ 105, 102.5], [ 103, 112.5]], + [[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]], + [[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]] + ] + } + } +} diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json new file mode 100644 index 0000000000..f445057860 --- /dev/null +++ b/resources/definitions/ultimaker_original.def.json @@ -0,0 +1,68 @@ +{ + "id": "ultimaker_original", + "version": 2, + "name": "Ultimaker Original", + "inherits": "ultimaker", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "ultimaker_platform.stl", + "pages": [ + "SelectUpgradedParts", + "UpgradeFirmware", + "UltimakerCheckup", + "BedLeveling" + ] + }, + + "overrides": { + "machine_width": { + "default_value": 205 + }, + "machine_height": { + "default_value": 200 + }, + "machine_depth": { + "default_value": 205 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -75, 35 ], + [ -75, -18 ], + [ 18, 35 ], + [ 18, -18 ] + ] + }, + "gantry_height": { + "default_value": 55 + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": true + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json new file mode 100644 index 0000000000..830050beb0 --- /dev/null +++ b/resources/definitions/ultimaker_original_plus.def.json @@ -0,0 +1,26 @@ +{ + "id": "ultimaker_original_plus", + "version": 2, + "name": "Ultimaker Original+", + "inherits": "ultimaker_original", + "metadata": { + "author": "Ultimaker", + "manufacturer": "Ultimaker", + "category": "Ultimaker", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "UltimakerPlusbackplate.png", + "pages": [ + "UpgradeFirmware", + "UltimakerCheckup", + "BedLeveling" + ] + }, + + "overrides": { + "machine_heated_bed": { + "default_value": true + } + } +} diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json new file mode 100644 index 0000000000..1342e065a2 --- /dev/null +++ b/resources/definitions/uniqbot_one.def.json @@ -0,0 +1,55 @@ +{ + "id": "uniqbot_one", + "version": 2, + "name": "Uniqbot", + "inherits": "fdmprinter", + "metadata": { + "author": "Unimatech", + "manufacturer": "Unimatech", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker2.png" + }, + + "overrides": { + "machine_heated_bed": { + "default_value": false + }, + "machine_width": { + "default_value": 140 + }, + "machine_height": { + "default_value": 120 + }, + "machine_depth": { + "default_value": 160 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.5 + }, + "material_diameter": { + "default_value": 1.75 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 2 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 2 + }, + "gantry_height": { + "default_value": 55 + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode": { + "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." + }, + "machine_end_gcode": { + "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" + } + } +} diff --git a/resources/instances/high_quality.inst.cfg b/resources/instances/high_quality.inst.cfg new file mode 100644 index 0000000000..2e860cf380 --- /dev/null +++ b/resources/instances/high_quality.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = high +definition = fdmprinter + +[metadata] +type = quality + +[values] diff --git a/resources/instances/normal_quality.inst.cfg b/resources/instances/normal_quality.inst.cfg new file mode 100644 index 0000000000..6bb23d841c --- /dev/null +++ b/resources/instances/normal_quality.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = normal +definition = fdmprinter + +[metadata] +type = quality + +[values] diff --git a/resources/machines/RigidBot.json b/resources/machines/RigidBot.json deleted file mode 100644 index efd5a6e72c..0000000000 --- a/resources/machines/RigidBot.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "id": "rigidbot", - "version": 1, - "name": "RigidBot", - "manufacturer": "Other", - "author": "RBC", - "platform": "rigidbot_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - - "machine_width": { "default": 254 }, - "machine_depth": { "default": 254 }, - "machine_height": { "default": 254 }, - "machine_heated_bed": { "default": true }, - - "machine_nozzle_size": { "default": 0.4, - "visible": true - }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 0 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." - }, - "machine_end_gcode": { - "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" - } - }, - - "overrides": { - "layer_height": { "default": 0.2 }, - "wall_thickness": { "default": 0.8 }, - "top_bottom_thickness": { "default": 0.3, "visible": true }, - "material_print_temperature": { "default": 195, "visible": true }, - "material_bed_temperature": { "default": 60, "visible": true }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 60.0, "visible": true }, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 15.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": "0.1", "default": 15.0, "visible": true }, - "infill_overlap": { "default": 10.0 }, - "cool_fan_enabled": { "default": false, "visible": true }, - "cool_fan_speed": { "default": 0.0, "visible": true }, - "skirt_line_count": { "default": 3, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_gap": { "default": 4.0, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_minimal_length": { "default": 200.0, "active_if": { "setting": "adhesion_type", "value": "None" } } - } -} diff --git a/resources/machines/RigidBotBig.json b/resources/machines/RigidBotBig.json deleted file mode 100644 index 0f8fdb1481..0000000000 --- a/resources/machines/RigidBotBig.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "rigidbotbig", - "version": 1, - "name": "RigidBotBig", - "manufacturer": "Other", - "author": "RBC", - "platform": "rigidbotbig_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - - "machine_width": { "default": 400 }, - "machine_depth": { "default": 300 }, - "machine_height": { "default": 254 }, - "machine_heated_bed": { "default": true }, - - "machine_nozzle_size": { "default": 0.4}, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 0 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." - }, - "machine_end_gcode": { - "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" - } - }, - - "overrides": { - "layer_height": { "default": 0.2 }, - "wall_thickness": { "default": 0.8 }, - "top_bottom_thickness": { "default": 0.3, "visible": true }, - "material_print_temperature": { "default": 195, "visible": true }, - "material_bed_temperature": { "default": 60, "visible": true }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 60.0, "visible": true}, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 15.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": "0.1", "default": 15.0, "visible": true }, - "infill_overlap": { "default": 10.0 }, - "cool_fan_enabled": { "default": false, "visible": true}, - "cool_fan_speed": { "default": 0.0, "visible": true }, - "skirt_line_count": { "default": 3, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_gap": { "default": 4.0, "active_if": { "setting": "adhesion_type", "value": "None" } }, - "skirt_minimal_length": { "default": 200.0, "active_if": { "setting": "adhesion_type", "value": "None" } } - } -} diff --git a/resources/machines/bq_hephestos.json b/resources/machines/bq_hephestos.json deleted file mode 100644 index e3aa354b75..0000000000 --- a/resources/machines/bq_hephestos.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_hephestos", - "version": 1, - "name": "BQ Prusa i3 Hephestos", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 215 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 180 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -82, 0] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_hephestos_2.json b/resources/machines/bq_hephestos_2.json deleted file mode 100644 index d3af415b7a..0000000000 --- a/resources/machines/bq_hephestos_2.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "id": "bq_hephestos_2", - "version": 1, - "name": "BQ Hephestos 2", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_2_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 210 - }, - "machine_depth": { - "default": 297 - }, - "machine_height": { - "default": 220 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_platform_offset": { - "default": [6, 1320, 0] - }, - "material_print_temperature": { "default": 210.0, "visible": true }, - "material_bed_temperature": { "default": 0 }, - "material_diameter": { "default": 1.75 }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": true }, - "wall_line_count": { "default": 3, "visible": false }, - "wall_thickness": { "default": 1.2, "visible": false }, - "top_bottom_thickness": { "default": 1.2, "visible": false }, - "infill_sparse_density": { "default": 20.0 }, - "infill_overlap": { "default": 15.0, "visible": false }, - "speed_print": { "default": 60.0 }, - "speed_travel": { "default": 160.0 }, - "speed_layer_0": { "default": 30.0, "visible": true }, - "speed_wall_x": { "default": 35.0, "visible": false }, - "speed_wall_0": { "default": 30.0, "visible": false }, - "speed_infill": { "default": 80.0, "visible": true }, - "speed_topbottom": { "default": 35.0, "visible": false }, - "skirt_speed": { "default": 35.0, "visible": false }, - "skirt_line_count": { "default": 4 }, - "skirt_minimal_length": { "default": 30.0, "visible": false }, - "skirt_gap": { "default": 6.0 }, - "cool_fan_full_at_height": { "default": 0.4, "visible": false } - } -} diff --git a/resources/machines/bq_hephestos_xl.json b/resources/machines/bq_hephestos_xl.json deleted file mode 100644 index 5ce1dc3a7f..0000000000 --- a/resources/machines/bq_hephestos_xl.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_hephestos_xl", - "version": 1, - "name": "BQ Prusa i3 Hephestos XL", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_hephestos_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG1 Z10 ;move extruder up 10 mm\nG90 ;set to absolute positioning\nG1 X0 Y180 F1200 ;expose the platform\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 200 - }, - "machine_depth": { - "default": 300 - }, - "machine_height": { - "default": 180 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -82, 0] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_witbox.json b/resources/machines/bq_witbox.json deleted file mode 100644 index 83ac707ff6..0000000000 --- a/resources/machines/bq_witbox.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "id": "bq_witbox", - "version": 1, - "name": "BQ Witbox", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_witbox_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/sec\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM104 S0 ;set extruder temperature to zero (turned off)\nG91 ;set to relative positioning\nG1 E-20 F300 ;retract the filament a bit to release some of the pressure\nG90 ;set to absolute positioning\nG1 Z200 ;move the platform to the bottom\nG28 X0 Y0 ;move to the X/Y origin (Home)\nM84 ;turn off steppers\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 297 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 200 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -145, -38] - }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_thickness": { "default": 1.0, "visible": false }, - "top_bottom_thickness": { "default": 1.0, "visible": false}, - "bottom_thickness": { "default": 1.0, "visible": false }, - "material_print_temperature": { "default": 220, "visible": true }, - "material_bed_temperature": { "default": 0, "visible": false }, - "material_diameter": { "default": 1.75, "visible": true }, - "speed_print": { "default": 40.0}, - "speed_infill": { "default": 40.0, "visible": true }, - "speed_wall": { "default": 35.0, "visible": true}, - "speed_topbottom": { "default": 35.0, "visible": true }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0, "visible": false }, - "support_enable": { "default": true } - } -} diff --git a/resources/machines/bq_witbox_2.json b/resources/machines/bq_witbox_2.json deleted file mode 100644 index 61ce18a161..0000000000 --- a/resources/machines/bq_witbox_2.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "id": "bq_witbox_2", - "version": 1, - "name": "BQ Witbox 2", - "manufacturer": "Other", - "author": "BQ", - "platform": "bq_witbox_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_start_gcode": { - "default": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" - }, - "machine_end_gcode": { - "default": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" - }, - "machine_width": { - "default": 297 - }, - "machine_depth": { - "default": 210 - }, - "machine_height": { - "default": 200 - }, - "machine_heated_bed": { - "default": false - }, - "machine_center_is_zero": { - "default": false - }, - "machine_gcode_flavor": { - "default": "RepRap" - }, - "machine_platform_offset": { - "default": [0, -145, -38] - }, - "material_print_temperature": { "default": 210.0, "visible": true }, - "material_bed_temperature": { "default": 0 }, - "material_diameter": { "default": 1.75 }, - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": true }, - "wall_line_count": { "default": 3, "visible": false }, - "wall_thickness": { "default": 1.2, "visible": false }, - "top_bottom_thickness": { "default": 1.2, "visible": false }, - "infill_sparse_density": { "default": 20.0 }, - "infill_overlap": { "default": 15.0, "visible": false }, - "speed_print": { "default": 60.0 }, - "speed_travel": { "default": 160.0 }, - "speed_layer_0": { "default": 30.0, "visible": true }, - "speed_wall_x": { "default": 35.0, "visible": false }, - "speed_wall_0": { "default": 30.0, "visible": false }, - "speed_infill": { "default": 80.0, "visible": true }, - "speed_topbottom": { "default": 35.0, "visible": false }, - "skirt_speed": { "default": 35.0, "visible": false }, - "skirt_line_count": { "default": 4 }, - "skirt_minimal_length": { "default": 30.0, "visible": false }, - "skirt_gap": { "default": 6.0 }, - "cool_fan_full_at_height": { "default": 0.4, "visible": false }, - "support_enable": { "default": false } - } -} diff --git a/resources/machines/dual_extrusion_printer.json b/resources/machines/dual_extrusion_printer.json deleted file mode 100644 index 6506f0c7f8..0000000000 --- a/resources/machines/dual_extrusion_printer.json +++ /dev/null @@ -1,322 +0,0 @@ -{ - "version": 1, - "id": "dual_extrusion", - "name": "Dual Extrusion Base File", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g", - "inherits": "fdmprinter.json", - - "visible": false, - - "machine_extruder_trains": { - "0": { - "extruder_nr": { "default": 0 }, - "machine_nozzle_offset_x": { "default": 0.0 }, - "machine_nozzle_offset_y": { "default": 0.0 } - }, - "1": { - "extruder_nr": { "default": 1 } - } - }, - - "machine_settings": { - "machine_use_extruder_offset_to_offset_coords": { "default": false }, - - "machine_nozzle_offset_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_nozzle_offset_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_code": { "default": "", "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_start_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_abs": { "default": false, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_x": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_pos_y": { "default": 0, "SEE_machine_extruder_trains": true }, - "machine_extruder_end_code": { "default": "", "SEE_machine_extruder_trains": true } - }, - "overrides": { - "speed_print": { - "children": { - "speed_prime_tower": { - "label": "Prime Tower Speed", - "description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.", - "unit": "mm/s", - "type": "float", - "min_value": "0.1", - "max_value_warning": "150", - "default": 60, - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - }, - "line_width": { - "children": { - "prime_tower_line_width": { - "label": "Prime Tower Line Width", - "description": "Width of a single prime tower line.", - "unit": "mm", - "min_value": "0.0001", - "min_value_warning": "0.2", - "max_value_warning": "5", - "default": 0.4, - "type": "float", - "visible": false, - "enabled": "prime_tower_enable", - "global_only": true - } - } - } - }, - "categories": { - "dual": { - "label": "Dual Extrusion", - "visible": true, - "icon": "category_dual", - "settings": { - "extruder_nr": { - "label": "Extruder", - "description": "The extruder train used for printing. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "always_visible": true - }, - "adhesion_extruder_nr": { - "label": "Platform Adhesion Extruder", - "description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr": { - "label": "Support Extruder", - "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true, - "children": { - "support_infill_extruder_nr": { - "label": "Support Infill Extruder", - "description": "The extruder train to use for printing the infill of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_extruder_nr_layer_0": { - "label": "First Layer Support Extruder", - "description": "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "global_only": true - }, - "support_roof_extruder_nr": { - "label": "Support Roof Extruder", - "description": "The extruder train to use for printing the roof of the support. This is used in multi-extrusion.", - "type": "int", - "default": 0, - "min_value": "0", - "max_value": "machine_extruder_count - 1", - "enabled": "support_roof_enable", - "global_only": true - } - } - }, - "prime_tower_enable": { - "label": "Enable Prime Tower", - "description": "Print a tower next to the print which serves to prime the material after each nozzle switch.", - "type": "boolean", - "visible": true, - "default": false, - "global_only": true - }, - "prime_tower_size": { - "label": "Prime Tower Size", - "description": "The width of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 15, - "min_value": "0", - "max_value_warning": "20", - "inherit_function": "15 if prime_tower_enable else 0", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_x": { - "label": "Prime Tower X Position", - "description": "The x position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_position_y": { - "label": "Prime Tower Y Position", - "description": "The y position of the prime tower.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 200, - "min_value_warning": "-1000", - "max_value_warning": "1000", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_flow": { - "label": "Prime Tower Flow", - "description": "Flow compensation: the amount of material extruded is multiplied by this value.", - "visible": false, - "unit": "%", - "default": 100, - "type": "float", - "min_value": "5", - "min_value_warning": "50", - "max_value_warning": "150", - "enabled": "prime_tower_enable", - "global_only": true - }, - "prime_tower_wipe_enabled": { - "label": "Wipe Nozzle on Prime tower", - "description": "After printing the prime tower with the one nozzle, wipe the oozed material from the other nozzle off on the prime tower.", - "type": "boolean", - "default": false, - "enabled": "prime_tower_enable", - "global_only": true - }, - "multiple_mesh_overlap": { - "label": "Dual Extrusion Overlap", - "description": "Make the objects printed with different extruder trains overlap a bit. This makes the different materials bond together better.", - "visible": false, - "type": "float", - "unit": "mm", - "default": 0.15, - "min_value": "0", - "max_value_warning": "1.0" - }, - "ooze_shield_enabled": { - "label": "Enable Ooze Shield", - "description": "Enable exterior ooze shield. This will create a shell around the object which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", - "type": "boolean", - "default": false, - "global_only": true - }, - "ooze_shield_angle": { - "label": "Ooze Shield Angle", - "description": "The maximum angle a part in the ooze shield will have. With 0 degrees being vertical, and 90 degrees being horizontal. A smaller angle leads to less failed ooze shields, but more material.", - "unit": "°", - "type": "float", - "min_value": "0", - "max_value": "90", - "default": 60, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - }, - "ooze_shield_dist": { - "label": "Ooze Shields Distance", - "description": "Distance of the ooze shield from the print, in the X/Y directions.", - "unit": "mm", - "type": "float", - "min_value": "0", - "max_value_warning": "30", - "default": 2, - "visible": false, - "enabled": "ooze_shield_enabled", - "global_only": true - } - } - }, - "material": { - "settings": { - "material_standby_temperature": { - "label": "Standby Temperature", - "description": "The temperature of the nozzle when another nozzle is currently used for printing.", - "unit": "°C", - "type": "float", - "default": 150, - "min_value": "0", - "max_value_warning": "260", - "global_only": "True", - "visible": false - }, - "switch_extruder_retraction_amount": { - "label": "Nozzle Switch Retraction Distance", - "description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.", - "unit": "mm", - "type": "float", - "default": 20, - "min_value_warning": "0", - "max_value_warning": "100", - "visible": false, - "inherit_function": "machine_heat_zone_length", - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_retraction_speeds": { - "label": "Nozzle Switch Retraction Speed", - "description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "inherit": false, - "enabled": "retraction_enable", - "global_only": true, - "children": { - "switch_extruder_retraction_speed": { - "label": "Nozzle Switch Retract Speed", - "description": "The speed at which the filament is retracted during a nozzle switch retract. ", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - }, - "switch_extruder_prime_speed": { - "label": "Nozzle Switch Prime Speed", - "description": "The speed at which the filament is pushed back after a nozzle switch retraction.", - "unit": "mm/s", - "type": "float", - "default": 20, - "min_value": "0.1", - "max_value_warning": "300", - "visible": false, - "enabled": "retraction_enable", - "global_only": true - } - } - }, - "switch_extruder_retraction_hop": { - "label": "Nozzle Switch Z Hop", - "description": "Whenever the machine switches to another nozzle, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle which has been unused for a while from oozing material on the outside of the print.", - "unit": "mm", - "type": "float", - "default": 1.0, - "min_value_warning": "-0.0001", - "max_value_warning": "10", - "visible": false, - "inherit": false, - "enabled": "retraction_enable" - } - } - } - } -} diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index 3890d4182e..c85c46f786 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -121,15 +121,6 @@ "default": [], "global_only": true }, - "machine_platform_offset": { - "description": "Where to display the platform mesh.", - "default": [ - 0, - 0, - 0 - ], - "global_only": true - }, "machine_head_polygon": { "description": "A 2D silhouette of the print head (fan caps excluded).", "type": "polygon", diff --git a/resources/machines/grr_neo.json b/resources/machines/grr_neo.json deleted file mode 100644 index e2eb9aae73..0000000000 --- a/resources/machines/grr_neo.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "id": "grr_neo", - "version": 1, - "name": "German RepRap Neo", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker.png", - "platform": "grr_neo_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - "visible": "true", - - "overrides": { - "machine_width": { "default": 150 }, - "machine_height": { "default": 150 }, - "machine_depth": { "default": 150 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.5 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - }, - - "material_bed_temperature": { "visible": false } - } -} diff --git a/resources/machines/innovo-inventor.json b/resources/machines/innovo-inventor.json deleted file mode 100644 index a37143a8d7..0000000000 --- a/resources/machines/innovo-inventor.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "id": "innovo-inventor", - "version": 1, - "name": "Innovo INVENTOR", - "manufacturer": "Other", - "author": "AR", - "platform": "inventor_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "machine_settings": { - "machine_width": {"default": 340}, - "machine_height": {"default": 290}, - "machine_depth": {"default": 300}, - "machine_heated_bed": { "default": true}, - "machine_center_is_zero": {"default": false}, - "machine_nozzle_size": {"default": 0.4}, - "machine_head_shape_min_x": {"default": 43.7}, - "machine_head_shape_min_y": {"default": 19.2}, - "machine_head_shape_max_x": {"default": 43.7}, - "machine_head_shape_max_y": {"default": 55}, - "machine_nozzle_gantry_distance": {"default": 82.3}, - "machine_nozzle_offset_x_1": {"default": 0}, - "machine_nozzle_offset_y_1": {"default": 15}, - "machine_gcode_flavor": {"default": "RepRap (Marlin/Sprinter)"}, - "machine_start_gcode": {"default": "G28 ; Home extruder\nM107 ; Turn off fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\n{IF_BED}M190 S{BED}\n{IF_EXT0}M104 T0 S{TEMP0}\n{IF_EXT0}M109 T0 S{TEMP0}\n{IF_EXT1}M104 T1 S{TEMP1}\n{IF_EXT1}M109 T1 S{TEMP1}\nG32 S3 ; auto level\nG92 E0 ; Reset extruder position"}, - "machine_end_gcode": {"default": "M104 S0\nG91 ; relative positioning\nG1 E-2 F5000; retract 2mm\nG28 Z; move bed down\nG90 ; absolute positioning\nM84 ; disable motors"}, - "machine_platform_offset": {"default": [-180, -0.25, 160]} - }, - "overrides": { - "layer_height": { "default": 0.15}, - "wall_thickness": { "default": 0.8}, - "top_bottom_thickness": { "default": 0.3, "visible": true}, - "material_print_temperature": { "default": 215, "visible": true}, - "material_bed_temperature": { "default": 60, "visible": true}, - "material_diameter": { "default": 1.75, "visible": true}, - "speed_print": { "default": 60.0, "visible": true}, - "speed_infill": { "default": 100.0, "visible": true }, - "speed_topbottom": { "default": 30.0, "visible": true }, - "speed_travel": { "default": 150.0, "visible": true }, - "speed_layer_0": { "min_value": 0.1, "default": 30.0, "visible": true }, - "infill_overlap": { "default": 10.0 } - } -} \ No newline at end of file diff --git a/resources/machines/m180.json b/resources/machines/m180.json deleted file mode 100644 index 7e31577ac2..0000000000 --- a/resources/machines/m180.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "id": "m180", - "version": 1, - "name": "Malyan M180", - "manufacturer": "Other", - "icon": "icon_ultimaker.png", - "platform": "", - "file_formats": "application/x3g", - "inherits": "fdmprinter.json", - - "machine_settings": { - "machine_width": { "default": 230 }, - "machine_height": { "default": 165 }, - "machine_depth": { "default": 145 }, - "machine_center_is_zero": { "default": true }, - "machine_nozzle_size": { "default": 0.4, "min_value": "0.001" }, - "machine_head_with_fans_polygon": { - "default": [ - [ -75, 35 ], - [ -75, -18 ], - [ 18, -18 ], - [ 18, 35 ] - ] - }, - "gantry_height": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - "machine_start_gcode": { "default": "M136\nM73 P0\nM103\nG21\nG90\nM320\n;(**** begin homing ****)\nG162 X Y F4000\nG161 Z F3500\nG92 Z-5\nG1 Z0.0\nG161 Z F100\nM132 X Y Z A B\n;(**** end homing ****)\nG92 X147 Y66 Z5\nG1 X105 Y-60 Z10 F4000.0\nG130 X127 Y127 A127 B127\nG0 X105 Y-60\nG1 Z0.3 F300\nG92 E0\nG1 X100 E10 F300\nG92 E0\nG1 Z0.0 F300\nM320" }, - "machine_end_gcode": { "default": "G92 Z0\nG1 Z10 F400\nM18\nM109 S0 T0\nM104 S0 T0\nM73 P100 (end build progress)\nG162 X Y F3000\nM18" } - }, - - "overrides": { - "material_bed_temperature": { "visible": "True" }, - "material_diameter": { - "default": 1.75, - "min_value_warning": "1.5", - "max_value_warning": "2.0" - } - } -} diff --git a/resources/machines/maker_starter.json b/resources/machines/maker_starter.json deleted file mode 100644 index 1d6dfa6a18..0000000000 --- a/resources/machines/maker_starter.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "id": "maker_starter", - "version": 1, - "name": "3DMaker Starter", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "makerstarter_platform.stl", - "file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_width": { "default": 210 }, - "machine_depth": { "default": 185 }, - "machine_height": { "default": 200 }, - "machine_heated_bed": { "default": false }, - - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 0 }, - "machine_head_shape_min_y": { "default": 0 }, - "machine_head_shape_max_x": { "default": 0 }, - "machine_head_shape_max_y": { "default": 0 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap" }, - "machine_disallowed_areas": { "default": []}, - "machine_platform_offset": { "default": [0.0, 0.0, 0.0] }, - - "machine_nozzle_tip_outer_diameter": { "default": 1.0 }, - "machine_nozzle_head_distance": { "default": 3.0 }, - "machine_nozzle_expansion_angle": { "default": 45 }, - - "layer_height": { "default": 0.2 }, - "layer_height_0": { "default": 0.2, "visible": false }, - "wall_line_count": { "default": 2, "visible": true }, - "top_layers": { "default": 4, "visible": true }, - "bottom_layers": { "default": 4, "visible": true }, - "material_print_temperature": { "visible": false }, - "material_bed_temperature": { "visible": false }, - "material_diameter": { "default": 1.75, "visible": false }, - "material_flow": { "visible": false }, - "speed_print": { "default": 50.0 }, - "speed_wall": { "default": 30.0 }, - "speed_wall_0": { "default": 30.0 }, - "speed_wall_x": { "default": 30.0 }, - "speed_topbottom": { "default": 50.0 }, - "speed_support": { "default": 50.0 }, - "speed_travel": { "default": 120.0 }, - "speed_layer_0": { "default": 20.0 }, - "skirt_speed": { "default": 15.0 }, - "speed_slowdown_layers": { "default": 4 }, - "infill_sparse_density": { "default": 20.0 }, - "cool_fan_speed_min": { "default": 50.0 }, - "cool_fan_speed_max": { "default": 100.0 }, - "cool_fan_full_layer": { "default": 4, "visible": true }, - "cool_min_layer_time": { "default": 5.0 }, - "cool_min_layer_time_fan_speed_max": { "default": 10.0 }, - "support_type": { "default": "Everywhere" }, - "support_angle": { "default": 45.0, "visible": true }, - "support_xy_distance": { "default": 1 }, - "support_z_distance": { "default": 0.2 }, - "support_top_distance": { "default": 0.2 }, - "support_bottom_distance": { "default": 0.24 }, - "support_pattern": { "default": "ZigZag" }, - "support_infill_rate": { "default": 15, "visible": true }, - "adhesion_type": { "default": "Raft" }, - "skirt_minimal_length": { "default": 100.0 }, - "raft_base_line_spacing": { "default": 2.0 }, - "raft_base_thickness": { "default": 0.3 }, - "raft_base_line_width": { "default": 2.0 }, - "raft_base_speed": { "default": 15.0 }, - "raft_interface_thickness": { "default": 0.24 }, - "raft_interface_line_width": { "default": 0.6 }, - "raft_airgap": { "default": 0.2 }, - "raft_surface_layers": { "default": 2 } - } -} - - diff --git a/resources/machines/prusa_i3.json b/resources/machines/prusa_i3.json deleted file mode 100644 index dcbca32801..0000000000 --- a/resources/machines/prusa_i3.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "prusa_i3", - "version": 1, - "name": "Prusa i3", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "prusai3_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": true }, - "machine_width": { "default": 200 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 200 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} diff --git a/resources/machines/prusa_i3_xl.json b/resources/machines/prusa_i3_xl.json deleted file mode 100644 index b66b974983..0000000000 --- a/resources/machines/prusa_i3_xl.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "id": "prusa_i3_xl", - "version": 1, - "name": "Prusa i3 xl", - "manufacturer": "Other", - "author": "Other", - "icon": "icon_ultimaker2.png", - "platform": "prusai3_xl_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": true }, - "machine_width": { "default": 200 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 270 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_shape_min_x": { "default": 75 }, - "machine_head_shape_min_y": { "default": 18 }, - "machine_head_shape_max_x": { "default": 18 }, - "machine_head_shape_max_y": { "default": 35 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} diff --git a/resources/machines/ultimaker.json b/resources/machines/ultimaker.json deleted file mode 100644 index a7a9cd3994..0000000000 --- a/resources/machines/ultimaker.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "id": "ultimaker_base", - "version": 1, - "visible": false, - "name": "Ultimaker", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "inherits": "fdmprinter.json", - - "machine_preferences": { - "prefered_profile": "Normal Quality", - "prefered_variant": "0.4 mm", - "prefered_material": "PLA" - } -} diff --git a/resources/machines/ultimaker2.json b/resources/machines/ultimaker2.json deleted file mode 100644 index e19aec1336..0000000000 --- a/resources/machines/ultimaker2.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "id": "ultimaker2", - "version": 1, - "name": "Ultimaker 2", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2backplate.png", - "file_formats": "text/x-gcode", - - "inherits": "ultimaker.json", - - "machine_extruder_trains": { - "0": { - "machine_nozzle_heat_up_speed": { - "default": 2.0 - }, - "machine_nozzle_cool_down_speed": { - "default": 2.0 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - } - }, - "machine_settings": { - "machine_start_gcode" : { "default": "" }, - "machine_end_gcode" : { "default": "" }, - "machine_width": { "default": 223 }, - "machine_depth": { "default": 223 }, - "machine_height": { "default": 205 }, - "machine_heated_bed": { "default": true }, - - "machine_head_with_fans_polygon": - { - "default": [ - [ - -42, - 12 - ], - [ - -42, - -32 - ], - [ - 62, - 12 - ], - [ - 62, - -32 - ] - ] - }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4, "min_value": "0.001"}, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "gantry_height": { "default": 55 }, - "machine_use_extruder_offset_to_offset_coords": { "default": true }, - "machine_gcode_flavor": { "default": "UltiGCode" }, - "machine_disallowed_areas": { "default": [ - [[-115.0, 112.5], [ -82.0, 112.5], [ -84.0, 102.5], [-115.0, 102.5]], - [[ 115.0, 112.5], [ 115.0, 102.5], [ 110.0, 102.5], [ 108.0, 112.5]], - [[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]], - [[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]] - ]}, - "machine_platform_offset": { "default": [9.0, 0.0, 0.0] }, - - "machine_nozzle_tip_outer_diameter": { "default": 1.0 }, - "machine_nozzle_head_distance": { "default": 3.0 }, - "machine_nozzle_expansion_angle": { "default": 45 } - }, - - "overrides": { - "material_print_temperature": { "enabled": "False" }, - "material_bed_temperature": { "enabled": "False" }, - "material_diameter": { "enabled": "False" }, - "material_flow": { "enabled": "False" }, - "retraction_amount": { "enabled": "False" }, - "retraction_speed": { "enabled": "False" }, - "retraction_retract_speed": { "enabled": "False" }, - "retraction_prime_speed": { "enabled": "False" } - } -} diff --git a/resources/machines/ultimaker2_extended.json b/resources/machines/ultimaker2_extended.json deleted file mode 100644 index 0cd5ff0002..0000000000 --- a/resources/machines/ultimaker2_extended.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "id": "ultimaker2_extended", - "version": 1, - "name": "Ultimaker 2 Extended", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Extendedbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "machine_settings": { - "machine_height": { "default": 315 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus.json b/resources/machines/ultimaker2_extended_plus.json deleted file mode 100644 index 34a1f894bb..0000000000 --- a/resources/machines/ultimaker2_extended_plus.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "id": "ultimaker2_extended_plus_base", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "visible": false, - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "machine_settings": { - "machine_height": { "default": 305}, - "machine_show_variants": { "default": true }, - "machine_nozzle_head_distance": { "default": 5 }, - "machine_nozzle_expansion_angle": { "default": 45 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_025.json b/resources/machines/ultimaker2_extended_plus_025.json deleted file mode 100644 index 187079aa33..0000000000 --- a/resources/machines/ultimaker2_extended_plus_025.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.25 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.25 }, - "machine_nozzle_tip_outer_diameter": { "default": 0.8 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_040.json b/resources/machines/ultimaker2_extended_plus_040.json deleted file mode 100644 index b548bbe423..0000000000 --- a/resources/machines/ultimaker2_extended_plus_040.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.4 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.40 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.05 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_060.json b/resources/machines/ultimaker2_extended_plus_060.json deleted file mode 100644 index 9d39c267ba..0000000000 --- a/resources/machines/ultimaker2_extended_plus_060.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.6 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.60 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.25 } - } -} diff --git a/resources/machines/ultimaker2_extended_plus_080.json b/resources/machines/ultimaker2_extended_plus_080.json deleted file mode 100644 index bf74998f57..0000000000 --- a/resources/machines/ultimaker2_extended_plus_080.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "id": "ultimaker2_extended_plus", - "version": 1, - "name": "Ultimaker 2 Extended+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2ExtendedPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2_extended_plus.json", - "variant": "0.8 mm", - "profiles_machine": "ultimaker2plus", - "machine_settings": { - "machine_nozzle_size": { "default": 0.80 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.35 } - } -} diff --git a/resources/machines/ultimaker2_go.json b/resources/machines/ultimaker2_go.json deleted file mode 100644 index cc2cde09d7..0000000000 --- a/resources/machines/ultimaker2_go.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "id": "ultimaker2_go", - "version": 1, - "name": "Ultimaker 2 Go", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker2.png", - "platform": "ultimaker2go_platform.obj", - "platform_texture": "Ultimaker2Gobackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "overrides": { - "machine_width": { "default": 120 }, - "machine_depth": { "default": 120 }, - "machine_height": { "default": 115 }, - "machine_heated_bed": { "default": false }, - "machine_disallowed_areas": { "default": [ - [[-60.0, 60.0], [-33.0, 60.0], [-35.0, 52.0], [-60.0, 52.0]], - [[ 60.0, 60.0], [ 60.0, 52.0], [ 35.0, 52.0], [ 33.0, 60.0]], - [[-60.0, -60.0], [-60.0, -52.0], [-35.0, -52.0], [-33.0, -60.0]], - [[ 60.0, -60.0], [ 33.0, -60.0], [ 35.0, -52.0], [ 60.0, -52.0]] - ]}, - "machine_platform_offset": { "default": [0.0, 0.0, 0.0] } - } -} diff --git a/resources/machines/ultimaker2plus.json b/resources/machines/ultimaker2plus.json deleted file mode 100644 index d9a1fdf22d..0000000000 --- a/resources/machines/ultimaker2plus.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "id": "ultimaker2plus_base", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "visible": false, - "file_formats": "text/x-gcode", - "inherits": "ultimaker2.json", - - "overrides": { - "speed_infill": { "inherit_function": "speed_print" }, - "speed_wall_x": { "inherit_function": "speed_wall" }, - "layer_height_0": { "inherit_function": "round(machine_nozzle_size / 1.5, 2)" }, - "line_width": { "inherit_function": "round(machine_nozzle_size * 0.875, 2)" }, - "speed_layer_0": { "default": "20" }, - "speed_support": { "inherit_function": "speed_wall_0" }, - "machine_show_variants": { "default": true }, - "gantry_height": { "default": 52 }, - "machine_nozzle_head_distance": { "default": 5 }, - "machine_nozzle_expansion_angle": { "default": 45 }, - "machine_heat_zone_length": { "default": 20 }, - "machine_head_with_fans_polygon": - { - "default": [ - [ - -44, - 14 - ], - [ - -44, - -34 - ], - [ - 64, - 14 - ], - [ - 64, - -34 - ] - ] - }, - "machine_disallowed_areas": { "default": [ - [[-115.0, 112.5], [ -78.0, 112.5], [ -80.0, 102.5], [-115.0, 102.5]], - [[ 115.0, 112.5], [ 115.0, 102.5], [ 105.0, 102.5], [ 103.0, 112.5]], - [[-115.0, -112.5], [-115.0, -104.5], [ -84.0, -104.5], [ -82.0, -112.5]], - [[ 115.0, -112.5], [ 108.0, -112.5], [ 110.0, -104.5], [ 115.0, -104.5]] - ]} - } -} diff --git a/resources/machines/ultimaker2plus_025.json b/resources/machines/ultimaker2plus_025.json deleted file mode 100644 index 2c022f8448..0000000000 --- a/resources/machines/ultimaker2plus_025.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.25 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.2, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 5 else (speed_wall - 5)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 1.5, 1)" }, - "machine_nozzle_size": { "default": 0.25 }, - "machine_nozzle_tip_outer_diameter": { "default": 0.8 }, - "coasting_volume": { "default": 0.1 }, - "coasting_min_volume": { "default": 0.17 } - } -} diff --git a/resources/machines/ultimaker2plus_040.json b/resources/machines/ultimaker2plus_040.json deleted file mode 100644 index f5a0f5a710..0000000000 --- a/resources/machines/ultimaker2plus_040.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.4 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.25, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2.25, 1)" }, - "machine_nozzle_size": { "default": 0.40 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.05 } - } -} diff --git a/resources/machines/ultimaker2plus_060.json b/resources/machines/ultimaker2plus_060.json deleted file mode 100644 index 89538f2fd0..0000000000 --- a/resources/machines/ultimaker2plus_060.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.6 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.333333, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2, 1)" }, - "machine_nozzle_size": { "default": 0.60 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.25 }, - "coasting_volume": { "default": 1.36 } - } -} diff --git a/resources/machines/ultimaker2plus_080.json b/resources/machines/ultimaker2plus_080.json deleted file mode 100644 index e231fbb9f5..0000000000 --- a/resources/machines/ultimaker2plus_080.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker2plus", - "version": 1, - "name": "Ultimaker 2+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "platform": "ultimaker2_platform.obj", - "platform_texture": "Ultimaker2Plusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker2plus.json", - - "variant": "0.8 mm", - - "overrides": { - "speed_wall": { "inherit_function": "round(speed_print / 1.333333, 1)" }, - "speed_wall_0": { "inherit_function": "1 if speed_wall < 10 else (speed_wall - 10)" }, - "speed_topbottom": { "inherit_function": "round(speed_print / 2, 1)" }, - "machine_nozzle_size": { "default": 0.80 }, - "machine_nozzle_tip_outer_diameter": { "default": 1.35 }, - "coasting_volume": { "default": 3.22 } - } -} diff --git a/resources/machines/ultimaker_original.json b/resources/machines/ultimaker_original.json deleted file mode 100644 index 3e694c1b8e..0000000000 --- a/resources/machines/ultimaker_original.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "id": "ultimaker_original", - "version": 1, - "name": "Ultimaker Original", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker.png", - "platform": "ultimaker_platform.stl", - "file_formats": "text/x-gcode", - "inherits": "ultimaker.json", - - "pages": [ - "SelectUpgradedParts", - "UpgradeFirmware", - "UltimakerCheckup", - "BedLeveling" - ], - - "machine_extruder_trains": { - "0": { - "machine_nozzle_heat_up_speed": { - "default": 2.0 - }, - "machine_nozzle_cool_down_speed": { - "default": 2.0 - }, - "machine_nozzle_tip_outer_diameter": { - "default": 1 - }, - "machine_nozzle_head_distance": { - "default": 3 - }, - "machine_nozzle_expansion_angle": { - "default": 45 - }, - "machine_heat_zone_length": { - "default": 16 - } - } - }, - "overrides": { - "machine_width": { "default": 205 }, - "machine_height": { "default": 200 }, - "machine_depth": { "default": 205 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.4 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_head_with_fans_polygon": - { - "default": [ - [ - -75, - 35 - ], - [ - -75, - -18 - ], - [ - 18, - 35 - ], - [ - 18, - -18 - ] - ] - }, - "gantry_height": { "default": 55 }, - "machine_use_extruder_offset_to_offset_coords": { "default": true }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - }, - - "machine_extruder_drive_upgrade": { "default": false } - } -} diff --git a/resources/machines/ultimaker_original_plus.json b/resources/machines/ultimaker_original_plus.json deleted file mode 100644 index 07c5a04549..0000000000 --- a/resources/machines/ultimaker_original_plus.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "id": "ultimaker_original_plus", - "version": 1, - "name": "Ultimaker Original+", - "manufacturer": "Ultimaker", - "author": "Ultimaker", - "icon": "icon_ultimaker.png", - "platform": "ultimaker2_platform.obj", - "platform_texture": "UltimakerPlusbackplate.png", - "file_formats": "text/x-gcode", - "inherits": "ultimaker_original.json", - - "pages": [ - "UpgradeFirmware", - "UltimakerCheckup", - "BedLeveling" - ], - - "overrides": { - "machine_heated_bed": { "default": true } - } -} diff --git a/resources/machines/uniqbot_one.json b/resources/machines/uniqbot_one.json deleted file mode 100644 index d1343e6c54..0000000000 --- a/resources/machines/uniqbot_one.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "id": "uniqbot_one", - "version": 1, - "name": "Uniqbot", - "manufacturer": "Other", - "author": "Unimatech", - "icon": "icon_ultimaker2.png", - "file_formats": "text/x-gcode", - "inherits": "fdmprinter.json", - - "overrides": { - "machine_heated_bed": { "default": false }, - "machine_width": { "default": 140 }, - "machine_height": { "default": 120 }, - "machine_depth": { "default": 160 }, - "machine_center_is_zero": { "default": false }, - "machine_nozzle_size": { "default": 0.5 }, - "material_diameter": { "default": 1.75 }, - "machine_nozzle_heat_up_speed": { "default": 2.0 }, - "machine_nozzle_cool_down_speed": { "default": 2.0 }, - "machine_nozzle_gantry_distance": { "default": 55 }, - "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, - - "machine_start_gcode": { - "default": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." - }, - "machine_end_gcode": { - "default": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" - } - } -} diff --git a/resources/materials/abs.inst.cfg b/resources/materials/abs.inst.cfg new file mode 100644 index 0000000000..0d64e81437 --- /dev/null +++ b/resources/materials/abs.inst.cfg @@ -0,0 +1,12 @@ +[general] +version = 2 +name = ABS +definition = fdmprinter + +[metadata] +type = material + +[values] +material_print_temperature = 250 +material_bed_temperature = 80 +material_flow = 107 diff --git a/resources/materials/cpe.inst.cfg b/resources/materials/cpe.inst.cfg new file mode 100644 index 0000000000..ca30cba046 --- /dev/null +++ b/resources/materials/cpe.inst.cfg @@ -0,0 +1,11 @@ +[general] +version = 2 +name = CPE +definition = fdmprinter + +[metadata] +type = material + +[values] +material_print_temperature = 250 +material_bed_temperature = 70 \ No newline at end of file diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material new file mode 100644 index 0000000000..a4fe02c195 --- /dev/null +++ b/resources/materials/generic_pla.xml.fdm_material @@ -0,0 +1,47 @@ + + + + + + Generic + PLA + Generic + + 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 + 0 + #FFFFFF + + + 1.3 + 2.85 + + + 210 + 60 + 175 + + + + + 150 + + + + + + + + + + 150 + + 80 + + + 100 + + + + diff --git a/resources/materials/pla.inst.cfg b/resources/materials/pla.inst.cfg new file mode 100644 index 0000000000..dfa9c62469 --- /dev/null +++ b/resources/materials/pla.inst.cfg @@ -0,0 +1,10 @@ +[general] +version = 2 +name = PLA +definition = fdmprinter + +[metadata] +type = material + +[values] +material_bed_temperature = 60 diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 33754c71ab..f3bce7b993 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -1,6 +1,8 @@ // Copyright (c) 2015 Ultimaker B.V. // Cura is released under the terms of the AGPLv3 or higher. +pragma Singleton + import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.1 as UM @@ -45,6 +47,8 @@ Item property alias toggleFullScreen: toggleFullScreenAction; + property alias configureSettingVisibility: configureSettingVisibilityAction + UM.I18nCatalog{id: catalog; name:"cura"} Action @@ -60,6 +64,8 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Undo"); iconName: "edit-undo"; shortcut: StandardKey.Undo; + onTriggered: UM.OperationStack.undo(); + enabled: UM.OperationStack.canUndo; } Action @@ -68,6 +74,8 @@ Item text: catalog.i18nc("@action:inmenu menubar:edit","&Redo"); iconName: "edit-redo"; shortcut: StandardKey.Redo; + onTriggered: UM.OperationStack.redo(); + enabled: UM.OperationStack.canRedo; } Action @@ -103,6 +111,7 @@ Item id: updateProfileAction; enabled: UM.ActiveProfile.valid && !UM.ActiveProfile.readOnly && UM.ActiveProfile.hasCustomisedValues text: catalog.i18nc("@action:inmenu menubar:profile","&Update Current Profile"); + onTriggered: UM.ActiveProfile.updateProfile(); } Action @@ -110,6 +119,7 @@ Item id: resetProfileAction; enabled: UM.ActiveProfile.valid && UM.ActiveProfile.hasCustomisedValues text: catalog.i18nc("@action:inmenu menubar:profile","&Reload Current Profile"); + onTriggered: UM.ActiveProfile.discardChanges(); } Action @@ -132,12 +142,14 @@ Item text: catalog.i18nc("@action:inmenu menubar:help","Show Online &Documentation"); iconName: "help-contents"; shortcut: StandardKey.Help; + onTriggered: CuraActions.openDocumentation(); } Action { id: reportBugAction; text: catalog.i18nc("@action:inmenu menubar:help","Report a &Bug"); iconName: "tools-report-bug"; + onTriggered: CuraActions.openBugReportPage(); } Action @@ -154,6 +166,7 @@ Item enabled: UM.Controller.toolsEnabled; iconName: "edit-delete"; shortcut: StandardKey.Delete; + onTriggered: Printer.deleteSelection(); } Action @@ -177,6 +190,7 @@ Item enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "object-group" shortcut: "Ctrl+G"; + onTriggered: Printer.groupSelected(); } Action @@ -186,6 +200,7 @@ Item enabled: UM.Scene.isGroupSelected iconName: "object-ungroup" shortcut: "Ctrl+Shift+G"; + onTriggered: Printer.ungroupSelected(); } Action @@ -195,6 +210,7 @@ Item enabled: UM.Scene.numObjectsSelected > 1 ? true: false iconName: "merge"; shortcut: "Ctrl+Alt+G"; + onTriggered: Printer.mergeSelected(); } Action @@ -211,6 +227,7 @@ Item enabled: UM.Controller.toolsEnabled; iconName: "edit-delete"; shortcut: "Ctrl+D"; + onTriggered: Printer.deleteAll(); } Action @@ -218,18 +235,21 @@ Item id: reloadAllAction; text: catalog.i18nc("@action:inmenu menubar:file","Re&load All Objects"); iconName: "document-revert"; + onTriggered: Printer.reloadAll(); } Action { id: resetAllTranslationAction; text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Object Positions"); + onTriggered: Printer.resetAllTranslation(); } Action { id: resetAllAction; text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Object &Transformations"); + onTriggered: Printer.resetAll(); } Action @@ -247,4 +267,10 @@ Item iconName: "view-list-text"; shortcut: StandardKey.WhatsThis; } + + Action + { + id: configureSettingVisibilityAction + text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); + } } diff --git a/resources/qml/AddMachineDialog.qml b/resources/qml/AddMachineDialog.qml new file mode 100644 index 0000000000..4a5e14f183 --- /dev/null +++ b/resources/qml/AddMachineDialog.qml @@ -0,0 +1,178 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.1 + +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + + +UM.Dialog +{ + id: base + title: catalog.i18nc("@title:window", "Add Printer") + property string activeManufacturer: "Ultimaker"; + + function getMachineName() + { + var name = machineList.model.getItem(machineList.currentIndex).name + return name + } + + ScrollView + { + id: machinesHolder + + anchors + { + left: parent.left; + top: parent.top; + right: parent.right; + bottom: parent.bottom; + } + ListView + { + id: machineList + + model: UM.DefinitionContainersModel + { + id: machineDefinitionsModel + filter: {"visible":true} + } + section.property: "manufacturer" + section.delegate: Button + { + text: section + style: ButtonStyle + { + background: Rectangle + { + border.width: 0 + color: "transparent"; + height: UM.Theme.getSize("standard_list_lineheight").height + width: machineList.width + } + label: Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("standard_arrow").width + UM.Theme.getSize("default_margin").width + text: control.text + color: palette.windowText + font.bold: true + UM.RecolorImage + { + id: downArrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: width + color: palette.windowText + source: base.activeManufacturer == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right") + } + } + } + + onClicked: + { + base.activeManufacturer = section; + machineList.currentIndex = machineList.model.find("manufacturer", section) + machineName.text = getMachineName() + } + } + + delegate: RadioButton + { + id: machineButton + + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("standard_list_lineheight").width + + opacity: 1; + height: UM.Theme.getSize("standard_list_lineheight").height; + + checked: ListView.isCurrentItem; + + exclusiveGroup: printerGroup; + + text: model.name + + onClicked: + { + ListView.view.currentIndex = index; + machineName.text = getMachineName() + } + + states: State + { + name: "collapsed"; + when: base.activeManufacturer != model.manufacturer; + + PropertyChanges { target: machineButton; opacity: 0; height: 0; } + } + + transitions: + [ + Transition + { + to: "collapsed"; + SequentialAnimation + { + NumberAnimation { property: "opacity"; duration: 75; } + NumberAnimation { property: "height"; duration: 75; } + } + }, + Transition + { + from: "collapsed"; + SequentialAnimation + { + NumberAnimation { property: "height"; duration: 75; } + NumberAnimation { property: "opacity"; duration: 75; } + } + } + ] + } + } + } + + TextField + { + id: machineName; + text: getMachineName() + implicitWidth: UM.Theme.getSize("standard_list_input").width + maximumLength: 40 + anchors.bottom:parent.bottom + } + + Button + { + text:"save" + anchors.bottom: parent.bottom + anchors.right: parent.right + onClicked: + { + base.visible = false + var item = machineList.model.getItem(machineList.currentIndex); + Cura.MachineManager.addMachine(machineName.text, item.id) + } + } + + Item + { + UM.I18nCatalog + { + id: catalog; + name: "cura"; + } + SystemPalette { id: palette } + ExclusiveGroup { id: printerGroup; } + } +} diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index ccaeb63c4e..6ea69c428b 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -7,7 +7,10 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import QtQuick.Dialogs 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura + +import "." UM.MainWindow { @@ -53,7 +56,7 @@ UM.MainWindow title: catalog.i18nc("@title:menu menubar:toplevel","&File"); MenuItem { - action: actions.open; + action: Actions.open; } Menu @@ -115,11 +118,11 @@ UM.MainWindow } } - MenuItem { action: actions.reloadAll; } + MenuItem { action: Actions.reloadAll; } MenuSeparator { } - MenuItem { action: actions.quit; } + MenuItem { action: Actions.quit; } } Menu @@ -127,17 +130,17 @@ UM.MainWindow //: Edit menu title: catalog.i18nc("@title:menu menubar:toplevel","&Edit"); - MenuItem { action: actions.undo; } - MenuItem { action: actions.redo; } + MenuItem { action: Actions.undo; } + MenuItem { action: Actions.redo; } MenuSeparator { } - MenuItem { action: actions.deleteSelection; } - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } + MenuItem { action: Actions.deleteSelection; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } MenuSeparator { } - MenuItem { action: actions.groupObjects;} - MenuItem { action: actions.mergeObjects;} - MenuItem { action: actions.unGroupObjects;} + MenuItem { action: Actions.groupObjects;} + MenuItem { action: Actions.mergeObjects;} + MenuItem { action: Actions.unGroupObjects;} } Menu @@ -168,14 +171,17 @@ UM.MainWindow Instantiator { - model: UM.MachineInstancesModel { } + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + } MenuItem { text: model.name; checkable: true; - checked: model.active; - exclusiveGroup: machineMenuGroup; - onTriggered: UM.MachineManager.setActiveMachineInstance(model.name) + checked: Cura.MachineManager.activeMachineId == model.id + exclusiveGroup: machineSelectionMenuGroup; + onTriggered: Cura.MachineManager.setActiveMachine(model.id); } onObjectAdded: machineMenu.insertItem(index, object) onObjectRemoved: machineMenu.removeItem(object) @@ -187,13 +193,20 @@ UM.MainWindow Instantiator { - model: UM.MachineVariantsModel { } + model: UM.InstanceContainersModel + { + filter: + { + "type": "variant", + "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine + } + } MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeVariantId; exclusiveGroup: machineVariantsGroup; - onTriggered: UM.MachineManager.setActiveMachineVariant(model.name) + onTriggered: Cura.MachineManager.setActiveVariant(model.id) } onObjectAdded: machineMenu.insertItem(index, object) onObjectRemoved: machineMenu.removeItem(object) @@ -201,10 +214,10 @@ UM.MainWindow ExclusiveGroup { id: machineVariantsGroup; } - MenuSeparator { visible: UM.MachineManager.hasVariants; } + MenuSeparator { visible: Cura.MachineManager.hasVariants; } - MenuItem { action: actions.addMachine; } - MenuItem { action: actions.configureMachines; } + MenuItem { action: Actions.addMachine; } + MenuItem { action: Actions.configureMachines; } } Menu @@ -215,7 +228,7 @@ UM.MainWindow Instantiator { id: profileMenuInstantiator - model: UM.ProfilesModel {} +// model: UM.ProfilesModel {} property int separatorIndex: -1 Loader { @@ -277,11 +290,11 @@ UM.MainWindow MenuSeparator { id: profileMenuSeparator } - MenuItem { action: actions.updateProfile; } - MenuItem { action: actions.resetProfile; } - MenuItem { action: actions.addProfile; } + MenuItem { action: Actions.updateProfile; } + MenuItem { action: Actions.resetProfile; } + MenuItem { action: Actions.addProfile; } MenuSeparator { } - MenuItem { action: actions.manageProfiles; } + MenuItem { action: Actions.manageProfiles; } } Menu @@ -292,7 +305,7 @@ UM.MainWindow Instantiator { - model: UM.Models.extensionModel + model: UM.ExtensionModel { } Menu { @@ -323,7 +336,7 @@ UM.MainWindow //: Settings menu title: catalog.i18nc("@title:menu menubar:toplevel","&Settings"); - MenuItem { action: actions.preferences; } + MenuItem { action: Actions.preferences; } } Menu @@ -331,11 +344,11 @@ UM.MainWindow //: Help menu title: catalog.i18nc("@title:menu menubar:toplevel","&Help"); - MenuItem { action: actions.showEngineLog; } - MenuItem { action: actions.documentation; } - MenuItem { action: actions.reportBug; } + MenuItem { action: Actions.showEngineLog; } + MenuItem { action: Actions.documentation; } + MenuItem { action: Actions.reportBug; } MenuSeparator { } - MenuItem { action: actions.about; } + MenuItem { action: Actions.about; } } } @@ -425,7 +438,7 @@ UM.MainWindow left: parent.left; //leftMargin: UM.Theme.getSize("loadfile_margin").width } - action: actions.open; + action: Actions.open; } Image @@ -513,22 +526,12 @@ UM.MainWindow width: UM.Theme.getSize("sidebar").width; - addMachineAction: actions.addMachine; - configureMachinesAction: actions.configureMachines; - addProfileAction: actions.addProfile; - updateProfileAction: actions.updateProfile; - resetProfileAction: actions.resetProfile; - manageProfilesAction: actions.manageProfiles; - - configureSettingsAction: Action - { - onTriggered: - { - preferences.visible = true; - preferences.setPage(2); - preferences.getCurrentItem().scrollToSection(source.key); - } - } + addMachineAction: Actions.addMachine; + configureMachinesAction: Actions.configureMachines; + addProfileAction: Actions.addProfile; + updateProfileAction: Actions.updateProfile; + resetProfileAction: Actions.resetProfile; + manageProfilesAction: Actions.manageProfiles; } } } @@ -546,6 +549,12 @@ UM.MainWindow //: View preferences page title insertPage(1, catalog.i18nc("@title:tab","View"), Qt.resolvedUrl("ViewPage.qml")); + insertPage(3, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("MachinesPage.qml")); + + insertPage(4, catalog.i18nc("@title:tab", "Materials"), Qt.resolvedUrl("Preferences/MaterialsPage.qml")); + + insertPage(5, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml")); + //Force refresh setPage(0); } @@ -561,73 +570,16 @@ UM.MainWindow } } - Actions + Connections { - id: actions; + target: Actions.preferences + onTriggered: preferences.visible = true + } - open.onTriggered: openDialog.open(); - - quit.onTriggered: base.visible = false; - - undo.onTriggered: UM.OperationStack.undo(); - undo.enabled: UM.OperationStack.canUndo; - redo.onTriggered: UM.OperationStack.redo(); - redo.enabled: UM.OperationStack.canRedo; - - deleteSelection.onTriggered: - { - Printer.deleteSelection(); - } - - deleteObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.deleteObject(objectContextMenu.objectId); - objectContextMenu.objectId = 0; - } - } - - multiplyObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.multiplyObject(objectContextMenu.objectId, 1); - objectContextMenu.objectId = 0; - } - } - - centerObject.onTriggered: - { - if(objectContextMenu.objectId != 0) - { - Printer.centerObject(objectContextMenu.objectId); - objectContextMenu.objectId = 0; - } - } - - groupObjects.onTriggered: - { - Printer.groupSelected(); - } - - unGroupObjects.onTriggered: - { - Printer.ungroupSelected(); - } - - mergeObjects.onTriggered: - { - Printer.mergeSelected(); - } - - deleteAll.onTriggered: Printer.deleteAll(); - resetAllTranslation.onTriggered: Printer.resetAllTranslation(); - resetAll.onTriggered: Printer.resetAll(); - reloadAll.onTriggered: Printer.reloadAll(); - - addMachine.onTriggered: addMachineWizard.visible = true; - addProfile.onTriggered: + Connections + { + target: Actions.addProfile + onTriggered: { UM.MachineManager.createProfile(); preferences.setPage(4); @@ -636,26 +588,37 @@ UM.MainWindow // Show the renameDialog after a very short delay so the preference page has time to initiate showProfileNameDialogTimer.start(); } - updateProfile.onTriggered: UM.ActiveProfile.updateProfile(); - resetProfile.onTriggered: UM.ActiveProfile.discardChanges(); + } - preferences.onTriggered: preferences.visible = true; - configureMachines.onTriggered: + Connections + { + target: Actions.configureMachines + onTriggered: { preferences.visible = true; preferences.setPage(3); } - manageProfiles.onTriggered: + } + + Connections + { + target: Actions.manageProfiles + onTriggered: { preferences.visible = true; preferences.setPage(4); } + } - documentation.onTriggered: CuraActions.openDocumentation(); - reportBug.onTriggered: CuraActions.openBugReportPage(); - showEngineLog.onTriggered: engineLog.visible = true; - about.onTriggered: aboutDialog.visible = true; - toggleFullScreen.onTriggered: base.toggleFullscreen(); + Connections + { + target: Actions.configureSettingVisibility + onTriggered: + { + preferences.visible = true; + preferences.setPage(2); + preferences.getCurrentItem().scrollToSection(source.key); + } } Timer @@ -672,31 +635,70 @@ UM.MainWindow id: objectContextMenu; property variant objectId: -1; - MenuItem { action: actions.centerObject; } - MenuItem { action: actions.deleteObject; } - MenuItem { action: actions.multiplyObject; } + MenuItem { action: Actions.centerObject; } + MenuItem { action: Actions.deleteObject; } + MenuItem { action: Actions.multiplyObject; } MenuSeparator { } - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.reloadAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.reloadAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } MenuSeparator { } - MenuItem { action: actions.groupObjects; } - MenuItem { action: actions.mergeObjects; } - MenuItem { action: actions.unGroupObjects; } + MenuItem { action: Actions.groupObjects; } + MenuItem { action: Actions.mergeObjects; } + MenuItem { action: Actions.unGroupObjects; } + + Connections + { + target: Actions.deleteObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.deleteObject(objectContextMenu.objectId); + objectContextMenu.objectId = 0; + } + } + } + + Connections + { + target: Actions.multiplyObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.multiplyObject(objectContextMenu.objectId, 1); + objectContextMenu.objectId = 0; + } + } + } + + Connections + { + target: Actions.centerObject + onTriggered: + { + if(objectContextMenu.objectId != 0) + { + Printer.centerObject(objectContextMenu.objectId); + objectContextMenu.objectId = 0; + } + } + } } Menu { id: contextMenu; - MenuItem { action: actions.deleteAll; } - MenuItem { action: actions.reloadAll; } - MenuItem { action: actions.resetAllTranslation; } - MenuItem { action: actions.resetAll; } + MenuItem { action: Actions.deleteAll; } + MenuItem { action: Actions.reloadAll; } + MenuItem { action: Actions.resetAllTranslation; } + MenuItem { action: Actions.resetAll; } MenuSeparator { } - MenuItem { action: actions.groupObjects; } - MenuItem { action: actions.mergeObjects; } - MenuItem { action: actions.unGroupObjects; } + MenuItem { action: Actions.groupObjects; } + MenuItem { action: Actions.mergeObjects; } + MenuItem { action: Actions.unGroupObjects; } } Connections @@ -715,6 +717,18 @@ UM.MainWindow } } + Connections + { + target: Actions.quit + onTriggered: base.visible = false; + } + + Connections + { + target: Actions.toggleFullScreen + onTriggered: base.toggleFullscreen(); + } + FileDialog { id: openDialog; @@ -739,14 +753,32 @@ UM.MainWindow } } + Connections + { + target: Actions.open + onTriggered: openDialog.open() + } + EngineLog { id: engineLog; } - AddMachineWizard + Connections { - id: addMachineWizard + target: Actions.showEngineLog + onTriggered: engineLog.visible = true; + } + + AddMachineDialog + { + id: addMachineDialog + } + + Connections + { + target: Actions.addMachine + onTriggered: addMachineDialog.visible = true; } AboutDialog @@ -754,13 +786,19 @@ UM.MainWindow id: aboutDialog } + Connections + { + target: Actions.about + onTriggered: aboutDialog.visible = true; + } + Connections { target: Printer onRequestAddPrinter: { - addMachineWizard.visible = true - addMachineWizard.firstRun = false + addMachineDialog.visible = true + addMachineDialog.firstRun = false } } @@ -777,10 +815,9 @@ UM.MainWindow base.visible = true; restart(); } - else if(UM.MachineManager.activeMachineInstance == "") + else if(Cura.MachineManager.activeMachineId == null || Cura.MachineManager.activeMachineId == "") { - addMachineWizard.firstRun = true; - addMachineWizard.open(); + addMachineDialog.open(); } } } diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 99b2d00c36..9551e3bcf5 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -7,15 +7,16 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Rectangle { id: base; property bool activity: Printer.getPlatformActivity; property string fileBaseName - property variant activeMachineInstance: UM.MachineManager.activeMachineInstance + property variant activeMachineName: Cura.MachineManager.activeMachineName - onActiveMachineInstanceChanged: + onActiveMachineNameChanged: { base.createFileName() } @@ -28,36 +29,48 @@ Rectangle { height: childrenRect.height color: "transparent" - function createFileName(){ - var splitMachineName = UM.MachineManager.activeMachineInstance.split(" ") - var abbrMachine = '' - if ((UM.Preferences.getValue("cura/jobname_prefix"))) { - for (var i = 0; i < splitMachineName.length; i++){ - if (splitMachineName[i].search(/ultimaker/i) != -1){ - abbrMachine += 'UM' + function createFileName() + { + var splitMachineName = Cura.MachineManager.activeMachineName.split(" ") + var abbrMachine = ""; + if ((UM.Preferences.getValue("cura/jobname_prefix"))) + { + for (var i = 0; i < splitMachineName.length; i++) + { + if (splitMachineName[i].search(/ultimaker/i) != -1) + { + abbrMachine += "UM"; } - else{ + else + { if (splitMachineName[i].charAt(0).search(/[0-9]/g) == -1) - abbrMachine += splitMachineName[i].charAt(0) - } - var regExpAdditives = /[0-9\+]/g; - var resultAdditives = splitMachineName[i].match(regExpAdditives); - if (resultAdditives != null){ - for (var j = 0; j < resultAdditives.length; j++){ - abbrMachine += resultAdditives[j] - + { + abbrMachine += splitMachineName[i].charAt(0); } } } - printJobTextfield.text = abbrMachine + '_' + base.fileBaseName - } else { - printJobTextfield.text = base.fileBaseName + var regExpAdditives = /[0-9\+]/g; + var resultAdditives = splitMachineName[i].match(regExpAdditives); + if (resultAdditives != null) + { + for (var j = 0; j < resultAdditives.length; j++) + { + abbrMachine += resultAdditives[j]; + } + } + printJobTextfield.text = abbrMachine + "_" + base.fileBaseName; + } + else + { + printJobTextfield.text = base.fileBaseName; } } - Connections { + Connections + { target: backgroundItem - onHasMesh: { + onHasMesh: + { base.fileBaseName = name } } diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml new file mode 100644 index 0000000000..14425acc05 --- /dev/null +++ b/resources/qml/MachinesPage.qml @@ -0,0 +1,68 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Printers"); + property int numInstances: model.rowCount(); + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + onDataChanged: numInstances = model.rowCount() + } + + onAddObject: Printer.requestAddPrinter() + onRemoveObject: confirmDialog.open(); + onRenameObject: renameDialog.open(); + + removeEnabled: numInstances > 1 + renameEnabled: numInstances > 0 + + Flow + { + anchors.fill: parent; + spacing: UM.Theme.getSize("default_margin").height; + + Label + { + text: base.currentItem && base.currentItem.name ? base.currentItem.name : "" + font: UM.Theme.getFont("large") + width: parent.width + elide: Text.ElideRight + } + + Label { text: catalog.i18nc("@label", "Type"); width: parent.width * 0.2; } + Label { text: base.currentItem && base.currentItem.typeName ? base.currentItem.typeName : ""; width: parent.width * 0.7; } + + UM.I18nCatalog { id: catalog; name: "uranium"; } + + UM.ConfirmRemoveDialog + { + id: confirmDialog; + object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; + onYes: Cura.MachineManager.removeMachine(base.currentItem.id); + } + + UM.RenameDialog + { + id: renameDialog; + object: base.currentItem && base.currentItem.name ? base.currentItem.name : ""; + onAccepted: + { + Cura.MachineManager.renameMachine(base.currentItem.id, newName.trim()); + //Reselect current item to update details panel + var index = objectList.currentIndex + objectList.currentIndex = -1 + objectList.currentIndex = index + } + } + } +} diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml new file mode 100644 index 0000000000..03ede39a5c --- /dev/null +++ b/resources/qml/Preferences/MaterialsPage.qml @@ -0,0 +1,217 @@ +// Copyright (c) 2016 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Materials"); + + model: UM.InstanceContainersModel { filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } } +/* + onAddObject: { var selectedMaterial = UM.MaterialManager.createProfile(); base.selectMaterial(selectedMaterial); } + onRemoveObject: confirmDialog.open(); + onRenameObject: { renameDialog.open(); renameDialog.selectText(); } +*/ +// activateEnabled: false + addEnabled: false + removeEnabled: false + renameEnabled: false + + scrollviewCaption: " " + detailsVisible: true + + property string currency: UM.Preferences.getValue("general/currency") + + Item { + UM.I18nCatalog { id: catalog; name: "cura"; } + + visible: base.currentItem != null + anchors.fill: parent + + Label { id: profileName; text: materialProperties.name; font: UM.Theme.getFont("large"); width: parent.width; } + + TabView { + id: scrollView + anchors.left: parent.left + anchors.right: parent.right + anchors.top: profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.bottom: parent.bottom + + Tab { + title: "Information" + anchors.margins: UM.Theme.getSize("default_margin").height + + Flow { + id: containerGrid + + width: scrollView.width; + property real columnWidth: width / 2 + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Profile Type") } + Label { width: parent.columnWidth; text: materialProperties.profile_type } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Supplier") } + Label { width: parent.columnWidth; text: materialProperties.supplier } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Material Type") } + Label { width: parent.columnWidth; text: materialProperties.material_type } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Color") } + + Row { + width: parent.columnWidth; + spacing: UM.Theme.getSize("default_margin").width/2 + Rectangle { + color: materialProperties.color_code + width: colorLabel.height + height: colorLabel.height + border.width: UM.Theme.getSize("default_lining").height + } + Label { id: colorLabel; text: materialProperties.color_name } + } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { width: parent.width; text: "" + catalog.i18nc("@label", "Properties") + "" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Density") } + Label { width: parent.columnWidth; text: materialProperties.density } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Diameter") } + Label { width: parent.columnWidth; text: materialProperties.diameter } + + Label { + text: catalog.i18nc("@label", "Filament cost") + width: parent.columnWidth; + height: spoolCostInput.height + verticalAlignment: Text.AlignVCenter + } + + Row { + width: parent.columnWidth; + Label { + text: base.currency ? base.currency + " " : " " + anchors.verticalCenter: parent.verticalCenter + } + TextField { + id: spoolCostInput + text: materialProperties.spool_cost + } + } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Filament weight") } + Label { width: parent.columnWidth; text: materialProperties.spool_weight + " " + "g" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Filament length") } + Label { width: parent.columnWidth; text: materialProperties.spool_length + " " + "m" } + + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "Cost per meter") } + Label { width: parent.columnWidth; text: catalog.i18nc("@label", "approx. %1 %2/m").arg(materialProperties.cost_per_meter).arg(base.currency); } + + Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } + + Label { + text: materialProperties.description ? "" + catalog.i18nc("@label", "Information") + "
" + materialProperties.description : ""; + width: parent.width + wrapMode: Text.WordWrap + } + Label { + text: materialProperties.adhesion_info ? "" + catalog.i18nc("@label", "Adhesion") + "
" + materialProperties.adhesion_info : ""; + width: parent.width + wrapMode: Text.WordWrap + } + } + } + Tab { + title: catalog.i18nc("@label", "Print settings") + anchors.margins: UM.Theme.getSize("default_margin").height + + Grid { + columns: 2 + spacing: UM.Theme.getSize("default_margin").width + + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { + text: modelData.name.toString(); + elide: Text.ElideMiddle; + } + } + } + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { text: modelData.value.toString() + " " + modelData.unit.toString(); } + } + } + } + } + } + + QtObject + { + id: materialProperties + + property string name: "Unknown"; + property string profile_type: "Unknown"; + property string supplier: "Unknown"; + property string material_type: "Unknown"; + + property string color_name: "Yellow"; + property color color_code: "yellow"; + + property string density: "Unknown"; + property string diameter: "Unknown"; + + property string spool_cost: "Unknown"; + property string spool_weight: "Unknown"; + property string spool_length: "Unknown"; + property string cost_per_meter: "Unknown"; + + property string description: ""; + property string adhesion_info: ""; + } + } + + onCurrentItemChanged: + { + if(!currentItem == null) + { + return + } + + materialProperties.name = currentItem.name; + + if(currentItem.metadata != undefined && currentItem.metadata != null) + { + materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown"; + materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown"; + materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow"; + materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow"; + + materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : ""; + materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : ""; + + if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null) + { + materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : "Unknown"; + materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : "Unknown"; + } + else + { + materialProperties.density = "Unknown"; + materialProperties.diameter = "Unknown"; + } + } + } +} diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml new file mode 100644 index 0000000000..6e5d39cb49 --- /dev/null +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -0,0 +1,222 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.2 + +import UM 1.2 as UM + +UM.ManagementPage +{ + id: base; + + title: catalog.i18nc("@title:tab", "Profiles"); + addText: catalog.i18nc("@label", "Duplicate") + + model: UM.InstanceContainersModel { filter: { "type": "quality" } } + + onAddObject: { + var selectedProfile; + if (objectList.currentIndex == 0) { + // Current settings + selectedProfile = UM.MachineManager.createProfile(); + } else { + selectedProfile = UM.MachineManager.duplicateProfile(currentItem.name); + } + base.selectProfile(selectedProfile); + + renameDialog.removeWhenRejected = true; + renameDialog.open(); + renameDialog.selectText(); + } + onRemoveObject: confirmDialog.open(); + onRenameObject: { renameDialog.removeWhenRejected = false; renameDialog.open(); renameDialog.selectText(); } + + addEnabled: currentItem != null; + removeEnabled: currentItem != null ? !currentItem.readOnly : false; + renameEnabled: currentItem != null ? !currentItem.readOnly : false; + + scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(UM.MachineManager.activeMachineInstance) + + signal selectProfile(string name) + onSelectProfile: { + objectList.currentIndex = objectList.model.find("name", name); + } + + Item { + visible: base.currentItem != null + anchors.fill: parent + + Label { + id: profileName + text: base.currentItem ? base.currentItem.name : "" + font: UM.Theme.getFont("large") + width: parent.width + elide: Text.ElideRight + } + + ScrollView { + anchors.left: parent.left + anchors.top: profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height + anchors.right: parent.right + anchors.bottom: parent.bottom + + Column + { + spacing: UM.Theme.getSize("default_margin").height + + Row + { + visible: base.currentItem.id == -1 || base.currentItem.active + Button + { + text: { + var profileName = UM.MachineManager.activeProfile; + profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; + return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); + } + enabled: UM.ActiveProfile.hasCustomisedValues && !UM.ActiveProfile.readOnly + onClicked: UM.ActiveProfile.updateProfile() + } + + Button + { + text: catalog.i18nc("@action:button", "Discard changes"); + enabled: UM.ActiveProfile.hasCustomisedValues + onClicked: UM.ActiveProfile.discardChanges() + } + } + + Grid + { + id: containerGrid + columns: 2 + spacing: UM.Theme.getSize("default_margin").width + + Label { + text: base.currentItem == null ? "" : + base.currentItem.id == -1 ? catalog.i18nc("@label", "Based on") : catalog.i18nc("@label", "Profile type") + } + Label { + text: base.currentItem == null ? "" : + base.currentItem.id == -1 ? UM.MachineManager.activeProfile : + base.currentItem.readOnly ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") + } + + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { + text: modelData.name.toString(); + elide: Text.ElideMiddle; + } + } + } + Column { + Repeater { + model: base.currentItem ? base.currentItem.settings : null + Label { text: modelData.value.toString(); } + } + } + } + } + } + } + + buttons: Row { + + Button + { + text: catalog.i18nc("@action:button", "Import"); + iconName: "document-import"; + onClicked: importDialog.open(); + } + + Button + { + text: catalog.i18nc("@action:button", "Export"); + iconName: "document-export"; + onClicked: exportDialog.open(); + } + } + + Item + { + UM.I18nCatalog { id: catalog; name: "uranium"; } + + UM.ConfirmRemoveDialog + { + id: confirmDialog; + object: base.currentItem != null ? base.currentItem.name : ""; + onYes: base.model.removeProfile(base.currentItem.name); + } + UM.RenameDialog + { + id: renameDialog; + object: base.currentItem != null ? base.currentItem.name : ""; + property bool removeWhenRejected: false; + onAccepted: base.model.renameProfile(base.currentItem.name, newName.trim()); + onRejected: { + if(removeWhenRejected) { + base.model.removeProfile(base.currentItem.name) + } + } + } + MessageDialog + { + id: messageDialog + title: catalog.i18nc("@window:title", "Import Profile"); + standardButtons: StandardButton.Ok + modality: Qt.ApplicationModal + } + + FileDialog + { + id: importDialog; + title: catalog.i18nc("@title:window", "Import Profile"); + selectExisting: true; + nameFilters: base.model.getFileNameFiltersRead() + folder: base.model.getDefaultPath() + onAccepted: + { + var result = base.model.importProfile(fileUrl) + messageDialog.text = result.message + if(result.status == "ok") + { + messageDialog.icon = StandardIcon.Information + } + else if(result.status == "duplicate") + { + messageDialog.icon = StandardIcon.Warning + } + else + { + messageDialog.icon = StandardIcon.Critical + } + messageDialog.open() + } + } + + FileDialog + { + id: exportDialog; + title: catalog.i18nc("@title:window", "Export Profile"); + selectExisting: false; + nameFilters: base.model.getFileNameFiltersWrite() + folder: base.model.getDefaultPath() + onAccepted: + { + var result = base.model.exportProfile(base.currentItem.id, base.currentItem.name, fileUrl, selectedNameFilter) + if(result && result.status == "error") + { + messageDialog.icon = StandardIcon.Critical + messageDialog.text = result.message + messageDialog.open() + } + // else pop-up Message thing from python code + } + } + } +} diff --git a/resources/qml/ProfileSetup.qml b/resources/qml/ProfileSetup.qml index d6ff042a44..95aed3685c 100644 --- a/resources/qml/ProfileSetup.qml +++ b/resources/qml/ProfileSetup.qml @@ -6,7 +6,8 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura Item{ id: base; @@ -41,13 +42,13 @@ Item{ property int rightMargin: customisedSettings.visible ? customisedSettings.width + UM.Theme.getSize("default_margin").width / 2 : 0 id: globalProfileSelection - text: UM.MachineManager.activeProfile + text: Cura.MachineManager.activeQualityName width: parent.width/100*55 height: UM.Theme.getSize("setting_control").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter - tooltip: UM.MachineManager.activeProfile + tooltip: Cura.MachineManager.activeQualityName style: UM.Theme.styles.sidebar_header_button menu: Menu @@ -56,7 +57,10 @@ Item{ Instantiator { id: profileSelectionInstantiator - model: UM.ProfilesModel {} + model: UM.InstanceContainersModel + { + filter: {"type": "quality"} + } property int separatorIndex: -1 Loader { @@ -98,18 +102,18 @@ Item{ id: item text: model_data ? model_data.name : "" checkable: true; - checked: model_data ? model_data.active : false; + checked: Cura.MachineManager.activeQualityId == model_data.id exclusiveGroup: profileSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveProfile(model_data.name); - if (!model_data.active) { + Cura.MachineManager.setActiveQuality(model_data.id); + /*if (!model_data.active) { //Selecting a profile was canceled; undo menu selection profileSelectionInstantiator.model.setProperty(model_index, "active", false); var activeProfileName = UM.MachineManager.activeProfile; var activeProfileIndex = profileSelectionInstantiator.model.find("name", activeProfileName); profileSelectionInstantiator.model.setProperty(activeProfileIndex, "active", true); - } + }*/ } } } diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml new file mode 100644 index 0000000000..f4e3dbe5ae --- /dev/null +++ b/resources/qml/Settings/SettingCategory.qml @@ -0,0 +1,82 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.1 as UM + +import ".." + +Button { + id: base; + + style: UM.Theme.styles.sidebar_category; + + signal showTooltip(string text); + signal hideTooltip(); + signal contextMenuRequested() + + text: definition.label + iconSource: UM.Theme.getIcon(definition.icon) + + checkable: true + checked: definition.expanded + + onClicked: definition.expanded ? settingDefinitionsModel.collapse(definition.key) : settingDefinitionsModel.expandAll(definition.key) + + UM.SimpleButton { + id: settingsButton + + visible: base.hovered || settingsButton.hovered + height: base.height * 0.6 + width: base.height * 0.6 + + anchors { + right: inheritButton.visible ? inheritButton.left : parent.right + rightMargin: inheritButton.visible? UM.Theme.getSize("default_margin").width / 2 : UM.Theme.getSize("setting_preferences_button_margin").width + verticalCenter: parent.verticalCenter; + } + + color: UM.Theme.getColor("setting_control_button"); + hoverColor: UM.Theme.getColor("setting_control_button_hover") + iconSource: UM.Theme.getIcon("settings"); + + onClicked: { + Actions.configureSettingVisibility.trigger(definition) + } + } + + UM.SimpleButton + { + id: inheritButton; + + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width + + visible: hiddenValuesCount > 0 + height: parent.height / 2; + width: height; + + onClicked: { + base.showAllHiddenInheritedSettings() + } + + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + iconSource: UM.Theme.getIcon("notice") + + onEntered: { + base.showTooltip(catalog.i18nc("@label","Some hidden settings use values different from their normal calculated value.\n\nClick to make these settings visible.")) + } + + onExited: { + base.hideTooltip(); + } + + UM.I18nCatalog { id: catalog; name: "cura" } + } +} diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml new file mode 100644 index 0000000000..6f0314160e --- /dev/null +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -0,0 +1,78 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.2 as UM + +SettingItem +{ + id: base + + contents: MouseArea + { + id: control + anchors.fill: parent + + property bool checked: + { + switch(propertyProvider.properties.value) + { + case "True": + return true + case "False": + return false + default: + return propertyProvider.properties.value + } + } + + onClicked: propertyProvider.setPropertyValue("value", !checked) + + Rectangle + { + anchors + { + top: parent.top + bottom: parent.bottom + left: parent.left + } + width: height + + color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled") + } + if(control.containsMouse || control.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight") + } + else + { + return UM.Theme.getColor("setting_control") + } + } + + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") + + UM.RecolorImage { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width/2.5 + height: parent.height/2.5 + sourceSize.width: width + sourceSize.height: width + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); + source: UM.Theme.getIcon("check") + opacity: control.checked ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100; } } + } + } + } +} diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml new file mode 100644 index 0000000000..c9f3cb727b --- /dev/null +++ b/resources/qml/Settings/SettingComboBox.qml @@ -0,0 +1,109 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM + +SettingItem +{ + id: base + + contents: ComboBox + { + id: control + + model: definition.options + textRole: "value"; + + anchors.fill: parent + + MouseArea + { + anchors.fill: parent; + acceptedButtons: Qt.NoButton; + onWheel: wheel.accepted = true; + } + + style: ComboBoxStyle + { + background: Rectangle + { + color: + { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled") + } + if(control.hovered || base.activeFocus) + { + return UM.Theme.getColor("setting_control_highlight") + } + else + { + return UM.Theme.getColor("setting_control") + } + } + border.width: UM.Theme.getSize("default_lining").width; + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border"); + } + label: Item + { + Label + { + anchors.left: parent.left; + anchors.leftMargin: UM.Theme.getSize("default_lining").width + anchors.right: downArrow.left; + anchors.rightMargin: UM.Theme.getSize("default_lining").width; + anchors.verticalCenter: parent.verticalCenter; + + text: control.currentText; + font: UM.Theme.getFont("default"); + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); + + elide: Text.ElideRight; + verticalAlignment: Text.AlignVCenter; + } + + UM.RecolorImage + { + id: downArrow + anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2; + anchors.verticalCenter: parent.verticalCenter; + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 + sourceSize.height: width + 5 + + color: UM.Theme.getColor("setting_control_text"); + + } + } + } + + onActivated: provider.setPropertyValue("value", definition.options[index].key) + onModelChanged: updateCurrentIndex(); + + Connections + { + target: provider + onPropertiesChanged: control.updateCurrentIndex() + } + + function updateCurrentIndex() { + for(var i = 0; i < definition.options.length; ++i) { + if(definition.options[i].key == provider.properties.value) { + currentIndex = i; + return; + } + } + + currentIndex = -1; + } + } +} diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml new file mode 100644 index 0000000000..ebbf93af84 --- /dev/null +++ b/resources/qml/Settings/SettingItem.qml @@ -0,0 +1,155 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 + +import UM 1.1 as UM + +import "." + +Item { + id: base; + + height: UM.Theme.getSize("section").height; + + property alias contents: controlContainer.children; + property alias hovered: mouse.containsMouse + + signal contextMenuRequested() + signal showTooltip(string text); + signal hideTooltip(); + + MouseArea + { + id: mouse; + + anchors.fill: parent; + + acceptedButtons: Qt.RightButton; + hoverEnabled: true; + + onClicked: base.contextMenuRequested(); + + onEntered: { + hoverTimer.start(); + } + + onExited: { + if(controlContainer.item && controlContainer.item.hovered) { + return; + } + hoverTimer.stop(); + base.hideTooltip(); + } + + Timer { + id: hoverTimer; + interval: 500; + repeat: false; + + onTriggered: base.showTooltip(definition.description); + } + + Label + { + id: label; + + anchors.left: parent.left; + anchors.leftMargin: (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) + anchors.right: settingControls.left; + anchors.verticalCenter: parent.verticalCenter + + height: UM.Theme.getSize("section").height; + verticalAlignment: Text.AlignVCenter; + + text: definition.label + elide: Text.ElideMiddle; + + color: UM.Theme.getColor("setting_control_text"); + font: UM.Theme.getFont("default"); + } + + Row + { + id: settingControls + + height: parent.height / 2 + spacing: UM.Theme.getSize("default_margin").width / 2 + + anchors { + right: controlContainer.left + rightMargin: UM.Theme.getSize("default_margin").width / 2 + verticalCenter: parent.verticalCenter + } + + UM.SimpleButton + { + id: revertButton; + + visible: propertyProvider.properties.state == "InstanceState.User" + + height: parent.height; + width: height; + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("reset") + + onClicked: { + base.resetRequested() + controlContainer.notifyReset(); + } + + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) + onExited: base.showTooltip(definition.description); + } + + UM.SimpleButton + { + // This button shows when the setting has an inherited function, but is overriden by profile. + id: inheritButton; + + //visible: has_profile_value && base.has_inherit_function && base.is_enabled + visible: propertyProvider.properties.state == "InstanceState.User" + + height: parent.height; + width: height; + + onClicked: { + base.resetToDefaultRequested(); + controlContainer.notifyReset(); + } + + backgroundColor: UM.Theme.getColor("setting_control"); + hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight") + color: UM.Theme.getColor("setting_control_button") + hoverColor: UM.Theme.getColor("setting_control_button_hover") + + iconSource: UM.Theme.getIcon("notice"); + + onEntered: base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) + onExited: base.showTooltip(definition.description); + } + + } + + Item + { + id: controlContainer; + + anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("default_margin").width + anchors.verticalCenter: parent.verticalCenter; + width: UM.Theme.getSize("setting_control").width; + height: UM.Theme.getSize("setting_control").height + } + } + + UM.I18nCatalog { id: catalog; name: "cura" } +} diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml new file mode 100644 index 0000000000..9972f83aa1 --- /dev/null +++ b/resources/qml/Settings/SettingTextField.qml @@ -0,0 +1,155 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.2 + +import UM 1.1 as UM + +SettingItem +{ + id: base + + contents: Rectangle + { + id: control + + anchors.fill: parent + + property alias hovered: mouseArea.containsMouse; + + border.width: UM.Theme.getSize("default_lining").width + border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border") + + property variant parentValue: value //From parent loader + function notifyReset() { + input.text = format(parentValue) + } + + color: { + if (!enabled) + { + return UM.Theme.getColor("setting_control_disabled") + } + switch(propertyProvider.properties.validationState) + { + case "ValidatorState.Exception": + return UM.Theme.getColor("setting_validation_error") + case "ValidatorState.MinimumError": + return UM.Theme.getColor("setting_validation_error") + case "ValidatorState.MaximumError": + return UM.Theme.getColor("setting_validation_error") + case "ValidatorState.MinimumWarning": + return UM.Theme.getColor("setting_validation_warning") + case "ValidatorState.MaximumWarning": + return UM.Theme.getColor("setting_validation_warning") + case "ValidatorState.Valid": + return UM.Theme.getColor("setting_validation_ok") + + default: + return UM.Theme.getColor("setting_control") + } + } + + Rectangle + { + anchors.fill: parent; + anchors.margins: UM.Theme.getSize("default_lining").width; + color: UM.Theme.getColor("setting_control_highlight") + opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35; + } + + Label + { + anchors.right: parent.right; + anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter; + + text: definition.unit; + color: UM.Theme.getColor("setting_unit") + font: UM.Theme.getFont("default") + } + + MouseArea + { + id: mouseArea + anchors.fill: parent; + hoverEnabled: true; + cursorShape: Qt.IBeamCursor + } + + TextInput + { + id: input + + anchors + { + left: parent.left + leftMargin: UM.Theme.getSize("setting_unit_margin").width + right: parent.right + verticalCenter: parent.verticalCenter + } + + Keys.onReleased: + { +// text = text.replace(",", ".") // User convenience. We use dots for decimal values +// if(parseFloat(text) != base.parentValue) +// { +// base.valueChanged(parseFloat(text)); +// } + + propertyProvider.setPropertyValue("value", text) + } + + onEditingFinished: + { +// if(parseFloat(text) != base.parentValue) +// { +// base.valueChanged(parseFloat(text)); +// } + propertyProvider.setPropertyValue("value", text) + } + + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default"); + + selectByMouse: true; + + maximumLength: 10; + + validator: RegExpValidator { regExp: /[0-9.,-]{0,10}/ } + + Binding + { + target: input + property: "text" + value: control.format(propertyProvider.properties.value) + when: !input.activeFocus + } + } + + //Rounds a floating point number to 4 decimals. This prevents floating + //point rounding errors. + // + //input: The number to round. + //decimals: The number of decimals (digits after the radix) to round to. + //return: The rounded number. + function roundFloat(input, decimals) + { + //First convert to fixed-point notation to round the number to 4 decimals and not introduce new floating point errors. + //Then convert to a string (is implicit). The fixed-point notation will be something like "3.200". + //Then remove any trailing zeroes and the radix. + return input.toFixed(decimals).replace(/\.?0*$/, ""); //Match on periods, if any ( \.? ), followed by any number of zeros ( 0* ), then the end of string ( $ ). + } + + //Formats a value for display in the text field. + // + //This correctly handles formatting of float values. + // + //input: The string value to format. + //return: The formatted string. + function format(inputValue) { + return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals. + } + } +} diff --git a/resources/qml/Settings/SettingUnknown.qml b/resources/qml/Settings/SettingUnknown.qml new file mode 100644 index 0000000000..55e26b6695 --- /dev/null +++ b/resources/qml/Settings/SettingUnknown.qml @@ -0,0 +1,19 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 + +import UM 1.2 as UM + +SettingItem +{ + contents: Label + { + anchors.fill: parent + text: value + " " + unit; + color: UM.Theme.getColor("setting_control_text") + + verticalAlignment: Qt.AlignVCenter + } +} diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml new file mode 100644 index 0000000000..0e99ecc4b7 --- /dev/null +++ b/resources/qml/Settings/SettingView.qml @@ -0,0 +1,135 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +import ".." + +ScrollView +{ + id: base; + + style: UM.Theme.styles.scrollview; + flickableItem.flickableDirection: Flickable.VerticalFlick; + + property Action configureSettings; + signal showTooltip(Item item, point location, string text); + signal hideTooltip(); + + ListView + { + id: contents + spacing: UM.Theme.getSize("default_lining").height; + + model: UM.SettingDefinitionsModel { id: definitionsModel; containerId: Cura.MachineManager.activeDefinitionId } + + delegate: Loader + { + id: delegate + + width: UM.Theme.getSize("sidebar").width; + height: provider.properties.enabled ? UM.Theme.getSize("section").height : 0 + Behavior on height { NumberAnimation { duration: 100 } } + opacity: provider.properties.enabled ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: 100 } } + enabled: provider.properties.enabled + + property var definition: model + property var settingDefinitionsModel: definitionsModel + property var propertyProvider: provider + + //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 + asynchronous: QT_VERSION_STR.split(".")[1] >= 5 + + source: + { + switch(model.type) + { + case "int": + return "SettingTextField.qml" + case "float": + return "SettingTextField.qml" + case "enum": + return "SettingComboBox.qml" + case "bool": + return "SettingCheckBox.qml" + case "str": + return "SettingTextField.qml" + case "category": + return "SettingCategory.qml" + default: + return "SettingUnknown.qml" + } + } + + UM.SettingPropertyProvider + { + id: provider + + containerStackId: Cura.MachineManager.activeMachineId + key: model.key + watchedProperties: [ "value", "enabled", "state", "validationState" ] + storeIndex: 0 + } + + Connections + { + target: item + onContextMenuRequested: { contextMenu.key = model.key; contextMenu.popup() } + onShowTooltip: base.showTooltip(delegate, { x: 0, y: delegate.height / 2 }, text) + onHideTooltip: base.hideTooltip() + } + } + + UM.I18nCatalog { id: catalog; name: "uranium"; } + + add: Transition { + SequentialAnimation { + NumberAnimation { properties: "height"; from: 0; duration: 100 } + NumberAnimation { properties: "opacity"; from: 0; duration: 100 } + } + } + remove: Transition { + SequentialAnimation { + NumberAnimation { properties: "opacity"; to: 0; duration: 100 } + NumberAnimation { properties: "height"; to: 0; duration: 100 } + } + } + addDisplaced: Transition { + NumberAnimation { properties: "x,y"; duration: 100 } + } + removeDisplaced: Transition { + SequentialAnimation { + PauseAnimation { duration: 100; } + NumberAnimation { properties: "x,y"; duration: 100 } + } + } + + Menu + { + id: contextMenu; + + property string key; + + MenuItem + { + //: Settings context menu action + text: catalog.i18nc("@action:menu", "Hide this setting"); + onTriggered: definitionsModel.hide(contextMenu.key); + } + MenuItem + { + //: Settings context menu action + text: catalog.i18nc("@action:menu", "Configure setting visiblity..."); + + onTriggered: Actions.configureSettingVisibility.trigger(contextMenu); + } + } + } +} diff --git a/resources/qml/Settings/SettingsConfigurationPage.qml b/resources/qml/Settings/SettingsConfigurationPage.qml new file mode 100644 index 0000000000..a2889d410a --- /dev/null +++ b/resources/qml/Settings/SettingsConfigurationPage.qml @@ -0,0 +1,119 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQml 2.2 + +import UM 1.1 as UM + +import "../Preferences" + +PreferencesPage +{ + //: Machine configuration page title. + title: catalog.i18nc("@title:tab","Machine"); + id: base + + contents: ColumnLayout + { + z: base.z + anchors.fill: parent; + UM.I18nCatalog { id: catalog; name:"uranium"} + RowLayout + { + //: Active machine combo box label + Label { text: catalog.i18nc("@label:listbox","Active Machine:"); } + ComboBox + { + id: machineCombo; + Layout.fillWidth: true; + model: UM.Models.machinesModel; + textRole: "name"; + onActivated: + { + if(index != -1) + UM.Models.machinesModel.setActive(index); + } + + Connections + { + id: machineChange + target: UM.Application + onMachineChanged: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); + } + + Component.onCompleted: machineCombo.currentIndex = machineCombo.find(UM.Application.machineName); + } + //: Remove active machine button + Button { text: catalog.i18nc("@action:button","Remove"); onClicked: confirmRemoveDialog.open(); } + } + ScrollView + { + id: settingsScrollView + Layout.fillWidth: true; + Layout.fillHeight: true; + + ListView + { + id: settingsListView + delegate: settingDelegate + model: UM.Models.settingsModel + x: 0 + + section.property: "category" + section.delegate: Label { text: section } + } + } + } + + Component + { + id: settingDelegate + CheckBox + { + z:0 + id: settingCheckBox + text: model.name; + x: depth * 25 + checked: model.visibility + onClicked: ListView.view.model.setVisibility(model.key, checked) + //enabled: !model.disabled + + onHoveredChanged: + { + if(hovered) + { + var xPos = parent.x + settingCheckBox.width; + var yPos = parent.y; + toolTip.show(model.description, 1000, 200, undefined, undefined) //tooltip-text, hover-delay in msec, animation-length in msec, position X, position Y (both y en x == undefined: gives the tooltip a standard placement in the right corner) + } else + { + toolTip.hide(0, 0)//hover-delay in msec, animation-length in msec + } + } + } + } + + PreferencesToolTip + { + id: toolTip; + } + + MessageDialog + { + id: confirmRemoveDialog; + + icon: StandardIcon.Question; + //: Remove machine confirmation dialog title + title: catalog.i18nc("@title:window","Confirm Machine Deletion"); + //: Remove machine confirmation dialog text + text: catalog.i18nc("@label","Are you sure you wish to remove the machine?"); + standardButtons: StandardButton.Yes | StandardButton.No; + + onYes: UM.Models.machinesModel.removeMachine(machineCombo.currentIndex); + } +} diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 5426125194..81823f039d 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -27,7 +27,7 @@ Rectangle function showTooltip(item, position, text) { tooltip.text = text; - position = item.mapToItem(base, position.x, position.y / 2); + position = item.mapToItem(base, position.x, position.y); tooltip.show(position); } @@ -247,7 +247,6 @@ Rectangle id: sidebarAdvanced; visible: false; - configureSettings: base.configureSettingsAction; onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() } diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/SidebarAdvanced.qml index 8a231aa53d..30f4e74db6 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/SidebarAdvanced.qml @@ -5,9 +5,9 @@ import QtQuick 2.0 import QtQuick.Controls 1.2 -import UM 1.0 as UM +import "Settings" -UM.SettingView { - expandedCategories: Printer.expandedCategories; - onExpandedCategoriesChanged: Printer.setExpandedCategories(expandedCategories); +SettingView { +// expandedCategories: Printer.expandedCategories; +// onExpandedCategoriesChanged: Printer.setExpandedCategories(expandedCategories); } diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b5fcc880f6..d8bc4291bb 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -5,7 +5,8 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura Item { @@ -57,10 +58,10 @@ Item ToolButton { id: machineSelection - text: UM.MachineManager.activeMachineInstance; + text: Cura.MachineManager.activeMachineName; width: parent.width/100*55 height: UM.Theme.getSize("setting_control").height - tooltip: UM.MachineManager.activeMachineInstance; + tooltip: Cura.MachineManager.activeMachineName; anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter @@ -71,14 +72,17 @@ Item id: machineSelectionMenu Instantiator { - model: UM.MachineInstancesModel { } + model: UM.ContainerStacksModel + { + filter: {"type": "machine"} + } MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: Cura.MachineManager.activeMachineId == model.id exclusiveGroup: machineSelectionMenuGroup; - onTriggered: UM.MachineManager.setActiveMachineInstance(model.name); + onTriggered: Cura.MachineManager.setActiveMachine(model.id); } onObjectAdded: machineSelectionMenu.insertItem(index, object) onObjectRemoved: machineSelectionMenu.removeItem(object) @@ -100,12 +104,12 @@ Item anchors.topMargin: visible ? UM.Theme.getSize("default_margin").height : 0 width: base.width height: visible ? UM.Theme.getSize("sidebar_setup").height : 0 - visible: UM.MachineManager.hasVariants || UM.MachineManager.hasMaterials + visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials Label{ id: variantLabel - text: (UM.MachineManager.hasVariants && UM.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): - UM.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); + text: (Cura.MachineManager.hasVariants && Cura.MachineManager.hasMaterials) ? catalog.i18nc("@label","Nozzle & Material:"): + Cura.MachineManager.hasVariants ? catalog.i18nc("@label","Nozzle:") : catalog.i18nc("@label","Material:"); anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter @@ -114,7 +118,8 @@ Item color: UM.Theme.getColor("text"); } - Rectangle { + Rectangle + { anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.verticalCenter: parent.verticalCenter @@ -124,9 +129,9 @@ Item ToolButton { id: variantSelection - text: UM.MachineManager.activeMachineVariant - tooltip: UM.MachineManager.activeMachineVariant; - visible: UM.MachineManager.hasVariants + text: Cura.MachineManager.activeVariantName + tooltip: Cura.MachineManager.activeVariantName; + visible: Cura.MachineManager.hasVariants height: UM.Theme.getSize("setting_control").height width: materialSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width @@ -139,23 +144,30 @@ Item Instantiator { id: variantSelectionInstantiator - model: UM.MachineVariantsModel { id: variantsModel } + model: UM.InstanceContainersModel + { + filter: + { + "type": "variant", + "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine + } + } MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeVariantId; exclusiveGroup: variantSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveMachineVariant(variantsModel.getItem(index).name); - if (typeof(model) !== "undefined" && !model.active) { + Cura.MachineManager.setActiveVariant(model.id); + /*if (typeof(model) !== "undefined" && !model.active) { //Selecting a variant was canceled; undo menu selection variantSelectionInstantiator.model.setProperty(index, "active", false); var activeMachineVariantName = UM.MachineManager.activeMachineVariant; var activeMachineVariantIndex = variantSelectionInstantiator.model.find("name", activeMachineVariantName); variantSelectionInstantiator.model.setProperty(activeMachineVariantIndex, "active", true); - } + }*/ } } onObjectAdded: variantsSelectionMenu.insertItem(index, object) @@ -168,9 +180,9 @@ Item ToolButton { id: materialSelection - text: UM.MachineManager.activeMaterial - tooltip: UM.MachineManager.activeMaterial - visible: UM.MachineManager.hasMaterials + text: Cura.MachineManager.activeMaterialName + tooltip: Cura.MachineManager.activeMaterialName + visible: Cura.MachineManager.hasMaterials height: UM.Theme.getSize("setting_control").height width: variantSelection.visible ? (parent.width - UM.Theme.getSize("default_margin").width) / 2 : parent.width @@ -183,23 +195,26 @@ Item Instantiator { id: materialSelectionInstantiator - model: UM.MachineMaterialsModel { id: machineMaterialsModel } + model: UM.InstanceContainersModel + { + filter: { "type": "material", "definition": Cura.MachineManager.activeDefinitionId } + } MenuItem { text: model.name; checkable: true; - checked: model.active; + checked: model.id == Cura.MachineManager.activeMaterialId; exclusiveGroup: materialSelectionMenuGroup; onTriggered: { - UM.MachineManager.setActiveMaterial(machineMaterialsModel.getItem(index).name); - if (typeof(model) !== "undefined" && !model.active) { + Cura.MachineManager.setActiveMaterial(model.id); + /*if (typeof(model) !== "undefined" && !model.active) { //Selecting a material was canceled; undo menu selection materialSelectionInstantiator.model.setProperty(index, "active", false); - var activeMaterialName = UM.MachineManager.activeMaterial; + var activeMaterialName = Cura.MachineManager.activeMaterialName var activeMaterialIndex = materialSelectionInstantiator.model.find("name", activeMaterialName); materialSelectionInstantiator.model.setProperty(activeMaterialIndex, "active", true); - } + }*/ } } onObjectAdded: materialSelectionMenu.insertItem(index, object) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index f3c551ab0c..a58f0c88fa 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -6,7 +6,8 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 -import UM 1.1 as UM +import UM 1.2 as UM +import Cura 1.0 as Cura Item { @@ -56,12 +57,7 @@ Item Repeater { id: infillListView property int activeIndex: { - if(!UM.ActiveProfile.valid) - { - return -1; - } - - var density = parseInt(UM.ActiveProfile.settingValues.getValue("infill_sparse_density")); + var density = parseInt(infillDensity.properties.value) for(var i = 0; i < infillModel.count; ++i) { if(density > infillModel.get(i).percentageMin && density <= infillModel.get(i).percentageMax ) @@ -116,11 +112,11 @@ Item onClicked: { if (infillListView.activeIndex != index) { - UM.MachineManager.setSettingValue("infill_sparse_density", model.percentage) + infillDensity.setPropertyValue("value", model.percentage) } } onEntered: { - base.showTooltip(infillCellRight, Qt.point(-infillCellRight.x, parent.height), model.text); + base.showTooltip(infillCellRight, Qt.point(-infillCellRight.x, 0), model.text); } onExited: { base.hideTooltip(); @@ -213,18 +209,19 @@ Item text: catalog.i18nc("@option:check","Generate Brim"); style: UM.Theme.styles.checkbox; - checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("adhesion_type") == "brim" : false; + checked: platformAdhesionType.properties.value == "brim" + MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { - UM.MachineManager.setSettingValue("adhesion_type", !parent.checked?"brim":"skirt") + platformAdhesionType.setPropertyValue("value", !parent.checked ? "brim" : "skirt") } onEntered: { parent.hovered_ex = true - base.showTooltip(brimCheckBox, Qt.point(-helpersCellRight.x, parent.height), + base.showTooltip(brimCheckBox, Qt.point(-helpersCellRight.x, 0), catalog.i18nc("@label", "Enable printing a brim. This will add a single-layer-thick flat area around your object which is easy to cut off afterwards.")); } onExited: @@ -246,18 +243,18 @@ Item text: catalog.i18nc("@option:check","Generate Support Structure"); style: UM.Theme.styles.checkbox; - checked: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_enable") : false; + checked: supportEnabled.properties.value == "True" MouseArea { anchors.fill: parent hoverEnabled: true onClicked: { - UM.MachineManager.setSettingValue("support_enable", !parent.checked) + supportEnabled.setPropertyValue("value", !parent.checked) } onEntered: { parent.hovered_ex = true - base.showTooltip(supportCheckBox, Qt.point(-helpersCellRight.x, parent.height), + base.showTooltip(supportCheckBox, Qt.point(-helpersCellRight.x, 0), catalog.i18nc("@label", "Enable printing support structures. This will build up supporting structures below the model to prevent the model from sagging or printing in mid air.")); } onExited: @@ -271,15 +268,15 @@ Item function populateExtruderModel() { - extruderModel.clear() - var extruder_count = UM.MachineManager.getSettingValue("machine_extruder_count"); - for(var extruder = 0; extruder < extruder_count ; extruder++) { - extruderModel.append({ - name: catalog.i18nc("@label", "Extruder %1").arg(extruder), - text: catalog.i18nc("@label", "Extruder %1").arg(extruder), - value: extruder - }) - } +// extruderModel.clear() +// var extruder_count = UM.MachineManager.getSettingValue("machine_extruder_count"); +// for(var extruder = 0; extruder < extruder_count ; extruder++) { +// extruderModel.append({ +// name: catalog.i18nc("@label", "Extruder %1").arg(extruder), +// text: catalog.i18nc("@label", "Extruder %1").arg(extruder), +// value: extruder +// }) +// } } Rectangle { @@ -290,7 +287,7 @@ Item width: parent.width height: childrenRect.height // Use both UM.ActiveProfile and UM.MachineManager to force UM.MachineManager.getSettingValue() to be reevaluated - visible: UM.ActiveProfile.settingValues.getValue("machine_extruder_count") || (UM.MachineManager.getSettingValue("machine_extruder_count") > 1) +// visible: UM.ActiveProfile.settingValues.getValue("machine_extruder_count") || (UM.MachineManager.getSettingValue("machine_extruder_count") > 1) Label { id: mainExtruderLabel @@ -308,9 +305,9 @@ Item anchors.top: parent.top anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox - currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("extruder_nr") : 0 +// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("extruder_nr") : 0 onActivated: { - UM.MachineManager.setSettingValue("extruder_nr", index) +// UM.MachineManager.setSettingValue("extruder_nr", index) } } @@ -335,7 +332,7 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.left: supportExtruderLabel.right style: UM.Theme.styles.combobox - currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_extruder_nr") : 0 +// currentIndex: UM.ActiveProfile.valid ? UM.ActiveProfile.settingValues.getValue("support_extruder_nr") : 0 onActivated: { UM.MachineManager.setSettingValue("support_extruder_nr", index) } @@ -345,12 +342,12 @@ Item id: extruderModel Component.onCompleted: populateExtruderModel() } - Connections - { - id: machineChange - target: UM.MachineManager - onActiveMachineInstanceChanged: populateExtruderModel() - } +// Connections +// { +// id: machineChange +// target: UM.MachineManager +// onActiveMachineInstanceChanged: populateExtruderModel() +// } } Rectangle { @@ -375,4 +372,36 @@ Item onLinkActivated: Qt.openUrlExternally(link) } } + + UM.SettingPropertyProvider + { + id: infillDensity + + containerStackId: Cura.MachineManager.activeMachineId + key: "infill_sparse_density" + watchedProperties: [ "value" ] + storeIndex: 0 + + onPropertiesChanged: console.log(properties.value) + } + + UM.SettingPropertyProvider + { + id: platformAdhesionType + + containerStackId: Cura.MachineManager.activeMachineId + key: "adhesion_type" + watchedProperties: [ "value" ] + storeIndex: 0 + } + + UM.SettingPropertyProvider + { + id: supportEnabled + + containerStackId: Cura.MachineManager.activeMachineId + key: "support_enable" + watchedProperties: [ "value" ] + storeIndex: 0 + } } diff --git a/resources/qml/SidebarTooltip.qml b/resources/qml/SidebarTooltip.qml index 1c7f4bcb76..5cb7ff1f0b 100644 --- a/resources/qml/SidebarTooltip.qml +++ b/resources/qml/SidebarTooltip.qml @@ -31,7 +31,7 @@ UM.PointingRectangle { y = position.y - UM.Theme.getSize("tooltip_arrow_margins").height; } base.opacity = 1; - target = Qt.point(40 , position.y) + target = Qt.point(40 , position.y + UM.Theme.getSize("tooltip_arrow_margins").height / 2) } function hide() { diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index d5274cd873..bde063de10 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -25,7 +25,7 @@ Item { Repeater { id: repeat - model: UM.Models.toolModel + model: UM.ToolModel { } Button { text: model.name diff --git a/resources/qml/WizardPages/SelectUpgradedParts.qml b/resources/qml/WizardPages/SelectUpgradedParts.qml index 4a327a6ed4..a49401ada9 100644 --- a/resources/qml/WizardPages/SelectUpgradedParts.qml +++ b/resources/qml/WizardPages/SelectUpgradedParts.qml @@ -17,9 +17,6 @@ Item Component.onDestruction: { - if (extruderCheckBox.checked == true){ - UM.MachineManager.setMachineSettingValue("machine_extruder_drive_upgrade", true) - } if (heatedBedCheckBox1.checked == true || heatedBedCheckBox2.checked == true){ UM.MachineManager.setMachineSettingValue("machine_heated_bed", true) } @@ -52,12 +49,6 @@ Item anchors.topMargin: UM.Theme.getSize("default_margin").height width: parent.width - UM.Theme.getSize("default_margin").width CheckBox - { - id: extruderCheckBox - text: catalog.i18nc("@option:check","Extruder driver ugrades") - checked: true - } - CheckBox { id: heatedBedCheckBox1 text: catalog.i18nc("@option:check","Heated printer bed") diff --git a/resources/qml/qmldir b/resources/qml/qmldir new file mode 100644 index 0000000000..096561aca5 --- /dev/null +++ b/resources/qml/qmldir @@ -0,0 +1,3 @@ +module Cura + +singleton Actions 1.0 Actions.qml diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg new file mode 100644 index 0000000000..0329e9ffe1 --- /dev/null +++ b/resources/quality/high.inst.cfg @@ -0,0 +1,10 @@ +[general] +version = 2 +name = High Quality +definition = fdmprinter + +[metadata] +type = quality + +[values] +layer_height = 0.06 diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg new file mode 100644 index 0000000000..6d317cdf7a --- /dev/null +++ b/resources/quality/normal.inst.cfg @@ -0,0 +1,9 @@ +[general] +version = 2 +name = Normal Quality +definition = fdmprinter + +[metadata] +type = quality + +[values] diff --git a/resources/themes/cura/styles.qml b/resources/themes/cura/styles.qml index e536c38ba7..cb85abf0c1 100644 --- a/resources/themes/cura/styles.qml +++ b/resources/themes/cura/styles.qml @@ -280,35 +280,6 @@ QtObject { } } - property variant setting_item: UM.SettingItemStyle { - labelFont: Theme.getFont("default"); - labelColor: Theme.getColor("setting_control_text"); - - spacing: Theme.getSize("default_lining").height; - fixedHeight: Theme.getSize("setting").height; - - controlWidth: Theme.getSize("setting_control").width; - controlRightMargin: Theme.getSize("setting_control_margin").width; - controlColor: Theme.getColor("setting_control"); - controlHighlightColor: Theme.getColor("setting_control_highlight"); - controlBorderColor: Theme.getColor("setting_control_border"); - controlBorderHighlightColor: Theme.getColor("setting_control_border_highlight"); - controlTextColor: Theme.getColor("setting_control_text"); - controlBorderWidth: Theme.getSize("default_lining").width; - controlDisabledColor: Theme.getColor("setting_control_disabled"); - controlDisabledTextColor: Theme.getColor("setting_control_disabled_text"); - controlDisabledBorderColor: Theme.getColor("setting_control_disabled_border"); - controlFont: Theme.getFont("default"); - - validationErrorColor: Theme.getColor("setting_validation_error"); - validationWarningColor: Theme.getColor("setting_validation_warning"); - validationOkColor: Theme.getColor("setting_validation_ok"); - - unitRightMargin: Theme.getSize("setting_unit_margin").width; - unitColor: Theme.getColor("setting_unit"); - unitFont: Theme.getFont("default"); - } - property Component combobox: Component { ComboBoxStyle { background: Rectangle { diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg new file mode 100644 index 0000000000..0c0154c03b --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg @@ -0,0 +1,17 @@ +[general] +name = 0.25 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.25 +machine_nozzle_tip_outer_diameter = 0.8 +coasting_volume = 0.1 +coasting_min_volume = 0.17 +speed_wall = round(speed_print / 1.2, 1) +speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg new file mode 100644 index 0000000000..87b74b2572 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg @@ -0,0 +1,15 @@ +[general] +name = 0.4 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.4 +machine_nozzle_tip_outer_diameter = 1.05 +speed_wall = round(speed_print / 1.25, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg new file mode 100644 index 0000000000..343b2d85e5 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg @@ -0,0 +1,16 @@ +[general] +name = 0.6 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.6 +machine_nozzle_tip_outer_diameter = 1.25 +coasting_volume = 1.36 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg new file mode 100644 index 0000000000..c1bb4555c1 --- /dev/null +++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg @@ -0,0 +1,16 @@ +[general] +name = 0.8 mm +version = 2 +definition = ultimaker2_extended_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.8 +machine_nozzle_tip_outer_diameter = 1.35 +coasting_volume = 3.22 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg new file mode 100644 index 0000000000..51a4b44a4a --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg @@ -0,0 +1,17 @@ +[general] +name = 0.25 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.25 +machine_nozzle_tip_outer_diameter = 0.8 +coasting_volume = 0.1 +coasting_min_volume = 0.17 +speed_wall = round(speed_print / 1.2, 1) +speed_wall_0 = 1 if speed_wall < 5 else (speed_wall - 5) +speed_topbottom = round(speed_print / 1.5, 1) diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg new file mode 100644 index 0000000000..aaea23a8df --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg @@ -0,0 +1,15 @@ +[general] +name = 0.4 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.4 +machine_nozzle_tip_outer_diameter = 1.05 +speed_wall = round(speed_print / 1.25, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2.25, 1) diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg new file mode 100644 index 0000000000..c416b2ec3c --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg @@ -0,0 +1,16 @@ +[general] +name = 0.6 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.6 +machine_nozzle_tip_outer_diameter = 1.25 +coasting_volume = 1.36 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1) diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg new file mode 100644 index 0000000000..3b577384ec --- /dev/null +++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg @@ -0,0 +1,16 @@ +[general] +name = 0.8 mm +version = 2 +definition = ultimaker2_plus + +[metadata] +author = Ultimaker +type = variant + +[values] +machine_nozzle_size = 0.8 +machine_nozzle_tip_outer_diameter = 1.35 +coasting_volume = 3.22 +speed_wall = round(speed_print * 4 / 3, 1) +speed_wall_0 = 1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = round(speed_print / 2, 1)