Merge branch 'master' into feature_enable_disable_extruder

This commit is contained in:
Jack Ha 2018-03-12 09:06:24 +01:00
commit d70cc072e9
478 changed files with 1278 additions and 1379 deletions

View File

@ -1,4 +1,4 @@
# Copyright (c) 2017 Ultimaker B.V.
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import platform
@ -14,10 +14,11 @@ import urllib.request
import urllib.error
import shutil
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl
from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, Qt, QUrl
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton
from PyQt5.QtGui import QDesktopServices
from UM.Resources import Resources
from UM.Application import Application
from UM.Logger import Logger
from UM.View.GL.OpenGL import OpenGL
@ -258,7 +259,7 @@ class CrashHandler:
opengl_instance = OpenGL.getInstance()
if not opengl_instance:
self.data["opengl"] = {"version": "n/a", "vendor": "n/a", "type": "n/a"}
return catalog.i18nc("@label", "not yet initialised<br/>")
return catalog.i18nc("@label", "Not yet initialized<br/>")
info = "<ul>"
info += catalog.i18nc("@label OpenGL version", "<li>OpenGL Version: {version}</li>").format(version = opengl_instance.getOpenGLVersion())

View File

@ -1,5 +1,6 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
#Type hinting.
from typing import Dict
@ -208,10 +209,10 @@ class CuraApplication(QtApplication):
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
{
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
}
)
@ -1693,7 +1694,7 @@ class CuraApplication(QtApplication):
result = workspace_reader.preRead(file_path, show_dialog=False)
return result == WorkspaceReader.PreReadResult.accepted
except Exception as e:
Logger.log("e", "Could not check file %s: %s", file_url, e)
Logger.logException("e", "Could not check file %s: %s", file_url)
return False
def _onContextMenuRequested(self, x: float, y: float) -> None:

View File

@ -357,10 +357,10 @@ class MaterialManager(QObject):
else:
return None
def getDefaultMaterial(self, global_stack: "GlobalStack", extruder_variant_name: str) -> Optional["MaterialNode"]:
def getDefaultMaterial(self, global_stack: "GlobalStack", extruder_variant_name: Optional[str]) -> Optional["MaterialNode"]:
node = None
machine_definition = global_stack.definition
if parseBool(machine_definition.getMetaDataEntry("has_materials", False)):
if parseBool(global_stack.getMetaDataEntry("has_materials", False)):
material_diameter = machine_definition.getProperty("material_diameter", "value")
if isinstance(material_diameter, SettingFunction):
material_diameter = material_diameter(global_stack)

View File

@ -122,17 +122,17 @@ class BrandMaterialsModel(ListModel):
material_type_item["colors"].clear()
# Sort materials by name
material_list = sorted(material_list, key = lambda x: x["name"])
material_list = sorted(material_list, key = lambda x: x["name"].upper())
material_type_item["colors"].setItems(material_list)
material_type_item_list.append(material_type_item)
# Sort material type by name
material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"])
material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"].upper())
brand_item["materials"].setItems(material_type_item_list)
brand_item_list.append(brand_item)
# Sort brand by name
brand_item_list = sorted(brand_item_list, key = lambda x: x["name"])
brand_item_list = sorted(brand_item_list, key = lambda x: x["name"].upper())
self.setItems(brand_item_list)

View File

