mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-12 07:28:59 +08:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
3e869048fd
@ -19,7 +19,7 @@ from UM.JobQueue import JobQueue
|
||||
from UM.SaveFile import SaveFile
|
||||
from UM.Scene.Selection import Selection
|
||||
from UM.Scene.GroupDecorator import GroupDecorator
|
||||
import UM.Settings.Validator
|
||||
from UM.Settings.Validator import Validator
|
||||
|
||||
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
||||
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
||||
@ -99,7 +99,32 @@ class CuraApplication(QtApplication):
|
||||
SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True)
|
||||
SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True)
|
||||
SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True)
|
||||
SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)
|
||||
SettingDefinition.addSettingType("extruder", int, str, Validator)
|
||||
|
||||
## 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.UserInstanceContainer, "user")
|
||||
Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
|
||||
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.ExtruderStack)
|
||||
ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack)
|
||||
|
||||
## Initialise the version upgrade manager with Cura's storage paths.
|
||||
import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies.
|
||||
self._version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager(
|
||||
{
|
||||
("quality", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||
("machine_stack", UM.Settings.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
||||
("preferences", UM.Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences")
|
||||
}
|
||||
)
|
||||
|
||||
self._machine_action_manager = MachineActionManager.MachineActionManager()
|
||||
|
||||
@ -142,21 +167,6 @@ class CuraApplication(QtApplication):
|
||||
|
||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading machines..."))
|
||||
|
||||
## 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.UserInstanceContainer, "user")
|
||||
Resources.addStorageType(self.ResourceTypes.ExtruderStack, "extruders")
|
||||
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.ExtruderStack)
|
||||
ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack)
|
||||
|
||||
# Add empty variant, material and quality containers.
|
||||
# Since they are empty, they should never be serialized and instead just programmatically created.
|
||||
# We need them to simplify the switching between materials.
|
||||
|
@ -80,7 +80,6 @@ class CuraEngineBackend(Backend):
|
||||
self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage
|
||||
self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage
|
||||
self._message_handlers["cura.proto.PrintTimeMaterialEstimates"] = self._onPrintTimeMaterialEstimates
|
||||
#self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage
|
||||
self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage
|
||||
|
||||
self._start_slice_job = None
|
||||
|
@ -37,9 +37,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
||||
self._connect_thread = threading.Thread(target = self._connect)
|
||||
self._connect_thread.daemon = True
|
||||
|
||||
self._end_stop_thread = threading.Thread(target = self._pollEndStop)
|
||||
self._end_stop_thread.daemon = True
|
||||
self._poll_endstop = -1
|
||||
self._end_stop_thread = None
|
||||
self._poll_endstop = False
|
||||
|
||||
# The baud checking is done by sending a number of m105 commands to the printer and waiting for a readable
|
||||
# response. If the baudrate is correct, this should make sense, else we get giberish.
|
||||
@ -221,13 +220,17 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
||||
|
||||
@pyqtSlot()
|
||||
def startPollEndstop(self):
|
||||
if self._poll_endstop == -1:
|
||||
if not self._poll_endstop:
|
||||
self._poll_endstop = True
|
||||
if self._end_stop_thread is None:
|
||||
self._end_stop_thread = threading.Thread(target=self._pollEndStop)
|
||||
self._end_stop_thread.daemon = True
|
||||
self._end_stop_thread.start()
|
||||
|
||||
@pyqtSlot()
|
||||
def stopPollEndstop(self):
|
||||
self._poll_endstop = False
|
||||
self._end_stop_thread = None
|
||||
|
||||
def _pollEndStop(self):
|
||||
while self._connection_state == ConnectionState.connected and self._poll_endstop:
|
||||
|
@ -157,9 +157,19 @@ class UMOCheckupMachineAction(MachineAction):
|
||||
self._output_device.bedTemperatureChanged.connect(self._onBedTemperatureChanged)
|
||||
self._output_device.hotendTemperaturesChanged.connect(self._onHotendTemperatureChanged)
|
||||
self._output_device.endstopStateChanged.connect(self._onEndstopStateChanged)
|
||||
except AttributeError: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
except AttributeError as e: # Connection is probably not a USB connection. Something went pretty wrong if this happens.
|
||||
pass
|
||||
|
||||
@pyqtSlot()
|
||||
def cooldownHotend(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetHotendTemperature(0, 0)
|
||||
|
||||
@pyqtSlot()
|
||||
def cooldownBed(self):
|
||||
if self._output_device is not None:
|
||||
self._output_device.setTargetBedTemperature(0)
|
||||
|
||||
@pyqtSlot()
|
||||
def heatupHotend(self):
|
||||
if self._output_device is not None:
|
||||
|
@ -15,6 +15,8 @@ Cura.MachineAction
|
||||
anchors.fill: parent;
|
||||
property int leftRow: checkupMachineAction.width * 0.40
|
||||
property int rightRow: checkupMachineAction.width * 0.60
|
||||
property bool heatupHotendStarted: false
|
||||
property bool heatupBedStarted: false
|
||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||
Label
|
||||
{
|
||||
@ -51,6 +53,8 @@ Cura.MachineAction
|
||||
text: catalog.i18nc("@action:button","Start Printer Check");
|
||||
onClicked:
|
||||
{
|
||||
checkupMachineAction.heatupHotendStarted = false
|
||||
checkupMachineAction.heatupBedStarted = false
|
||||
manager.startCheck()
|
||||
}
|
||||
}
|
||||
@ -181,10 +185,19 @@ Cura.MachineAction
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
text: checkupMachineAction.heatupHotendStarted ? catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
|
||||
//
|
||||
onClicked:
|
||||
{
|
||||
manager.heatupHotend()
|
||||
if (checkupMachineAction.heatupHotendStarted)
|
||||
{
|
||||
manager.cooldownHotend()
|
||||
checkupMachineAction.heatupHotendStarted = false
|
||||
} else
|
||||
{
|
||||
manager.heatupHotend()
|
||||
checkupMachineAction.heatupHotendStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,10 +243,18 @@ Cura.MachineAction
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
|
||||
Button
|
||||
{
|
||||
text: catalog.i18nc("@action:button","Start Heating")
|
||||
text: checkupMachineAction.heatupBedStarted ?catalog.i18nc("@action:button","Stop Heating") : catalog.i18nc("@action:button","Start Heating")
|
||||
onClicked:
|
||||
{
|
||||
manager.heatupBed()
|
||||
if (checkupMachineAction.heatupBedStarted)
|
||||
{
|
||||
manager.cooldownBed()
|
||||
checkupMachineAction.heatupBedStarted = false
|
||||
} else
|
||||
{
|
||||
manager.heatupBed()
|
||||
checkupMachineAction.heatupBedStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
100
plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py
Normal file
100
plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py
Normal file
@ -0,0 +1,100 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import UM.VersionUpgrade #To indicate that a file is of incorrect format.
|
||||
|
||||
import configparser #To read config files.
|
||||
import io #To write config files to strings as if they were files.
|
||||
|
||||
## Creates a new machine instance instance by parsing a serialised machine
|
||||
# instance in version 1 of the file format.
|
||||
#
|
||||
# \param serialised The serialised form of a machine instance in version 1.
|
||||
# \param filename The supposed file name of this machine instance, without
|
||||
# extension.
|
||||
# \return A machine instance instance, or None if the file format is
|
||||
# incorrect.
|
||||
def importFrom(serialised, filename):
|
||||
try:
|
||||
return MachineInstance(serialised, filename)
|
||||
except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
|
||||
return None
|
||||
|
||||
## A representation of a machine instance used as intermediary form for
|
||||
# conversion from one format to the other.
|
||||
class MachineInstance:
|
||||
## Reads version 1 of the file format, storing it in memory.
|
||||
#
|
||||
# \param serialised A string with the contents of a machine instance file,
|
||||
# without extension.
|
||||
# \param filename The supposed file name of this machine instance.
|
||||
def __init__(self, serialised, filename):
|
||||
self._filename = filename
|
||||
|
||||
config = configparser.ConfigParser(interpolation = None)
|
||||
config.read_string(serialised) # Read the input string as config file.
|
||||
|
||||
# Checking file correctness.
|
||||
if not config.has_section("general"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"general\" section.")
|
||||
if not config.has_option("general", "version"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"version\" in \"general\" section.")
|
||||
if not config.has_option("general", "name"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"name\" in \"general\" section.")
|
||||
if not config.has_option("general", "type"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"type\" in \"general\" section.")
|
||||
if int(config.get("general", "version")) != 1: # Explicitly hard-code version 1, since if this number changes the programmer MUST change this entire function.
|
||||
raise UM.VersionUpgrade.InvalidVersionException("The version of this machine instance is wrong. It must be 1.")
|
||||
|
||||
self._type_name = config.get("general", "type")
|
||||
self._variant_name = config.get("general", "variant", fallback = None)
|
||||
self._name = config.get("general", "name")
|
||||
self._key = config.get("general", "key", fallback = None)
|
||||
self._active_profile_name = config.get("general", "active_profile", fallback = None)
|
||||
self._active_material_name = config.get("general", "material", fallback = None)
|
||||
|
||||
self._machine_setting_overrides = {}
|
||||
for key, value in config["machine_settings"].items():
|
||||
self._machine_setting_overrides[key] = value
|
||||
|
||||
## Serialises this machine instance as file format version 2.
|
||||
#
|
||||
# This is where the actual translation happens in this case.
|
||||
#
|
||||
# \return A tuple containing the new filename and a serialised form of
|
||||
# this machine instance, serialised in version 2 of the file format.
|
||||
def export(self):
|
||||
config = configparser.ConfigParser(interpolation = None) # Build a config file in the form of version 2.
|
||||
|
||||
config.add_section("general")
|
||||
config.set("general", "name", self._name)
|
||||
config.set("general", "id", self._name)
|
||||
config.set("general", "type", self._type_name)
|
||||
config.set("general", "version", "2") # Hard-code version 2, since if this number changes the programmer MUST change this entire function.
|
||||
|
||||
import VersionUpgrade21to22 # Import here to prevent circular dependencies.
|
||||
type_name = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translatePrinter(self._type_name)
|
||||
active_profile = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateProfile(self._active_profile_name)
|
||||
active_material = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateProfile(self._active_material_name)
|
||||
variant = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._variant_name, type_name)
|
||||
|
||||
containers = [
|
||||
self._name + "_current_settings",
|
||||
active_profile,
|
||||
active_material,
|
||||
variant,
|
||||
type_name
|
||||
]
|
||||
config.set("general", "containers", ",".join(containers))
|
||||
|
||||
config.add_section("metadata")
|
||||
config.set("metadata", "type", "machine")
|
||||
|
||||
VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._machine_setting_overrides)
|
||||
config.add_section("values")
|
||||
for key, value in self._machine_setting_overrides.items():
|
||||
config.set("values", key, str(value))
|
||||
|
||||
output = io.StringIO()
|
||||
config.write(output)
|
||||
return self._filename, output.getvalue()
|
80
plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py
Normal file
80
plugins/VersionUpgrade/VersionUpgrade21to22/Preferences.py
Normal file
@ -0,0 +1,80 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import configparser #To read config files.
|
||||
import io #To output config files to string.
|
||||
|
||||
import UM.VersionUpgrade #To indicate that a file is of the wrong format.
|
||||
|
||||
## Creates a new preferences instance by parsing a serialised preferences file
|
||||
# in version 1 of the file format.
|
||||
#
|
||||
# \param serialised The serialised form of a preferences file in version 1.
|
||||
# \param filename The supposed filename of the preferences file, without
|
||||
# extension.
|
||||
# \return A representation of those preferences, or None if the file format is
|
||||
# incorrect.
|
||||
def importFrom(serialised, filename):
|
||||
try:
|
||||
return Preferences(serialised, filename)
|
||||
except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
|
||||
return None
|
||||
|
||||
## A representation of preferences files as intermediary form for conversion
|
||||
# from one format to the other.
|
||||
class Preferences:
|
||||
## Reads version 2 of the preferences file format, storing it in memory.
|
||||
#
|
||||
# \param serialised A serialised version 2 preferences file.
|
||||
# \param filename The supposed filename of the preferences file, without
|
||||
# extension.
|
||||
def __init__(self, serialised, filename):
|
||||
self._filename = filename
|
||||
|
||||
self._config = configparser.ConfigParser(interpolation = None)
|
||||
self._config.read_string(serialised)
|
||||
|
||||
#Checking file correctness.
|
||||
if not self._config.has_section("general"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"general\" section.")
|
||||
if not self._config.has_option("general", "version"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"version\" in \"general\" section.")
|
||||
if int(self._config.get("general", "version")) != 2: # Explicitly hard-code version 2, since if this number changes the programmer MUST change this entire function.
|
||||
raise UM.VersionUpgrade.InvalidVersionException("The version of this preferences file is wrong. It must be 2.")
|
||||
if self._config.has_option("general", "name"): #This is probably a machine instance.
|
||||
raise UM.VersionUpgrade.FormatException("There is a \"name\" field in this configuration file. I suspect it is not a preferences file.")
|
||||
|
||||
## Serialises these preferences as a preferences file of version 3.
|
||||
#
|
||||
# This is where the actual translation happens.
|
||||
#
|
||||
# \return A tuple containing the new filename and a serialised version of
|
||||
# a preferences file in version 3.
|
||||
def export(self):
|
||||
#Reset the cura/categories_expanded property since it works differently now.
|
||||
if self._config.has_section("cura") and self._config.has_option("cura", "categories_expanded"):
|
||||
self._config.remove_option("cura", "categories_expanded")
|
||||
|
||||
#Translate the setting names in the visible settings.
|
||||
if self._config.has_section("machines") and self._config.has_option("machines", "setting_visibility"):
|
||||
visible_settings = self._config.get("machines", "setting_visibility")
|
||||
visible_settings = visible_settings.split(",")
|
||||
import VersionUpgrade21to22 #Import here to prevent a circular dependency.
|
||||
visible_settings = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting_name)
|
||||
for setting_name in visible_settings]
|
||||
visible_settings = ",".join(visible_settings)
|
||||
self._config.set("machines", "setting_visibility", value = visible_settings)
|
||||
|
||||
#Translate the active_instance key.
|
||||
if self._config.has_section("machines") and self._config.has_option("machines", "active_instance"):
|
||||
active_machine = self._config.get("machines", "active_instance")
|
||||
self._config.remove_option("machines", "active_instance")
|
||||
self._config.set("cura", "active_machine", active_machine)
|
||||
|
||||
#Update the version number itself.
|
||||
self._config.set("general", "version", value = "3")
|
||||
|
||||
#Output the result as a string.
|
||||
output = io.StringIO()
|
||||
self._config.write(output)
|
||||
return self._filename, output.getvalue()
|
133
plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py
Normal file
133
plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py
Normal file
@ -0,0 +1,133 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import configparser #To read config files.
|
||||
import io #To write config files to strings as if they were files.
|
||||
|
||||
import UM.VersionUpgrade
|
||||
|
||||
## Creates a new profile instance by parsing a serialised profile in version 1
|
||||
# of the file format.
|
||||
#
|
||||
# \param serialised The serialised form of a profile in version 1.
|
||||
# \param filename The supposed filename of the profile, without extension.
|
||||
# \return A profile instance, or None if the file format is incorrect.
|
||||
def importFrom(serialised, filename):
|
||||
try:
|
||||
return Profile(serialised, filename)
|
||||
except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
|
||||
return None
|
||||
|
||||
## A representation of a profile used as intermediary form for conversion from
|
||||
# one format to the other.
|
||||
class Profile:
|
||||
## Reads version 1 of the file format, storing it in memory.
|
||||
#
|
||||
# \param serialised A string with the contents of a profile.
|
||||
# \param filename The supposed filename of the profile, without extension.
|
||||
def __init__(self, serialised, filename):
|
||||
self._filename = filename
|
||||
|
||||
parser = configparser.ConfigParser(interpolation = None)
|
||||
parser.read_string(serialised)
|
||||
|
||||
# Check correctness.
|
||||
if not parser.has_section("general"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"general\" section.")
|
||||
if not parser.has_option("general", "version"):
|
||||
raise UM.VersionUpgrade.FormatException("No \"version\" in the \"general\" section.")
|
||||
if int(parser.get("general", "version")) != 1: # Hard-coded profile version here. If this number changes the entire function needs to change.
|
||||
raise UM.VersionUpgrade.InvalidVersionException("The version of this profile is wrong. It must be 1.")
|
||||
|
||||
# Parse the general section.
|
||||
self._name = parser.get("general", "name")
|
||||
self._type = parser.get("general", "type", fallback = None)
|
||||
if "weight" in parser["general"]:
|
||||
self._weight = int(parser.get("general", "weight"))
|
||||
else:
|
||||
self._weight = None
|
||||
self._machine_type_id = parser.get("general", "machine_type", fallback = None)
|
||||
self._machine_variant_name = parser.get("general", "machine_variant", fallback = None)
|
||||
self._machine_instance_name = parser.get("general", "machine_instance", fallback = None)
|
||||
if "material" in parser["general"]:
|
||||
self._material_name = parser.get("general", "material")
|
||||
elif self._type == "material":
|
||||
self._material_name = parser.get("general", "name", fallback = None)
|
||||
else:
|
||||
self._material_name = None
|
||||
|
||||
# Parse the settings.
|
||||
self._settings = {}
|
||||
if parser.has_section("settings"):
|
||||
for key, value in parser["settings"].items():
|
||||
self._settings[key] = value
|
||||
|
||||
# Parse the defaults and the disabled defaults.
|
||||
self._changed_settings_defaults = {}
|
||||
if parser.has_section("defaults"):
|
||||
for key, value in parser["defaults"].items():
|
||||
self._changed_settings_defaults[key] = value
|
||||
self._disabled_settings_defaults = []
|
||||
if parser.has_section("disabled_defaults"):
|
||||
disabled_defaults_string = parser.get("disabled_defaults", "values")
|
||||
self._disabled_settings_defaults = [item for item in disabled_defaults_string.split(",") if item != ""] # Split by comma.
|
||||
|
||||
## Serialises this profile as file format version 2.
|
||||
#
|
||||
# \return A tuple containing the new filename and a serialised form of
|
||||
# this profile, serialised in version 2 of the file format.
|
||||
def export(self):
|
||||
import VersionUpgrade21to22 # Import here to prevent circular dependencies.
|
||||
|
||||
if self._name == "Current settings":
|
||||
self._filename += "_current_settings" #This resolves a duplicate ID arising from how Cura 2.1 stores its current settings.
|
||||
|
||||
config = configparser.ConfigParser(interpolation = None)
|
||||
|
||||
config.add_section("general")
|
||||
config.set("general", "version", "2") #Hard-coded profile version 2.
|
||||
config.set("general", "name", self._name)
|
||||
if self._machine_type_id:
|
||||
translated_machine = VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translatePrinter(self._machine_type_id)
|
||||
config.set("general", "definition", translated_machine)
|
||||
else:
|
||||
config.set("general", "definition", "fdmprinter")
|
||||
|
||||
config.add_section("metadata")
|
||||
if self._type:
|
||||
config.set("metadata", "type", self._type)
|
||||
else:
|
||||
config.set("metadata", "type", "quality")
|
||||
if self._weight:
|
||||
config.set("metadata", "weight", self._weight)
|
||||
if self._machine_variant_name:
|
||||
if self._machine_type_id:
|
||||
config.set("metadata", "variant", VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateVariant(self._machine_variant_name, self._machine_type_id))
|
||||
else:
|
||||
config.set("metadata", "variant", self._machine_variant_name)
|
||||
if self._material_name and self._type != "material":
|
||||
config.set("metadata", "material", self._material_name)
|
||||
|
||||
if self._settings:
|
||||
VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._settings)
|
||||
config.add_section("values")
|
||||
for key, value in self._settings.items():
|
||||
config.set("values", key, str(value))
|
||||
|
||||
if self._changed_settings_defaults:
|
||||
VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettings(self._changed_settings_defaults)
|
||||
config.add_section("defaults")
|
||||
for key, value in self._changed_settings_defaults.items():
|
||||
config.set("defaults", key, str(value))
|
||||
|
||||
if self._disabled_settings_defaults:
|
||||
disabled_settings_defaults = [VersionUpgrade21to22.VersionUpgrade21to22.VersionUpgrade21to22.translateSettingName(setting)
|
||||
for setting in self._disabled_settings_defaults]
|
||||
config.add_section("disabled_defaults")
|
||||
disabled_defaults_string = str(disabled_settings_defaults[0]) #Must be at least 1 item, otherwise we wouldn't enter this if statement.
|
||||
for item in disabled_settings_defaults[1:]:
|
||||
disabled_defaults_string += "," + str(item)
|
||||
|
||||
output = io.StringIO()
|
||||
config.write(output)
|
||||
return self._filename, output.getvalue()
|
@ -0,0 +1,181 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import configparser #To get version numbers from config files.
|
||||
|
||||
from UM.VersionUpgrade import VersionUpgrade # Superclass of the plugin.
|
||||
|
||||
from . import MachineInstance # To upgrade machine instances.
|
||||
from . import Preferences #To upgrade preferences.
|
||||
from . import Profile # To upgrade profiles.
|
||||
|
||||
## How to translate printer names from the old version to the new.
|
||||
_printer_translations = {
|
||||
"ultimaker2plus": "ultimaker2_plus"
|
||||
}
|
||||
|
||||
## How to translate profile names from the old version to the new.
|
||||
_profile_translations = {
|
||||
"PLA": "generic_pla",
|
||||
"ABS": "generic_abs",
|
||||
"CPE": "generic_cpe"
|
||||
}
|
||||
|
||||
## How to translate setting names from the old version to the new.
|
||||
_setting_name_translations = {
|
||||
"remove_overlapping_walls_0_enabled": "travel_compensate_overlapping_walls_0_enabled",
|
||||
"remove_overlapping_walls_enabled": "travel_compensate_overlapping_walls_enabled",
|
||||
"remove_overlapping_walls_x_enabled": "travel_compensate_overlapping_walls_x_enabled",
|
||||
"retraction_hop": "retraction_hop_enabled",
|
||||
"speed_support_lines": "speed_support_infill"
|
||||
}
|
||||
|
||||
## How to translate variants of specific machines from the old version to the
|
||||
# new.
|
||||
_variant_translations = {
|
||||
"ultimaker2_plus": {
|
||||
"0.25 mm": "ultimaker2_plus_0.25",
|
||||
"0.4 mm": "ultimaker2_plus_0.4",
|
||||
"0.6 mm": "ultimaker2_plus_0.6",
|
||||
"0.8 mm": "ultimaker2_plus_0.8"
|
||||
},
|
||||
"ultimaker2_extended_plus": {
|
||||
"0.25 mm": "ultimaker2_extended_plus_0.25",
|
||||
"0.4 mm": "ultimaker2_extended_plus_0.4",
|
||||
"0.6 mm": "ultimaker2_extended_plus_0.6",
|
||||
"0.8 mm": "ultimaker2_extended_plus_0.8"
|
||||
}
|
||||
}
|
||||
|
||||
## Converts configuration from Cura 2.1's file formats to Cura 2.2's.
|
||||
#
|
||||
# It converts the machine instances and profiles.
|
||||
class VersionUpgrade21to22(VersionUpgrade):
|
||||
## Gets the version number from a config file.
|
||||
#
|
||||
# In all config files that concern this version upgrade, the version
|
||||
# number is stored in general/version, so get the data from that key.
|
||||
#
|
||||
# \param serialised The contents of a config file.
|
||||
# \return \type{int} The version number of that config file.
|
||||
def getCfgVersion(self, serialised):
|
||||
parser = configparser.ConfigParser(interpolation = None)
|
||||
parser.read_string(serialised)
|
||||
return int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
|
||||
|
||||
## Converts machine instances from format version 1 to version 2.
|
||||
#
|
||||
# \param serialised The serialised machine instance in version 1.
|
||||
# \param filename The supposed file name of the machine instance, without
|
||||
# extension.
|
||||
# \return A tuple containing the new filename and the serialised machine
|
||||
# instance in version 2, or None if the input was not of the correct
|
||||
# format.
|
||||
def upgradeMachineInstance(self, serialised, filename):
|
||||
machine_instance = MachineInstance.importFrom(serialised, filename)
|
||||
if not machine_instance: #Invalid file format.
|
||||
return filename, None
|
||||
return machine_instance.export()
|
||||
|
||||
## Converts preferences from format version 2 to version 3.
|
||||
#
|
||||
# \param serialised The serialised preferences file in version 2.
|
||||
# \param filename THe supposed file name of the preferences file, without
|
||||
# extension.
|
||||
# \return A tuple containing the new filename and the serialised
|
||||
# preferences in version 3, or None if the input was not of the correct
|
||||
# format.
|
||||
def upgradePreferences(self, serialised, filename):
|
||||
preferences = Preferences.importFrom(serialised, filename)
|
||||
if not preferences: #Invalid file format.
|
||||
return filename, None
|
||||
return preferences.export()
|
||||
|
||||
## Converts profiles from format version 1 to version 2.
|
||||
#
|
||||
# \param serialised The serialised profile in version 1.
|
||||
# \param filename The supposed file name of the profile, without
|
||||
# extension.
|
||||
# \return A tuple containing the new filename and the serialised profile
|
||||
# in version 2, or None if the input was not of the correct format.
|
||||
def upgradeProfile(self, serialised, filename):
|
||||
profile = Profile.importFrom(serialised, filename)
|
||||
if not profile: # Invalid file format.
|
||||
return filename, None
|
||||
return profile.export()
|
||||
|
||||
## Translates a printer name that might have changed since the last
|
||||
# version.
|
||||
#
|
||||
# \param printer A printer name in Cura 2.1.
|
||||
# \return The name of the corresponding printer in Cura 2.2.
|
||||
@staticmethod
|
||||
def translatePrinter(printer):
|
||||
if printer in _printer_translations:
|
||||
return _printer_translations[printer]
|
||||
return printer #Doesn't need to be translated.
|
||||
|
||||
## Translates a built-in profile name that might have changed since the
|
||||
# last version.
|
||||
#
|
||||
# \param profile A profile name in the old version.
|
||||
# \return The corresponding profile name in the new version.
|
||||
@staticmethod
|
||||
def translateProfile(profile):
|
||||
if profile in _profile_translations:
|
||||
return _profile_translations[profile]
|
||||
return profile #Doesn't need to be translated.
|
||||
|
||||
## Updates settings for the change from Cura 2.1 to 2.2.
|
||||
#
|
||||
# The keys and values of settings are changed to what they should be in
|
||||
# the new version. Each setting is changed in-place in the provided
|
||||
# dictionary. This changes the input parameter.
|
||||
#
|
||||
# \param settings A dictionary of settings (as key-value pairs) to update.
|
||||
# \return The same dictionary.
|
||||
@staticmethod
|
||||
def translateSettings(settings):
|
||||
for key, value in settings.items():
|
||||
if key == "fill_perimeter_gaps": #Setting is removed.
|
||||
del settings[key]
|
||||
elif key == "remove_overlapping_walls_0_enabled": #Setting is functionally replaced.
|
||||
del settings[key]
|
||||
settings["travel_compensate_overlapping_walls_0_enabled"] = value
|
||||
elif key == "remove_overlapping_walls_enabled": #Setting is functionally replaced.
|
||||
del settings[key]
|
||||
settings["travel_compensate_overlapping_walls_enabled"] = value
|
||||
elif key == "remove_overlapping_walls_x_enabled": #Setting is functionally replaced.
|
||||
del settings[key]
|
||||
settings["travel_compensate_overlapping_walls_x_enabled"] = value
|
||||
elif key == "retraction_combing": #Combing was made into an enum instead of a boolean.
|
||||
settings[key] = "off" if (value == "False") else "all"
|
||||
elif key == "retraction_hop": #Setting key was changed.
|
||||
del settings[key]
|
||||
settings["retraction_hop_enabled"] = value
|
||||
elif key == "speed_support_lines": #Setting key was changed.
|
||||
del settings[key]
|
||||
settings["speed_support_infill"] = value
|
||||
return settings
|
||||
|
||||
## Translates a setting name for the change from Cura 2.1 to 2.2.
|
||||
#
|
||||
# \param setting The name of a setting in Cura 2.1.
|
||||
# \return The name of the corresponding setting in Cura 2.2.
|
||||
@staticmethod
|
||||
def translateSettingName(setting):
|
||||
if setting in _setting_name_translations:
|
||||
return _setting_name_translations[setting]
|
||||
return setting #Doesn't need to be translated.
|
||||
|
||||
## Translates a variant name for the change from Cura 2.1 to 2.2
|
||||
#
|
||||
# \param variant The name of a variant in Cura 2.1.
|
||||
# \param machine The name of the machine this variant is part of in Cura
|
||||
# 2.2's naming.
|
||||
# \return The name of the corresponding variant in Cura 2.2.
|
||||
@staticmethod
|
||||
def translateVariant(variant, machine):
|
||||
if machine in _variant_translations and variant in _variant_translations[machine]:
|
||||
return _variant_translations[machine][variant]
|
||||
return variant
|
43
plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py
Normal file
43
plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from . import VersionUpgrade21to22
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
upgrade = VersionUpgrade21to22.VersionUpgrade21to22()
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
"plugin": {
|
||||
"name": catalog.i18nc("@label", "Version Upgrade 2.1 to 2.2"),
|
||||
"author": "Ultimaker",
|
||||
"version": "1.0",
|
||||
"description": catalog.i18nc("@info:whatsthis", "Upgrades configurations from Cura 2.1 to Cura 2.2."),
|
||||
"api": 3
|
||||
},
|
||||
"version_upgrade": {
|
||||
# From To Upgrade function
|
||||
("profile", 1): ("quality", 2, upgrade.upgradeProfile),
|
||||
("machine_instance", 1): ("machine_stack", 2, upgrade.upgradeMachineInstance),
|
||||
("preferences", 2): ("preferences", 3, upgrade.upgradePreferences)
|
||||
},
|
||||
"sources": {
|
||||
"profile": {
|
||||
"get_version": upgrade.getCfgVersion,
|
||||
"location": {"./profiles", "./instance_profiles"}
|
||||
},
|
||||
"machine_instance": {
|
||||
"get_version": upgrade.getCfgVersion,
|
||||
"location": {"./machine_instances"}
|
||||
},
|
||||
"preferences": {
|
||||
"get_version": upgrade.getCfgVersion,
|
||||
"location": {"."}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def register(app):
|
||||
return { "version_upgrade": upgrade }
|
@ -315,6 +315,51 @@
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"extruder_prime_pos_x":
|
||||
{
|
||||
"label": "Extruder Prime X Position",
|
||||
"description": "The x coordinate of the position where the nozzle primes at the start of printing.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 0,
|
||||
"minimum_value_warning": "-1000",
|
||||
"maximum_value_warning": "1000",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"extruder_prime_pos_y":
|
||||
{
|
||||
"label": "Extruder Prime Y Position",
|
||||
"description": "The y coordinate of the position where the nozzle primes at the start of printing.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 0,
|
||||
"minimum_value_warning": "-1000",
|
||||
"maximum_value_warning": "1000",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"extruder_prime_pos_z":
|
||||
{
|
||||
"label": "Extruder Prime Z Position",
|
||||
"description": "The z coordinate of the position where the nozzle primes at the start of printing.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"default_value": 0,
|
||||
"minimum_value_warning": "-1000",
|
||||
"maximum_value_warning": "1000",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"extruder_prime_pos_abs":
|
||||
{
|
||||
"label": "Absolute Extruder Prime Position",
|
||||
"description": "Make the extruder prime position absolute rather than relative to the last-known location of the head.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user