mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-12 19:49:00 +08:00
Merge branch 'master' of github.com:Ultimaker/Cura into network_rewrite
This commit is contained in:
commit
c6458358ba
22
.github/ISSUE_TEMPLATE.md
vendored
22
.github/ISSUE_TEMPLATE.md
vendored
@ -1,32 +1,36 @@
|
|||||||
<!--
|
<!--
|
||||||
The following template is useful for filing new issues. Processing an issue will go much faster when this is filled out.
|
The following template is useful for filing new issues. Processing an issue will go much faster when this is filled out.
|
||||||
Before filing, please check if the issue already exists (either open or closed).
|
Before filing, please check if the issue already exists (either open or closed).
|
||||||
|
|
||||||
|
It is also helpful to attach a project (.3MF) file and Cura log file so we can debug issues quicker.
|
||||||
|
Information about how to find the log file can be found at https://github.com/Ultimaker/Cura/wiki/Cura-Preferences-and-Settings-Locations.
|
||||||
|
|
||||||
Thank you for using Cura!
|
Thank you for using Cura!
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Application Version:
|
**Application Version**
|
||||||
<!-- The version of the application this issue occurs with -->
|
<!-- The version of the application this issue occurs with -->
|
||||||
|
|
||||||
Platform:
|
**Platform**
|
||||||
<!-- Information about the platform the issue occurs on -->
|
<!-- Information about the platform the issue occurs on -->
|
||||||
|
|
||||||
Qt:
|
**Qt**
|
||||||
<!-- The version of Qt used (not necessary if you're using the version from Ultimaker's website) -->
|
<!-- The version of Qt used (not necessary if you're using the version from Ultimaker's website) -->
|
||||||
|
|
||||||
PyQt:
|
**PyQt**
|
||||||
<!-- The version of PyQt used (not necessary if you're using the version from Ultimaker's website) -->
|
<!-- The version of PyQt used (not necessary if you're using the version from Ultimaker's website) -->
|
||||||
|
|
||||||
Display Driver:
|
**Display Driver**
|
||||||
<!-- Video driver name and version -->
|
<!-- Video driver name and version -->
|
||||||
|
|
||||||
Steps to Reproduce:
|
**Steps to Reproduce**
|
||||||
<!-- Add the steps needed that lead up to the issue (replace this text) -->
|
<!-- Add the steps needed that lead up to the issue (replace this text) -->
|
||||||
|
|
||||||
Actual Results:
|
**Actual Results**
|
||||||
<!-- What happens after the above steps have been followed (replace this text) -->
|
<!-- What happens after the above steps have been followed (replace this text) -->
|
||||||
|
|
||||||
Expected results:
|
**Expected results**
|
||||||
<!-- What should happen after the above steps have been followed (replace this text) -->
|
<!-- What should happen after the above steps have been followed (replace this text) -->
|
||||||
|
|
||||||
Additional Information:
|
**Additional Information**
|
||||||
<!-- Extra information relevant to the issue, like screenshots (replace this text) -->
|
<!-- Extra information relevant to the issue, like screenshots (replace this text) -->
|
||||||
|
26
.gitignore
vendored
26
.gitignore
vendored
@ -33,21 +33,23 @@ cura.desktop
|
|||||||
.settings
|
.settings
|
||||||
|
|
||||||
#Externally located plug-ins.
|
#Externally located plug-ins.
|
||||||
plugins/CuraSolidWorksPlugin
|
|
||||||
plugins/Doodle3D-cura-plugin
|
|
||||||
plugins/GodMode
|
|
||||||
plugins/PostProcessingPlugin
|
|
||||||
plugins/X3GWriter
|
|
||||||
plugins/FlatProfileExporter
|
|
||||||
plugins/ProfileFlattener
|
|
||||||
plugins/cura-god-mode-plugin
|
|
||||||
plugins/cura-big-flame-graph
|
plugins/cura-big-flame-graph
|
||||||
|
plugins/cura-god-mode-plugin
|
||||||
plugins/cura-siemensnx-plugin
|
plugins/cura-siemensnx-plugin
|
||||||
plugins/CuraVariSlicePlugin
|
plugins/CuraBlenderPlugin
|
||||||
plugins/CuraLiveScriptingPlugin
|
|
||||||
plugins/CuraPrintProfileCreator
|
|
||||||
plugins/OctoPrintPlugin
|
|
||||||
plugins/CuraCloudPlugin
|
plugins/CuraCloudPlugin
|
||||||
|
plugins/CuraLiveScriptingPlugin
|
||||||
|
plugins/CuraOpenSCADPlugin
|
||||||
|
plugins/CuraPrintProfileCreator
|
||||||
|
plugins/CuraSolidWorksPlugin
|
||||||
|
plugins/CuraVariSlicePlugin
|
||||||
|
plugins/Doodle3D-cura-plugin
|
||||||
|
plugins/FlatProfileExporter
|
||||||
|
plugins/GodMode
|
||||||
|
plugins/OctoPrintPlugin
|
||||||
|
plugins/PostProcessingPlugin
|
||||||
|
plugins/ProfileFlattener
|
||||||
|
plugins/X3GWriter
|
||||||
|
|
||||||
#Build stuff
|
#Build stuff
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
@ -218,25 +218,6 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
if type(profile_or_list) is not list:
|
if type(profile_or_list) is not list:
|
||||||
profile_or_list = [profile_or_list]
|
profile_or_list = [profile_or_list]
|
||||||
|
|
||||||
if len(profile_or_list) == 1:
|
|
||||||
# If there is only 1 stack file it means we're loading a legacy (pre-3.1) .curaprofile.
|
|
||||||
# In that case we find the per-extruder settings and put those in a new quality_changes container
|
|
||||||
# so that it is compatible with the new stack setup.
|
|
||||||
profile = profile_or_list[0]
|
|
||||||
extruder_stack_quality_changes_container = ContainerManager.getInstance().duplicateContainerInstance(profile)
|
|
||||||
extruder_stack_quality_changes_container.addMetaDataEntry("extruder", "fdmextruder")
|
|
||||||
|
|
||||||
for quality_changes_setting_key in extruder_stack_quality_changes_container.getAllKeys():
|
|
||||||
settable_per_extruder = extruder_stack_quality_changes_container.getProperty(quality_changes_setting_key, "settable_per_extruder")
|
|
||||||
if settable_per_extruder:
|
|
||||||
profile.removeInstance(quality_changes_setting_key, postpone_emit = True)
|
|
||||||
else:
|
|
||||||
extruder_stack_quality_changes_container.removeInstance(quality_changes_setting_key, postpone_emit = True)
|
|
||||||
|
|
||||||
# We add the new container to the profile list so things like extruder positions are taken care of
|
|
||||||
# in the next code segment.
|
|
||||||
profile_or_list.append(extruder_stack_quality_changes_container)
|
|
||||||
|
|
||||||
# Import all profiles
|
# Import all profiles
|
||||||
for profile_index, profile in enumerate(profile_or_list):
|
for profile_index, profile in enumerate(profile_or_list):
|
||||||
if profile_index == 0:
|
if profile_index == 0:
|
||||||
@ -252,6 +233,9 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
profile.setMetaDataEntry("extruder", extruder_id)
|
profile.setMetaDataEntry("extruder", extruder_id)
|
||||||
profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
|
profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
|
||||||
|
|
||||||
|
else: #More extruders in the imported file than in the machine.
|
||||||
|
continue #Delete the additional profiles.
|
||||||
|
|
||||||
result = self._configureProfile(profile, profile_id, new_name)
|
result = self._configureProfile(profile, profile_id, new_name)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return {"status": "error", "message": catalog.i18nc(
|
return {"status": "error", "message": catalog.i18nc(
|
||||||
@ -305,7 +289,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
quality_type_criteria["definition"] = profile.getDefinition().getId()
|
quality_type_criteria["definition"] = profile.getDefinition().getId()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
profile.setDefinition(fdmprinter)
|
profile.setDefinition("fdmprinter")
|
||||||
quality_type_criteria["definition"] = "fdmprinter"
|
quality_type_criteria["definition"] = "fdmprinter"
|
||||||
|
|
||||||
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||||
@ -422,6 +406,10 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
if not isinstance(container, ContainerStack) or container.getMetaDataEntry("type") != "machine":
|
if not isinstance(container, ContainerStack) or container.getMetaDataEntry("type") != "machine":
|
||||||
return
|
return
|
||||||
|
|
||||||
|
machine_extruder_trains = container.getMetaDataEntry("machine_extruder_trains")
|
||||||
|
if machine_extruder_trains is not None and machine_extruder_trains != {"0": "fdmextruder"}:
|
||||||
|
return
|
||||||
|
|
||||||
extruder_stacks = self.findContainerStacks(type = "extruder_train", machine = container.getId())
|
extruder_stacks = self.findContainerStacks(type = "extruder_train", machine = container.getId())
|
||||||
if not extruder_stacks:
|
if not extruder_stacks:
|
||||||
self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder")
|
self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder")
|
||||||
|
@ -32,14 +32,16 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._stack = PerObjectContainerStack(stack_id = id(self))
|
self._stack = PerObjectContainerStack(stack_id = "per_object_stack_" + str(id(self)))
|
||||||
self._stack.setDirty(False) # This stack does not need to be saved.
|
self._stack.setDirty(False) # This stack does not need to be saved.
|
||||||
self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))
|
self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))
|
||||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||||
|
|
||||||
|
self._is_non_printing_mesh = False
|
||||||
|
|
||||||
self._stack.propertyChanged.connect(self._onSettingChanged)
|
self._stack.propertyChanged.connect(self._onSettingChanged)
|
||||||
|
|
||||||
ContainerRegistry.getInstance().addContainer(self._stack)
|
Application.getInstance().getContainerRegistry().addContainer(self._stack)
|
||||||
|
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack)
|
Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack)
|
||||||
self.activeExtruderChanged.connect(self._updateNextStack)
|
self.activeExtruderChanged.connect(self._updateNextStack)
|
||||||
@ -57,6 +59,10 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
# Properly set the right extruder on the copy
|
# Properly set the right extruder on the copy
|
||||||
deep_copy.setActiveExtruder(self._extruder_stack)
|
deep_copy.setActiveExtruder(self._extruder_stack)
|
||||||
|
|
||||||
|
# use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh"
|
||||||
|
# has not been updated yet.
|
||||||
|
deep_copy._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
|
||||||
|
|
||||||
return deep_copy
|
return deep_copy
|
||||||
|
|
||||||
## Gets the currently active extruder to print this object with.
|
## Gets the currently active extruder to print this object with.
|
||||||
@ -80,14 +86,17 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
container_stack = containers[0]
|
container_stack = containers[0]
|
||||||
return container_stack.getMetaDataEntry("position", default=None)
|
return container_stack.getMetaDataEntry("position", default=None)
|
||||||
|
|
||||||
|
def isNonPrintingMesh(self):
|
||||||
|
return self._is_non_printing_mesh
|
||||||
|
|
||||||
def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function
|
def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function
|
||||||
# Trigger slice/need slicing if the value has changed.
|
# Trigger slice/need slicing if the value has changed.
|
||||||
if property_name == "value":
|
if property_name == "value":
|
||||||
|
self._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
|
||||||
|
|
||||||
Application.getInstance().getBackend().needsSlicing()
|
Application.getInstance().getBackend().needsSlicing()
|
||||||
Application.getInstance().getBackend().tickle()
|
Application.getInstance().getBackend().tickle()
|
||||||
|
|
||||||
self._node._non_printing_mesh = any(self._stack.getProperty(setting, "value") for setting in self._non_printing_mesh_settings)
|
|
||||||
|
|
||||||
## Makes sure that the stack upon which the container stack is placed is
|
## Makes sure that the stack upon which the container stack is placed is
|
||||||
# kept up to date.
|
# kept up to date.
|
||||||
def _updateNextStack(self):
|
def _updateNextStack(self):
|
||||||
|
@ -461,7 +461,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
global_stack_id_new = self.getNewId(global_stack_id_original)
|
global_stack_id_new = self.getNewId(global_stack_id_original)
|
||||||
global_stack_need_rename = True
|
global_stack_need_rename = True
|
||||||
|
|
||||||
global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original)
|
if self._container_registry.findContainerStacksMetadata(name = global_stack_id_original):
|
||||||
|
global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original)
|
||||||
|
|
||||||
for each_extruder_stack_file in extruder_stack_files:
|
for each_extruder_stack_file in extruder_stack_files:
|
||||||
old_container_id = self._stripFileToId(each_extruder_stack_file)
|
old_container_id = self._stripFileToId(each_extruder_stack_file)
|
||||||
@ -583,7 +584,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
if machine_id:
|
if machine_id:
|
||||||
new_machine_id = self.getNewId(machine_id)
|
new_machine_id = self.getNewId(machine_id)
|
||||||
new_id = new_machine_id + "_current_settings"
|
new_id = new_machine_id + "_current_settings"
|
||||||
instance_container.setMetadataEntry("id", new_id)
|
instance_container.setMetaDataEntry("id", new_id)
|
||||||
instance_container.setName(new_id)
|
instance_container.setName(new_id)
|
||||||
instance_container.setMetaDataEntry("machine", new_machine_id)
|
instance_container.setMetaDataEntry("machine", new_machine_id)
|
||||||
containers_to_add.append(instance_container)
|
containers_to_add.append(instance_container)
|
||||||
@ -681,12 +682,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
file_name = global_stack_file)
|
file_name = global_stack_file)
|
||||||
|
|
||||||
# Ensure a unique ID and name
|
# Ensure a unique ID and name
|
||||||
stack._id = global_stack_id_new
|
stack.setMetaDataEntry("id", global_stack_id_new)
|
||||||
|
|
||||||
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
|
|
||||||
# bound machine also needs to change.
|
|
||||||
if stack.getMetaDataEntry("machine", None):
|
|
||||||
stack.setMetaDataEntry("machine", global_stack_id_new)
|
|
||||||
|
|
||||||
# Only machines need a new name, stacks may be non-unique
|
# Only machines need a new name, stacks may be non-unique
|
||||||
stack.setName(global_stack_name_new)
|
stack.setName(global_stack_name_new)
|
||||||
@ -740,7 +736,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
|
stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
|
||||||
|
|
||||||
# Ensure a unique ID and name
|
# Ensure a unique ID and name
|
||||||
stack._id = new_id
|
stack.setMetaDataEntry("id", new_id)
|
||||||
|
|
||||||
self._container_registry.addContainer(stack)
|
self._container_registry.addContainer(stack)
|
||||||
extruder_stacks_added.append(stack)
|
extruder_stacks_added.append(stack)
|
||||||
|
@ -19,6 +19,10 @@ from UM.Settings.SettingRelation import RelationType
|
|||||||
from cura.OneAtATimeIterator import OneAtATimeIterator
|
from cura.OneAtATimeIterator import OneAtATimeIterator
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
|
|
||||||
|
NON_PRINTING_MESH_SETTINGS = ["anti_overhang_mesh", "infill_mesh", "cutting_mesh"]
|
||||||
|
|
||||||
|
|
||||||
class StartJobResult(IntEnum):
|
class StartJobResult(IntEnum):
|
||||||
Finished = 1
|
Finished = 1
|
||||||
Error = 2
|
Error = 2
|
||||||
@ -133,11 +137,15 @@ class StartSliceJob(Job):
|
|||||||
temp_list = []
|
temp_list = []
|
||||||
has_printing_mesh = False
|
has_printing_mesh = False
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
if node.callDecoration("isSliceable") and type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||||
_non_printing_mesh = getattr(node, "_non_printing_mesh", False)
|
per_object_stack = node.callDecoration("getStack")
|
||||||
if not getattr(node, "_outside_buildarea", False) or _non_printing_mesh:
|
is_non_printing_mesh = False
|
||||||
|
if per_object_stack:
|
||||||
|
is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS)
|
||||||
|
|
||||||
|
if not getattr(node, "_outside_buildarea", False) or not is_non_printing_mesh:
|
||||||
temp_list.append(node)
|
temp_list.append(node)
|
||||||
if not _non_printing_mesh:
|
if not is_non_printing_mesh:
|
||||||
has_printing_mesh = True
|
has_printing_mesh = True
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import configparser # For reading the legacy profile INI files.
|
import configparser # For reading the legacy profile INI files.
|
||||||
@ -10,8 +10,10 @@ import os.path # For concatenating the path to the plugin and the relative path
|
|||||||
from UM.Application import Application # To get the machine manager to create the new profile in.
|
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.Logger import Logger # Logging errors.
|
||||||
from UM.PluginRegistry import PluginRegistry # For getting the path to this plugin's directory.
|
from UM.PluginRegistry import PluginRegistry # For getting the path to this plugin's directory.
|
||||||
|
from UM.Settings.ContainerRegistry import ContainerRegistry #To create unique profile IDs.
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make.
|
from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make.
|
||||||
from cura.ProfileReader import ProfileReader # The plug-in type to implement.
|
from cura.ProfileReader import ProfileReader # The plug-in type to implement.
|
||||||
|
from cura.Settings.ExtruderManager import ExtruderManager #To get the current extruder definition.
|
||||||
|
|
||||||
|
|
||||||
## A plugin that reads profile data from legacy Cura versions.
|
## A plugin that reads profile data from legacy Cura versions.
|
||||||
@ -77,7 +79,9 @@ class LegacyProfileReader(ProfileReader):
|
|||||||
raise Exception("Unable to import legacy profile. Multi extrusion is not supported")
|
raise Exception("Unable to import legacy profile. Multi extrusion is not supported")
|
||||||
|
|
||||||
Logger.log("i", "Importing legacy profile from file " + file_name + ".")
|
Logger.log("i", "Importing legacy profile from file " + file_name + ".")
|
||||||
profile = InstanceContainer("Imported Legacy Profile") # Create an empty profile.
|
container_registry = ContainerRegistry.getInstance()
|
||||||
|
profile_id = container_registry.uniqueName("Imported Legacy Profile")
|
||||||
|
profile = InstanceContainer(profile_id) # Create an empty profile.
|
||||||
|
|
||||||
parser = configparser.ConfigParser(interpolation = None)
|
parser = configparser.ConfigParser(interpolation = None)
|
||||||
try:
|
try:
|
||||||
@ -120,7 +124,7 @@ class LegacyProfileReader(ProfileReader):
|
|||||||
if "translation" not in dict_of_doom:
|
if "translation" not in dict_of_doom:
|
||||||
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
|
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
|
||||||
return None
|
return None
|
||||||
current_printer_definition = global_container_stack.getBottom()
|
current_printer_definition = global_container_stack.definition
|
||||||
profile.setDefinition(current_printer_definition.getId())
|
profile.setDefinition(current_printer_definition.getId())
|
||||||
for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations.
|
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]
|
old_setting_expression = dict_of_doom["translation"][new_setting]
|
||||||
@ -139,14 +143,13 @@ class LegacyProfileReader(ProfileReader):
|
|||||||
if len(profile.getAllKeys()) == 0:
|
if len(profile.getAllKeys()) == 0:
|
||||||
Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.")
|
Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.")
|
||||||
|
|
||||||
|
|
||||||
# We need to downgrade the container to version 1 (in Cura 2.1) so the upgrade system can correctly upgrade
|
|
||||||
# it to the latest version.
|
|
||||||
profile.addMetaDataEntry("type", "profile")
|
profile.addMetaDataEntry("type", "profile")
|
||||||
# don't know what quality_type it is based on, so use "normal" by default
|
# don't know what quality_type it is based on, so use "normal" by default
|
||||||
profile.addMetaDataEntry("quality_type", "normal")
|
profile.addMetaDataEntry("quality_type", "normal")
|
||||||
|
profile.setName(profile_id)
|
||||||
profile.setDirty(True)
|
profile.setDirty(True)
|
||||||
|
|
||||||
|
#Serialise and deserialise in order to perform the version upgrade.
|
||||||
parser = configparser.ConfigParser(interpolation=None)
|
parser = configparser.ConfigParser(interpolation=None)
|
||||||
data = profile.serialize()
|
data = profile.serialize()
|
||||||
parser.read_string(data)
|
parser.read_string(data)
|
||||||
@ -159,4 +162,20 @@ class LegacyProfileReader(ProfileReader):
|
|||||||
data = stream.getvalue()
|
data = stream.getvalue()
|
||||||
profile.deserialize(data)
|
profile.deserialize(data)
|
||||||
|
|
||||||
return profile
|
#We need to return one extruder stack and one global stack.
|
||||||
|
global_container_id = container_registry.uniqueName("Global Imported Legacy Profile")
|
||||||
|
global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile.
|
||||||
|
global_profile.setDirty(True)
|
||||||
|
|
||||||
|
#Only the extruder stack has an extruder metadata entry.
|
||||||
|
profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition.getId())
|
||||||
|
|
||||||
|
#Split all settings into per-extruder and global settings.
|
||||||
|
for setting_key in profile.getAllKeys():
|
||||||
|
settable_per_extruder = global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
||||||
|
if settable_per_extruder:
|
||||||
|
global_profile.removeInstance(setting_key)
|
||||||
|
else:
|
||||||
|
profile.removeInstance(setting_key)
|
||||||
|
|
||||||
|
return [global_profile, profile]
|
||||||
|
@ -270,6 +270,20 @@ Cura.MachineAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: manager
|
||||||
|
onDefinedExtruderCountChanged:
|
||||||
|
{
|
||||||
|
extruderCountModel.clear();
|
||||||
|
for(var i = 0; i < manager.definedExtruderCount; ++i)
|
||||||
|
{
|
||||||
|
extruderCountModel.append({text: String(i + 1), value: i});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
currentIndex: machineExtruderCountProvider.properties.value - 1
|
currentIndex: machineExtruderCountProvider.properties.value - 1
|
||||||
onActivated:
|
onActivated:
|
||||||
{
|
{
|
||||||
@ -432,7 +446,7 @@ Cura.MachineAction
|
|||||||
property int areaHeight: parent.height - y
|
property int areaHeight: parent.height - y
|
||||||
property string settingKey: "machine_extruder_start_code"
|
property string settingKey: "machine_extruder_start_code"
|
||||||
property bool isExtruderSetting: true
|
property bool isExtruderSetting: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column {
|
Column {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
@ -714,7 +728,7 @@ Cura.MachineAction
|
|||||||
width: gcodeArea.width
|
width: gcodeArea.width
|
||||||
text: _tooltip
|
text: _tooltip
|
||||||
|
|
||||||
property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting
|
property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting
|
||||||
property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
|
property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
|
||||||
|
|
||||||
UM.SettingPropertyProvider
|
UM.SettingPropertyProvider
|
||||||
@ -726,7 +740,7 @@ Cura.MachineAction
|
|||||||
{
|
{
|
||||||
if(settingsTabs.currentIndex > 0)
|
if(settingsTabs.currentIndex > 0)
|
||||||
{
|
{
|
||||||
return Cura.MachineManager.activeStackId;
|
return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -39,17 +39,22 @@ class SliceInfo(Extension):
|
|||||||
Preferences.getInstance().addPreference("info/send_slice_info", True)
|
Preferences.getInstance().addPreference("info/send_slice_info", True)
|
||||||
Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
|
Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
|
||||||
|
|
||||||
if not Preferences.getInstance().getValue("info/asked_send_slice_info") and Preferences.getInstance().getValue("info/send_slice_info"):
|
if not Preferences.getInstance().getValue("info/asked_send_slice_info"):
|
||||||
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in the preferences."),
|
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymized usage statistics."),
|
||||||
lifetime = 0,
|
lifetime = 0,
|
||||||
dismissable = False,
|
dismissable = False,
|
||||||
title = catalog.i18nc("@info:title", "Collecting Data"))
|
title = catalog.i18nc("@info:title", "Collecting Data"))
|
||||||
|
|
||||||
self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "")
|
self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None,
|
||||||
|
description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."))
|
||||||
|
self.send_slice_info_message.addAction("Disable", name = catalog.i18nc("@action:button", "Disable"), icon = None,
|
||||||
|
description = catalog.i18nc("@action:tooltip", "Don't allow Cura to send anonymized usage statistics. You can enable it again in the preferences."))
|
||||||
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
||||||
self.send_slice_info_message.show()
|
self.send_slice_info_message.show()
|
||||||
|
|
||||||
def messageActionTriggered(self, message_id, action_id):
|
def messageActionTriggered(self, message_id, action_id):
|
||||||
|
if action_id == "Disable":
|
||||||
|
Preferences.getInstance().setValue("info/send_slice_info", False)
|
||||||
self.send_slice_info_message.hide()
|
self.send_slice_info_message.hide()
|
||||||
Preferences.getInstance().setValue("info/asked_send_slice_info", True)
|
Preferences.getInstance().setValue("info/asked_send_slice_info", True)
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class SolidView(View):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if getattr(node, "_non_printing_mesh", False):
|
if node.callDecoration("isNonPrintingMesh"):
|
||||||
if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")):
|
if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")):
|
||||||
renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True)
|
renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True)
|
||||||
else:
|
else:
|
||||||
|
@ -129,12 +129,17 @@ class VersionUpgrade30to31(VersionUpgrade):
|
|||||||
if parser.has_option("values", "machine_nozzle_size"):
|
if parser.has_option("values", "machine_nozzle_size"):
|
||||||
machine_nozzle_size = parser["values"]["machine_nozzle_size"]
|
machine_nozzle_size = parser["values"]["machine_nozzle_size"]
|
||||||
|
|
||||||
definition_name = parser["general"]["name"]
|
machine_extruder_count = '1' # by default it is 1 and the value cannot be stored in the global stack
|
||||||
machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name)
|
if parser.has_option("values", "machine_extruder_count"):
|
||||||
|
machine_extruder_count = parser["values"]["machine_extruder_count"]
|
||||||
|
|
||||||
#For single extuder machine we nee only first extruder
|
if machine_extruder_count == '1':
|
||||||
if len(machine_extruders) !=0:
|
definition_name = parser["general"]["name"]
|
||||||
if self._updateSingleExtuderDefinitionFile(machine_extruders, machine_nozzle_size):
|
machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name)
|
||||||
|
|
||||||
|
# For single extruder machine we need only first extruder
|
||||||
|
if len(machine_extruders) !=0:
|
||||||
|
self._updateSingleExtruderDefinitionFile(machine_extruders, machine_nozzle_size)
|
||||||
parser.remove_option("values", "machine_nozzle_size")
|
parser.remove_option("values", "machine_nozzle_size")
|
||||||
|
|
||||||
# Update version numbers
|
# Update version numbers
|
||||||
@ -219,9 +224,9 @@ class VersionUpgrade30to31(VersionUpgrade):
|
|||||||
|
|
||||||
machine_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.MachineStack)
|
machine_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.MachineStack)
|
||||||
|
|
||||||
machine_instances = []
|
machine_instance_id = None
|
||||||
|
|
||||||
#Find all machine instances
|
# Find machine instances
|
||||||
for item in os.listdir(machine_instances_dir):
|
for item in os.listdir(machine_instances_dir):
|
||||||
file_path = os.path.join(machine_instances_dir, item)
|
file_path = os.path.join(machine_instances_dir, item)
|
||||||
if not os.path.isfile(file_path):
|
if not os.path.isfile(file_path):
|
||||||
@ -242,57 +247,51 @@ class VersionUpgrade30to31(VersionUpgrade):
|
|||||||
if not parser.has_option("general", "id"):
|
if not parser.has_option("general", "id"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
machine_instances.append(parser)
|
id = parser["general"]["id"]
|
||||||
|
if id + "_settings" != definition_name:
|
||||||
#Find for extruders
|
|
||||||
extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
|
|
||||||
#"machine",[extruders]
|
|
||||||
extruder_instances_per_machine = {}
|
|
||||||
|
|
||||||
#Find all custom extruders for founded machines
|
|
||||||
for item in os.listdir(extruders_instances_dir):
|
|
||||||
file_path = os.path.join(extruders_instances_dir, item)
|
|
||||||
if not os.path.isfile(file_path):
|
|
||||||
continue
|
continue
|
||||||
|
else:
|
||||||
parser = configparser.ConfigParser(interpolation=None)
|
machine_instance_id = id
|
||||||
try:
|
|
||||||
parser.read([file_path])
|
|
||||||
except:
|
|
||||||
# skip, it is not a valid stack file
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not parser.has_option("metadata", "type"):
|
|
||||||
continue
|
|
||||||
if "extruder_train" != parser["metadata"]["type"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not parser.has_option("metadata", "machine"):
|
|
||||||
continue
|
|
||||||
if not parser.has_option("metadata", "position"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
|
||||||
for machine_instace in machine_instances:
|
|
||||||
|
|
||||||
machine_id = machine_instace["general"]["id"]
|
|
||||||
if machine_id != parser["metadata"]["machine"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if machine_id + "_settings" != definition_name:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if extruder_instances_per_machine.get(machine_id) is None:
|
|
||||||
extruder_instances_per_machine.update({machine_id:[]})
|
|
||||||
|
|
||||||
extruder_instances_per_machine.get(machine_id).append(parser)
|
|
||||||
#the extruder can be related only to one machine
|
|
||||||
break
|
break
|
||||||
|
|
||||||
return extruder_instances_per_machine
|
if machine_instance_id is not None:
|
||||||
|
|
||||||
#Find extruder defition at index 0 and update its values
|
extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
|
||||||
def _updateSingleExtuderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size):
|
#"machine",[extruders]
|
||||||
|
extruder_instances = []
|
||||||
|
|
||||||
|
# Find all custom extruders for found machines
|
||||||
|
for item in os.listdir(extruders_instances_dir):
|
||||||
|
file_path = os.path.join(extruders_instances_dir, item)
|
||||||
|
if not os.path.isfile(file_path):
|
||||||
|
continue
|
||||||
|
|
||||||
|
parser = configparser.ConfigParser(interpolation=None)
|
||||||
|
try:
|
||||||
|
parser.read([file_path])
|
||||||
|
except:
|
||||||
|
# skip, it is not a valid stack file
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not parser.has_option("metadata", "type"):
|
||||||
|
continue
|
||||||
|
if "extruder_train" != parser["metadata"]["type"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not parser.has_option("metadata", "machine"):
|
||||||
|
continue
|
||||||
|
if not parser.has_option("metadata", "position"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if machine_instance_id != parser["metadata"]["machine"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
extruder_instances.append(parser)
|
||||||
|
|
||||||
|
return extruder_instances
|
||||||
|
|
||||||
|
# Find extruder definition at index 0 and update its values
|
||||||
|
def _updateSingleExtruderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size):
|
||||||
|
|
||||||
defintion_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer)
|
defintion_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer)
|
||||||
|
|
||||||
@ -312,19 +311,15 @@ class VersionUpgrade30to31(VersionUpgrade):
|
|||||||
continue
|
continue
|
||||||
name = parser["general"]["name"]
|
name = parser["general"]["name"]
|
||||||
custom_extruder_at_0_position = None
|
custom_extruder_at_0_position = None
|
||||||
for machine_extruders in extruder_instances_per_machine:
|
for extruder_instance in extruder_instances_per_machine:
|
||||||
for extruder_instance in extruder_instances_per_machine[machine_extruders]:
|
|
||||||
|
|
||||||
if extruder_instance["general"]["id"] + "_settings" == name:
|
definition_position = extruder_instance["metadata"]["position"]
|
||||||
defition_position = extruder_instance["metadata"]["position"]
|
|
||||||
|
|
||||||
if defition_position == "0":
|
if definition_position == "0":
|
||||||
custom_extruder_at_0_position = extruder_instance
|
custom_extruder_at_0_position = extruder_instance
|
||||||
break
|
|
||||||
if custom_extruder_at_0_position is not None:
|
|
||||||
break
|
break
|
||||||
|
|
||||||
#If not null, then parsed file is for first extuder and then can be updated. I need to update only
|
# If not null, then parsed file is for first extuder and then can be updated. I need to update only
|
||||||
# first, because this update for single extuder machine
|
# first, because this update for single extuder machine
|
||||||
if custom_extruder_at_0_position is not None:
|
if custom_extruder_at_0_position is not None:
|
||||||
|
|
||||||
@ -374,4 +369,4 @@ class VersionUpgrade30to31(VersionUpgrade):
|
|||||||
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
|
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
|
||||||
|
|
||||||
with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
|
with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
|
||||||
f.write(extruder_quality_changes_output.getvalue())
|
f.write(extruder_quality_changes_output.getvalue())
|
Loading…
x
Reference in New Issue
Block a user