@ -23,7 +23,7 @@ class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel):
quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack)
item_list = []
for key in sorted(quality_changes_group_dict):
for key in sorted(quality_changes_group_dict, key = lambda name: name.upper()):
quality_changes_group = quality_changes_group_dict[key]
item = {"name": quality_changes_group.name,

View File

@ -55,6 +55,6 @@ class GenericMaterialsModel(BaseMaterialsModel):
item_list.append(item)
# Sort the item list by material name alphabetically
item_list = sorted(item_list, key = lambda d: d["name"])
item_list = sorted(item_list, key = lambda d: d["name"].upper())
self.setItems(item_list)

View File

@ -97,5 +97,5 @@ class MaterialManagementModel(ListModel):
material_list.append(item)
material_list = sorted(material_list, key = lambda k: (k["brand"].lower(), k["name"]))
material_list = sorted(material_list, key = lambda k: (k["brand"].upper(), k["name"].upper()))
self.setItems(material_list)

View File

@ -45,7 +45,7 @@ class NozzleModel(ListModel):
return
item_list = []
for hotend_name, container_node in sorted(variant_node_dict.items(), key = lambda i: i[0]):
for hotend_name, container_node in sorted(variant_node_dict.items(), key = lambda i: i[0].upper()):
item = {"id": hotend_name,
"hotend_name": hotend_name,
"container_node": container_node

View File

@ -59,7 +59,7 @@ class QualityManagementModel(ListModel):
"quality_changes_group": None}
item_list.append(item)
# Sort by quality names
item_list = sorted(item_list, key = lambda x: x["name"])
item_list = sorted(item_list, key = lambda x: x["name"].upper())
# Create quality_changes group items
quality_changes_item_list = []
@ -74,7 +74,7 @@ class QualityManagementModel(ListModel):
quality_changes_item_list.append(item)
# Sort quality_changes items by names and append to the item list
quality_changes_item_list = sorted(quality_changes_item_list, key = lambda x: x["name"])
quality_changes_item_list = sorted(quality_changes_item_list, key = lambda x: x["name"].upper())
item_list += quality_changes_item_list
self.setItems(item_list)

View File

@ -69,7 +69,7 @@ class QualitySettingsModel(ListModel):
return self._selected_quality_item
def _update(self):
if self._selected_quality_item is None:
if not self._selected_quality_item:
self.setItems([])
return

View File

@ -7,47 +7,21 @@ from .QualityGroup import QualityGroup
class QualityChangesGroup(QualityGroup):
def __init__(self, name: str, quality_type: str, parent = None):
super().__init__(name, quality_type, parent)
self._container_registry = Application.getInstance().getContainerRegistry()
def addNode(self, node: "QualityNode"):
# TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the
# extruder definition ID it belongs to. But, in fact, we only need to know the following things:
# 1. which machine a custom profile is suitable for,
# 2. if this profile is for the GlobalStack,
# 3. if this profile is for an ExtruderStack and which one (the position).
#
# So, it is preferred to have a field like this:
# extruder_position = 1
# instead of this:
# extruder = custom_extruder_1
#
# An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition
# to figure out its position.
#
extruder_definition_id = node.metadata.get("extruder")
if extruder_definition_id:
metadata_list = self._container_registry.findDefinitionContainersMetadata(id = extruder_definition_id)
if not metadata_list:
raise RuntimeError("%s cannot get metadata for extruder definition [%s]" %
(self, extruder_definition_id))
extruder_definition_metadata = metadata_list[0]
extruder_position = str(extruder_definition_metadata["position"])
extruder_position = node.metadata.get("position")
if extruder_position is None: #Then we're a global quality changes profile.
if self.node_for_global is not None:
raise RuntimeError("{group} tries to overwrite the existing node_for_global {original_global} with {new_global}".format(group = self, original_global = self.node_for_global, new_global = node))
self.node_for_global = node
else: #This is an extruder's quality changes profile.
if extruder_position in self.nodes_for_extruders:
raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" %
(self, extruder_position, self.node_for_global, node))
self.nodes_for_extruders[extruder_position] = node
else:
# This is a quality_changes for the GlobalStack
if self.node_for_global is not None:
raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" %
(self, self.node_for_global, node))
self.node_for_global = node
def __str__(self) -> str:
return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available)

View File

@ -386,7 +386,7 @@ class QualityManager(QObject):
if quality_changes_group is None:
# create global quality changes only
new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name,
global_stack, extruder_id = None)
global_stack, None)
self._container_registry.addContainer(new_quality_changes)
else:
new_name = self._container_registry.uniqueName(quality_changes_name)
@ -428,11 +428,11 @@ class QualityManager(QObject):
Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
continue
extruder_definition_id = None
if isinstance(stack, ExtruderStack):
extruder_definition_id = stack.definition.getId()
quality_type = quality_container.getMetaDataEntry("quality_type")
new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id)
extruder_stack = None
if isinstance(stack, ExtruderStack):
extruder_stack = stack
new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_stack)
from cura.Settings.ContainerManager import ContainerManager
ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
ContainerManager.getInstance()._performMerge(new_changes, user_container)
@ -443,8 +443,8 @@ class QualityManager(QObject):
# Create a quality changes container with the given setup.
#
def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack",
extruder_id: Optional[str]) -> "InstanceContainer":
base_id = machine.definition.getId() if extruder_id is None else extruder_id
extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
base_id = machine.definition.getId() if extruder_stack is None else extruder_stack.getId()
new_id = base_id + "_" + new_name
new_id = new_id.lower().replace(" ", "_")
new_id = self._container_registry.uniqueName(new_id)
@ -456,8 +456,8 @@ class QualityManager(QObject):
quality_changes.addMetaDataEntry("quality_type", quality_type)
# If we are creating a container for an extruder, ensure we add that to the container
if extruder_id is not None:
quality_changes.addMetaDataEntry("extruder", extruder_id)
if extruder_stack is not None:
quality_changes.addMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
# If the machine specifies qualities should be filtered, ensure we match the current criteria.
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)

View File

@ -3,6 +3,13 @@
from UM.PluginObject import PluginObject
# Exception when there is no profile to import from a given files.
# Note that this should not be treated as an exception but as an information instead.
class NoProfileException(Exception):
pass
## A type of plug-ins that reads profiles from a file.
#
# The profile is then stored as instance container of the type user profile.
@ -14,4 +21,4 @@ class ProfileReader(PluginObject):
#
# \return \type{Profile|Profile[]} The profile that was obtained from the file or a list of Profiles.
def read(self, file_name):
raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.")
raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.")

View File

@ -29,6 +29,7 @@ from .ExtruderManager import ExtruderManager
from cura.CuraApplication import CuraApplication
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
from cura.ProfileReader import NoProfileException
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
@ -185,6 +186,8 @@ class CuraContainerRegistry(ContainerRegistry):
profile_reader = plugin_registry.getPluginObject(plugin_id)
try:
profile_or_list = profile_reader.read(file_name) # Try to open the file with the profile reader.
except NoProfileException:
return { "status": "ok", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "No custom profile to import in file <filename>{0}</filename>", file_name)}
except Exception as e:
# Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
Logger.log("e", "Failed to import profile from %s: %s while using profile reader. Got exception %s", file_name,profile_reader.getPluginId(), str(e))

View File

@ -950,7 +950,7 @@ class MachineManager(QObject):
quality_node = quality_group.nodes_for_extruders.get(position)
quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_changes_container
quality_container = self._empty_quality_container
if quality_changes_node:
quality_changes_container = quality_changes_node.getContainer()
if quality_node:
@ -974,11 +974,13 @@ class MachineManager(QObject):
def _setMaterial(self, position, container_node = None):
if container_node:
self._global_container_stack.extruders[position].material = container_node.getContainer()
root_material_id = container_node.metadata["base_file"]
root_material_name = container_node.getContainer().getName()
else:
self._global_container_stack.extruders[position].material = self._empty_material_container
root_material_id = None
root_material_name = None
# The _current_root_material_id is used in the MaterialMenu to see which material is selected
root_material_id = container_node.metadata["base_file"]
root_material_name = container_node.getContainer().getName()
if root_material_id != self._current_root_material_id[position]:
self._current_root_material_id[position] = root_material_id
self._current_root_material_name[position] = root_material_name
@ -1081,13 +1083,13 @@ class MachineManager(QObject):
self._updateQualityWithMaterial()
@pyqtSlot(QObject)
def setQualityGroup(self, quality_group):
def setQualityGroup(self, quality_group, no_dialog = False):
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self._setQualityGroup(quality_group)
# See if we need to show the Discard or Keep changes screen
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
self._application.discardOrKeepProfileChanges()
@pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
@ -1095,13 +1097,13 @@ class MachineManager(QObject):
return self._current_quality_group
@pyqtSlot(QObject)
def setQualityChangesGroup(self, quality_changes_group):
def setQualityChangesGroup(self, quality_changes_group, no_dialog = False):
self.blurSettings.emit()
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self._setQualityChangesGroup(quality_changes_group)
# See if we need to show the Discard or Keep changes screen
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
self._application.discardOrKeepProfileChanges()
@pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)

File diff suppressed because it is too large Load Diff

View File

@ -52,7 +52,6 @@ class WorkspaceDialog(QObject):
machineConflictChanged = pyqtSignal()
qualityChangesConflictChanged = pyqtSignal()
definitionChangesConflictChanged = pyqtSignal()
materialConflictChanged = pyqtSignal()
numVisibleSettingsChanged = pyqtSignal()
activeModeChanged = pyqtSignal()
@ -196,10 +195,6 @@ class WorkspaceDialog(QObject):
def qualityChangesConflict(self):
return self._has_quality_changes_conflict
@pyqtProperty(bool, notify=definitionChangesConflictChanged)
def definitionChangesConflict(self):
return self._has_definition_changes_conflict
@pyqtProperty(bool, notify=materialConflictChanged)
def materialConflict(self):
return self._has_material_conflict
@ -229,18 +224,11 @@ class WorkspaceDialog(QObject):
self._has_quality_changes_conflict = quality_changes_conflict
self.qualityChangesConflictChanged.emit()
def setDefinitionChangesConflict(self, definition_changes_conflict):
if self._has_definition_changes_conflict != definition_changes_conflict:
self._has_definition_changes_conflict = definition_changes_conflict
self.definitionChangesConflictChanged.emit()
def getResult(self):
if "machine" in self._result and not self._has_machine_conflict:
self._result["machine"] = None
if "quality_changes" in self._result and not self._has_quality_changes_conflict:
self._result["quality_changes"] = None
if "definition_changes" in self._result and not self._has_definition_changes_conflict:
self._result["definition_changes"] = None
if "material" in self._result and not self._has_material_conflict:
self._result["material"] = None

View File

@ -1,3 +1,9 @@
[3.2.1]
*Bug fixes
- Fixed issues where Cura crashes on startup and loading profiles
- Updated translations
- Fixed an issue where the text would not render properly
[3.2.0]
*Tree support
Experimental tree-like support structure that uses branches to support prints. Branches grow and multiply towards the model, with fewer contact points than alternative support methods. This results in better surface finishes for organic-shaped prints.

View File

@ -141,7 +141,7 @@ class StartSliceJob(Job):
# Don't slice if there is a per object setting with an error value.
for node in DepthFirstIterator(self._scene.getRoot()):
if type(node) is not CuraSceneNode or not node.isSelectable():
if not isinstance(node, CuraSceneNode) or not node.isSelectable():
continue
if self._checkStackForErrors(node.callDecoration("getStack")):

View File

@ -9,7 +9,7 @@ from UM.Logger import Logger
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
from cura.ProfileReader import ProfileReader
from cura.ProfileReader import ProfileReader, NoProfileException
## A class that reads profile data from g-code files.
#
@ -66,6 +66,11 @@ class GCodeProfileReader(ProfileReader):
return None
serialized = unescapeGcodeComment(serialized)
serialized = serialized.strip()
if not serialized:
Logger.log("i", "No custom profile to import from this g-code: %s", file_name)
raise NoProfileException()
# serialized data can be invalid JSON
try:

View File

@ -2,20 +2,16 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal
import UM.i18n
from UM.FlameProfiler import pyqtSlot
from cura.MachineAction import MachineAction
from UM.Application import Application
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Logger import Logger
from cura.Settings.ExtruderManager import ExtruderManager
from cura.MachineAction import MachineAction
from cura.Settings.CuraStackBuilder import CuraStackBuilder
import UM.i18n
catalog = UM.i18n.i18nCatalog("cura")
@ -26,6 +22,8 @@ class MachineSettingsAction(MachineAction):
super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
self._qml_url = "MachineSettingsAction.qml"
self._application = Application.getInstance()
self._global_container_stack = None
from cura.Settings.CuraContainerStack import _ContainerIndexes
@ -34,38 +32,44 @@ class MachineSettingsAction(MachineAction):
self._container_registry = ContainerRegistry.getInstance()
self._container_registry.containerAdded.connect(self._onContainerAdded)
self._container_registry.containerRemoved.connect(self._onContainerRemoved)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._empty_container = self._container_registry.getEmptyInstanceContainer()
self._backend = self._application.getBackend()
self._backend = Application.getInstance().getBackend()
self._empty_definition_container_id_list = []
def _isEmptyDefinitionChanges(self, container_id: str):
if not self._empty_definition_container_id_list:
self._empty_definition_container_id_list = [self._application.empty_container.getId(),
self._application.empty_definition_changes_container.getId()]
return container_id in self._empty_definition_container_id_list
def _onContainerAdded(self, container):
# Add this action as a supported action to all machine definitions
if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
self._application.getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
def _onContainerRemoved(self, container):
# Remove definition_changes containers when a stack is removed
if container.getMetaDataEntry("type") in ["machine", "extruder_train"]:
definition_changes_container = container.definitionChanges
if definition_changes_container == self._empty_container:
definition_changes_id = container.definitionChanges.getId()
if self._isEmptyDefinitionChanges(definition_changes_id):
return
self._container_registry.removeContainer(definition_changes_container.getId())
self._container_registry.removeContainer(definition_changes_id)
def _reset(self):
if not self._global_container_stack:
return
# Make sure there is a definition_changes container to store the machine settings
definition_changes_container = self._global_container_stack.definitionChanges
if definition_changes_container == self._empty_container:
definition_changes_container = CuraStackBuilder.createDefinitionChangesContainer(
self._global_container_stack, self._global_container_stack.getName() + "_settings")
definition_changes_id = self._global_container_stack.definitionChanges.getId()
if self._isEmptyDefinitionChanges(definition_changes_id):
CuraStackBuilder.createDefinitionChangesContainer(self._global_container_stack,
self._global_container_stack.getName() + "_settings")
# Notify the UI in which container to store the machine settings data
from cura.Settings.CuraContainerStack import CuraContainerStack, _ContainerIndexes
from cura.Settings.CuraContainerStack import _ContainerIndexes
container_index = _ContainerIndexes.DefinitionChanges
if container_index != self._container_index:
@ -107,13 +111,13 @@ class MachineSettingsAction(MachineAction):
def setMachineExtruderCount(self, extruder_count):
# Note: this method was in this class before, but since it's quite generic and other plugins also need it
# it was moved to the machine manager instead. Now this method just calls the machine manager.
Application.getInstance().getMachineManager().setActiveMachineExtruderCount(extruder_count)
self._application.getMachineManager().setActiveMachineExtruderCount(extruder_count)
@pyqtSlot()
def forceUpdate(self):
# Force rebuilding the build volume by reloading the global container stack.
# This is a bit of a hack, but it seems quick enough.
Application.getInstance().globalContainerStackChanged.emit()
self._application.globalContainerStackChanged.emit()
@pyqtSlot()
def updateHasMaterialsMetadata(self):
@ -126,9 +130,11 @@ class MachineSettingsAction(MachineAction):
# In other words: only continue for the UM2 (extended), but not for the UM2+
return
stacks = ExtruderManager.getInstance().getExtruderStacks()
machine_manager = self._application.getMachineManager()
extruder_positions = list(self._global_container_stack.extruders.keys())
has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
material_node = None
if has_materials:
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.setMetaDataEntry("has_materials", True)
@ -136,26 +142,22 @@ class MachineSettingsAction(MachineAction):
self._global_container_stack.addMetaDataEntry("has_materials", True)
# Set the material container for each extruder to a sane default
for stack in stacks:
material_container = stack.material
if material_container == self._empty_container:
machine_approximate_diameter = str(round(self._global_container_stack.getProperty("material_diameter", "value")))
search_criteria = { "type": "material", "definition": "fdmprinter", "id": self._global_container_stack.getMetaDataEntry("preferred_material"), "approximate_diameter": machine_approximate_diameter}
materials = self._container_registry.findInstanceContainers(**search_criteria)
if materials:
stack.material = materials[0]
material_manager = self._application.getMaterialManager()
material_node = material_manager.getDefaultMaterial(self._global_container_stack, None)
else:
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.removeMetaDataEntry("has_materials")
for stack in stacks:
stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer()
# set materials
for position in extruder_positions:
machine_manager.setMaterial(position, material_node)
Application.getInstance().globalContainerStackChanged.emit()
self._application.globalContainerStackChanged.emit()
@pyqtSlot(int)
def updateMaterialForDiameter(self, extruder_position: int):
# Updates the material container to a material that matches the material diameter set for the printer
Application.getInstance().getExtruderManager().updateMaterialForDiameter(extruder_position)
self._application.getExtruderManager().updateMaterialForDiameter(extruder_position)

View File

@ -1,3 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import List
from cura.MachineAction import MachineAction
from cura.PrinterOutputDevice import PrinterOutputDevice
@ -5,6 +10,7 @@ from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
from UM.i18n import i18nCatalog
from UM.Logger import Logger
catalog = i18nCatalog("cura")
@ -26,38 +32,45 @@ class BedLevelMachineAction(MachineAction):
@pyqtSlot()
def startBedLeveling(self):
self._bed_level_position = 0
printer_output_devices = self._getPrinterOutputDevices()
if printer_output_devices:
printer_output_devices[0].homeBed()
printer_output_devices[0].moveHead(0, 0, 3)
printer_output_devices[0].homeHead()
def _getPrinterOutputDevices(self):
printer_output_devices = self._getPrinterOutputDevices()
if not printer_output_devices:
Logger.log("e", "Can't start bed levelling. The printer connection seems to have been lost.")
return
printer = printer_output_devices[0].activePrinter
printer.homeBed()
printer.moveHead(0, 0, 3)
printer.homeHead()
def _getPrinterOutputDevices(self) -> List[PrinterOutputDevice]:
return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)]
@pyqtSlot()
def moveToNextLevelPosition(self):
output_devices = self._getPrinterOutputDevices()
if output_devices: # We found at least one output device
output_device = output_devices[0]
if not output_devices: #No output devices. Can't move.
Logger.log("e", "Can't move to the next position. The printer connection seems to have been lost.")
return
printer = output_devices[0].activePrinter
if self._bed_level_position == 0:
output_device.moveHead(0, 0, 3)
output_device.homeHead()
output_device.moveHead(0, 0, 3)
output_device.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0)
output_device.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position == 1:
output_device.moveHead(0, 0, 3)
output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value" ) / 2, Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") - 10, 0)
output_device.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position == 2:
output_device.moveHead(0, 0, 3)
output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") / 2 + 10, -(Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") + 10), 0)
output_device.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position >= 3:
output_device.sendCommand("M18") # Turn off all motors so the user can move the axes
self.setFinished()
if self._bed_level_position == 0:
printer.moveHead(0, 0, 3)
printer.homeHead()
printer.moveHead(0, 0, 3)
printer.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0)
printer.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position == 1:
printer.moveHead(0, 0, 3)
printer.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value" ) / 2, Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") - 10, 0)
printer.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position == 2:
printer.moveHead(0, 0, 3)
printer.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") / 2 + 10, -(Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") + 10), 0)
printer.moveHead(0, 0, -3)
self._bed_level_position += 1
elif self._bed_level_position >= 3:
output_devices[0].sendCommand("M18") # Turn off all motors so the user can move the axes
self.setFinished()

View File

@ -33,6 +33,10 @@ def getMetaData():
"get_version": upgrade.getCfgVersion,
"location": {"./extruders"}
},
"quality": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}

View File

@ -0,0 +1,111 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import configparser #To parse preference files.
import io #To serialise the preference files afterwards.
from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this.
## Mapping extruder definition IDs to the positions that they are in.
_EXTRUDER_TO_POSITION = {
"builder_premium_large_front": 1,
"builder_premium_large_rear": 0,
"builder_premium_medium_front": 1,
"builder_premium_medium_rear": 0,
"builder_premium_small_front": 1,
"builder_premium_small_rear": 0,
"cartesio_extruder_0": 0,
"cartesio_extruder_1": 1,
"cartesio_extruder_2": 2,
"cartesio_extruder_3": 3,
"custom_extruder_1": 0, #Warning, non-programmers are attempting to count here.
"custom_extruder_2": 1,
"custom_extruder_3": 2,
"custom_extruder_4": 3,
"custom_extruder_5": 4,
"custom_extruder_6": 5,
"custom_extruder_7": 6,
"custom_extruder_8": 7,
"hBp_extruder_left": 0,
"hBp_extruder_right": 1,
"makeit_dual_1st": 0,
"makeit_dual_2nd": 1,
"makeit_l_dual_1st": 0,
"makeit_l_dual_2nd": 1,
"ord_extruder_0": 0,
"ord_extruder_1": 1,
"ord_extruder_2": 2,
"ord_extruder_3": 3,
"ord_extruder_4": 4,
"punchtec_connect_xl_extruder_left": 0,
"punchtec_connect_xl_extruder_right": 1,
"raise3D_N2_dual_extruder_0": 0,
"raise3D_N2_dual_extruder_1": 1,
"raise3D_N2_plus_dual_extruder_0": 0,
"raise3D_N2_plus_dual_extruder_1": 1,
"ultimaker3_extended_extruder_left": 0,
"ultimaker3_extended_extruder_right": 1,
"ultimaker3_extruder_left": 0,
"ultimaker3_extruder_right": 1,
"ultimaker_original_dual_1st": 0,
"ultimaker_original_dual_2nd": 1,
"vertex_k8400_dual_1st": 0,
"vertex_k8400_dual_2nd": 1
}
## Upgrades configurations from the state they were in at version 3.2 to the
# state they should be in at version 3.3.
class VersionUpgrade32to33(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 3.2 format.
#
# Since the format may change, this is implemented for the 3.2 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
# \param serialised The serialised form of a CFG file.
# \return The version number stored in the CFG file.
# \raises ValueError The format of the version number in the file is
# incorrect.
# \raises KeyError The format of the file is incorrect.
def getCfgVersion(self, serialised):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
setting_version = int(parser.get("metadata", "setting_version", fallback = 0))
return format_version * 1000000 + setting_version
## Upgrades non-quality-changes instance containers to have the new version
# number.
def upgradeInstanceContainer(self, serialized, filename):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
#Update version number.
parser["general"]["version"] = "3"
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
## Upgrades a quality changes container to the new format.
def upgradeQualityChanges(self, serialized, filename):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
#Extruder quality changes profiles have the extruder position instead of the ID of the extruder definition.
if "metadata" in parser and "extruder" in parser["metadata"]: #Only do this for extruder profiles.
extruder_id = parser["metadata"]["extruder"]
if extruder_id in _EXTRUDER_TO_POSITION:
extruder_position = _EXTRUDER_TO_POSITION[extruder_id]
else:
extruder_position = 0 #The user was using custom extruder definitions. He's on his own then.
parser["metadata"]["position"] = str(extruder_position)
del parser["metadata"]["extruder"]
#Update version number.
parser["general"]["version"] = "3"
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]

View File

@ -0,0 +1,33 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from . import VersionUpgrade32to33
upgrade = VersionUpgrade32to33.VersionUpgrade32to33()
def getMetaData():
return {
"version_upgrade": {
# From To Upgrade function
("definition_changes", 2000004): ("definition_changes", 3000004, upgrade.upgradeInstanceContainer),
("quality_changes", 2000004): ("quality_changes", 3000004, upgrade.upgradeQualityChanges),
("user", 2000004): ("user", 3000004, upgrade.upgradeInstanceContainer)
},
"sources": {
"definition_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./definition_changes"}
},
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
}
}
}
def register(app):
return { "version_upgrade": upgrade }

View File

@ -0,0 +1,8 @@
{
"name": "Version Upgrade 3.2 to 3.3",
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
"api": 4,
"i18n-catalog": "cura"
}

View File

@ -6248,7 +6248,6 @@
"description": "Detect bridges and modify print speed, flow and fan settings while bridges are printed.",
"type": "bool",
"default_value": false,
"value": "not support_enable and not support_tree_enable",
"settable_per_mesh": true,
"settable_per_extruder": false,
"settable_per_meshgroup": false

View File

@ -2,7 +2,8 @@
"version": 2,
"name": "Tevo Tarantula",
"inherits": "fdmprinter",
"metadata": {
"metadata":
{
"visible": true,
"author": "TheAssassin",
"manufacturer": "Tevo",
@ -11,62 +12,39 @@
"platform": "prusai3_platform.stl"
},
"overrides": {
"machine_name": {
"default_value": "Tevo Tarantula"
},
"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_head_polygon": {
"default_value": [
"overrides":
{
"machine_name": { "default_value": "Tevo Tarantula" },
"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_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_acceleration": {
"default_value": 500
},
"machine_max_jerk_xy": {
"default_value": 4.0
},
"machine_max_jerk_z": {
"default_value": 0.2
},
"machine_max_jerk_e": {
"default_value": 2.5
},
"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\nG90 ;absolute positioning\nG1 X0 Y200 F3600 ;move extruder out of the way by moving the baseplate to the front for easier access to printed object\nM84 ;steppers off"
}
"gantry_height": { "default_value": 55 },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_acceleration": { "default_value": 2650 },
"machine_max_jerk_xy": { "default_value": 15.0 },
"machine_max_jerk_z": { "default_value": 0.4 },
"machine_max_jerk_e": { "default_value": 5 },
"machine_max_feedrate_x": { "default_value": 255 },
"machine_max_feedrate_y": { "default_value": 225 },
"machine_max_feedrate_z": { "default_value": 3 },
"machine_max_acceleration_x": { "default_value": 2620 },
"machine_max_acceleration_y": { "default_value": 2650 },
"acceleration_print": { "default_value": 2650 },
"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\nG90 ;absolute positioning\nG1 X0 Y200 F3600 ;move extruder out of the way by moving the baseplate to the front for easier access to printed object\nM84 ;steppers off" }
}
}

View File

@ -103,6 +103,7 @@ material_print_temperature_layer_0
material_initial_print_temperature
material_final_print_temperature
material_extrusion_cool_down_speed
default_material_bed_temperature
material_bed_temperature
material_bed_temperature_layer_0
material_diameter

View File

@ -14,6 +14,15 @@ Tab
property string extruderPosition: ""
property var qualityItem: null
property bool isQualityItemCurrentlyActivated:
{
if (qualityItem == null)
{
return false;
}
return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
}
TableView
{
anchors.fill: parent
@ -36,8 +45,8 @@ Tab
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value
font.strikeout: styleData.column == 1 && setting.user_value != "" && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName)
font.strikeout: styleData.column == 1 && setting.user_value != "" && base.isQualityItemCurrentlyActivated
font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && base.isQualityItemCurrentlyActivated)
opacity: font.strikeout ? 0.5 : 1
color: styleData.textColor
elide: Text.ElideRight
@ -63,7 +72,7 @@ Tab
{
role: "user_value"
title: catalog.i18nc("@title:column", "Current");
visible: qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
visible: base.isQualityItemCurrentlyActivated
width: (parent.width * 0.18) | 0
delegate: itemDelegate
}
@ -86,7 +95,7 @@ Tab
{
id: qualitySettings
selectedPosition: base.extruderPosition
selectedQualityItem: base.qualityItem
selectedQualityItem: base.qualityItem == null ? {} : base.qualityItem
}
SystemPalette { id: palette }

View File

@ -36,13 +36,15 @@ Item
text: catalog.i18nc("@title:tab", "Profiles")
}
property var hasCurrentItem: qualityListView.currentItem != null
property var hasCurrentItem: base.currentItem != null
property var currentItem: {
var current_index = qualityListView.currentIndex;
return qualitiesModel.getItem(current_index);
return (current_index == -1) ? null : qualitiesModel.getItem(current_index);
}
property var currentItemName: hasCurrentItem ? base.currentItem.name : ""
property var isCurrentItemActivated: {
if (!base.currentItem) {
return false;
@ -235,7 +237,7 @@ Item
icon: StandardIcon.Question;
title: catalog.i18nc("@title:window", "Confirm Remove")
text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name)
text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItemName)
standardButtons: StandardButton.Yes | StandardButton.No
modality: Qt.ApplicationModal
@ -437,6 +439,7 @@ Item
Item
{
anchors.fill: parent
visible: base.currentItem != null
Item // Profile title Label
{
@ -446,7 +449,7 @@ Item
height: childrenRect.height
Label {
text: base.currentItem.name
text: base.currentItemName
font: UM.Theme.getFont("large")
}
}

View File

@ -122,7 +122,7 @@ Column
{
label: catalog.i18nc("@label", "Printing Time")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : ""
width:base.width
width: base.width
visible: activePrinter != null
}

View File

@ -64,11 +64,11 @@ Rectangle
function getPrettyTime(time)
{
var hours = Math.round(time / 3600)
var hours = Math.floor(time / 3600)
time -= hours * 3600
var minutes = Math.round(time / 60);
var minutes = Math.floor(time / 60);
time -= minutes * 60
var seconds = Math.round(time);
var seconds = Math.floor(time);
var finalTime = strPadLeft(hours, "0", 2) + ':' + strPadLeft(minutes,'0',2)+ ':' + strPadLeft(seconds,'0',2);
return finalTime;

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_pri3

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Fine
definition = abax_pri3

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_pri3

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_pri5

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Fine
definition = abax_pri5

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_pri5

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_titan

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Fine
definition = abax_titan

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Fine
definition = abax_titan

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Draft
definition = anycubic_i3_mega

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = anycubic_i3_mega

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = anycubic_i3_mega

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High Quality
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = builder_premium_small

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Normal
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = Extra Coarse
definition = cartesio

View File

@ -1,5 +1,5 @@
[general]
version = 2
version = 3
name = High
definition = cartesio

Some files were not shown because too many files have changed in this diff Show More