mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
Merge branch 'master' into feature_mesh_types
# Conflicts: # plugins/SolidView/SolidView.py
This commit is contained in:
commit
1924946b59
63 changed files with 5629 additions and 1042 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -43,6 +43,7 @@ plugins/ProfileFlattener
|
||||||
plugins/cura-god-mode-plugin
|
plugins/cura-god-mode-plugin
|
||||||
plugins/cura-big-flame-graph
|
plugins/cura-big-flame-graph
|
||||||
plugins/cura-siemensnx-plugin
|
plugins/cura-siemensnx-plugin
|
||||||
|
plugins/CuraVariSlicePlugin
|
||||||
|
|
||||||
#Build stuff
|
#Build stuff
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
|
|
@ -39,7 +39,7 @@ find_package(PythonInterp 3.5.0 REQUIRED)
|
||||||
install(DIRECTORY resources
|
install(DIRECTORY resources
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
|
||||||
install(DIRECTORY plugins
|
install(DIRECTORY plugins
|
||||||
DESTINATION lib/cura)
|
DESTINATION lib${LIB_SUFFIX}/cura)
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(FILES cura_app.py
|
install(FILES cura_app.py
|
||||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
@ -47,16 +47,16 @@ if(NOT APPLE AND NOT WIN32)
|
||||||
RENAME cura)
|
RENAME cura)
|
||||||
if(EXISTS /etc/debian_version)
|
if(EXISTS /etc/debian_version)
|
||||||
install(DIRECTORY cura
|
install(DIRECTORY cura
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}/dist-packages
|
||||||
FILES_MATCHING PATTERN *.py)
|
FILES_MATCHING PATTERN *.py)
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
|
||||||
else()
|
else()
|
||||||
install(DIRECTORY cura
|
install(DIRECTORY cura
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
|
||||||
FILES_MATCHING PATTERN *.py)
|
FILES_MATCHING PATTERN *.py)
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
||||||
endif()
|
endif()
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/cura.desktop
|
install(FILES ${CMAKE_BINARY_DIR}/cura.desktop
|
||||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||||
|
@ -72,8 +72,8 @@ else()
|
||||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
install(DIRECTORY cura
|
install(DIRECTORY cura
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages
|
||||||
FILES_MATCHING PATTERN *.py)
|
FILES_MATCHING PATTERN *.py)
|
||||||
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py
|
||||||
DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
DESTINATION lib${LIB_SUFFIX}/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -876,15 +876,6 @@ class BuildVolume(SceneNode):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
## Private convenience function to get a setting from the adhesion
|
|
||||||
# extruder.
|
|
||||||
#
|
|
||||||
# \param setting_key The key of the setting to get.
|
|
||||||
# \param property The property to get from the setting.
|
|
||||||
# \return The property of the specified setting in the adhesion extruder.
|
|
||||||
def _getSettingFromAdhesionExtruder(self, setting_key, property = "value"):
|
|
||||||
return self._getSettingFromExtruder(setting_key, "adhesion_extruder_nr", property)
|
|
||||||
|
|
||||||
## Private convenience function to get a setting from every extruder.
|
## Private convenience function to get a setting from every extruder.
|
||||||
#
|
#
|
||||||
# For single extrusion machines, this gets the setting from the global
|
# For single extrusion machines, this gets the setting from the global
|
||||||
|
@ -899,44 +890,6 @@ class BuildVolume(SceneNode):
|
||||||
all_values[i] = 0
|
all_values[i] = 0
|
||||||
return all_values
|
return all_values
|
||||||
|
|
||||||
## Private convenience function to get a setting from the support infill
|
|
||||||
# extruder.
|
|
||||||
#
|
|
||||||
# \param setting_key The key of the setting to get.
|
|
||||||
# \param property The property to get from the setting.
|
|
||||||
# \return The property of the specified setting in the support infill
|
|
||||||
# extruder.
|
|
||||||
def _getSettingFromSupportInfillExtruder(self, setting_key, property = "value"):
|
|
||||||
return self._getSettingFromExtruder(setting_key, "support_infill_extruder_nr", property)
|
|
||||||
|
|
||||||
## Helper function to get a setting from an extruder specified in another
|
|
||||||
# setting.
|
|
||||||
#
|
|
||||||
# \param setting_key The key of the setting to get.
|
|
||||||
# \param extruder_setting_key The key of the setting that specifies from
|
|
||||||
# which extruder to get the setting, if there are multiple extruders.
|
|
||||||
# \param property The property to get from the setting.
|
|
||||||
# \return The property of the specified setting in the specified extruder.
|
|
||||||
def _getSettingFromExtruder(self, setting_key, extruder_setting_key, property = "value"):
|
|
||||||
multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
|
||||||
|
|
||||||
if not multi_extrusion:
|
|
||||||
stack = self._global_container_stack
|
|
||||||
else:
|
|
||||||
extruder_index = self._global_container_stack.getProperty(extruder_setting_key, "value")
|
|
||||||
|
|
||||||
if str(extruder_index) == "-1": # If extruder index is -1 use global instead
|
|
||||||
stack = self._global_container_stack
|
|
||||||
else:
|
|
||||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds[str(extruder_index)]
|
|
||||||
stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
|
||||||
|
|
||||||
value = stack.getProperty(setting_key, property)
|
|
||||||
setting_type = stack.getProperty(setting_key, "type")
|
|
||||||
if not value and (setting_type == "int" or setting_type == "float"):
|
|
||||||
return 0
|
|
||||||
return value
|
|
||||||
|
|
||||||
## Convenience function to calculate the disallowed radius around the edge.
|
## Convenience function to calculate the disallowed radius around the edge.
|
||||||
#
|
#
|
||||||
# This disallowed radius is to allow for space around the models that is
|
# This disallowed radius is to allow for space around the models that is
|
||||||
|
@ -945,6 +898,7 @@ class BuildVolume(SceneNode):
|
||||||
def _getEdgeDisallowedSize(self):
|
def _getEdgeDisallowedSize(self):
|
||||||
if not self._global_container_stack:
|
if not self._global_container_stack:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
container_stack = self._global_container_stack
|
container_stack = self._global_container_stack
|
||||||
used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
|
used_extruders = ExtruderManager.getInstance().getUsedExtruderStacks()
|
||||||
|
|
||||||
|
@ -953,32 +907,44 @@ class BuildVolume(SceneNode):
|
||||||
return 0.1 # Return a very small value, so we do draw disallowed area's near the edges.
|
return 0.1 # Return a very small value, so we do draw disallowed area's near the edges.
|
||||||
|
|
||||||
adhesion_type = container_stack.getProperty("adhesion_type", "value")
|
adhesion_type = container_stack.getProperty("adhesion_type", "value")
|
||||||
|
skirt_brim_line_width = self._global_container_stack.getProperty("skirt_brim_line_width", "value")
|
||||||
|
initial_layer_line_width_factor = self._global_container_stack.getProperty("initial_layer_line_width_factor", "value")
|
||||||
if adhesion_type == "skirt":
|
if adhesion_type == "skirt":
|
||||||
skirt_distance = self._getSettingFromAdhesionExtruder("skirt_gap")
|
skirt_distance = self._global_container_stack.getProperty("skirt_gap", "value")
|
||||||
skirt_line_count = self._getSettingFromAdhesionExtruder("skirt_line_count")
|
skirt_line_count = self._global_container_stack.getProperty("skirt_line_count", "value")
|
||||||
bed_adhesion_size = skirt_distance + (self._getSettingFromAdhesionExtruder("skirt_brim_line_width") * skirt_line_count) * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
|
||||||
if len(used_extruders) > 1:
|
bed_adhesion_size = skirt_distance + (skirt_brim_line_width * skirt_line_count) * initial_layer_line_width_factor / 100.0
|
||||||
for extruder_stack in used_extruders:
|
|
||||||
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
for extruder_stack in used_extruders:
|
||||||
#We don't create an additional line for the extruder we're printing the skirt with.
|
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
||||||
bed_adhesion_size -= self._getSettingFromAdhesionExtruder("skirt_brim_line_width", "value") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor", "value") / 100.0
|
|
||||||
|
# We don't create an additional line for the extruder we're printing the skirt with.
|
||||||
|
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
|
||||||
|
|
||||||
elif adhesion_type == "brim":
|
elif adhesion_type == "brim":
|
||||||
bed_adhesion_size = self._getSettingFromAdhesionExtruder("skirt_brim_line_width") * self._getSettingFromAdhesionExtruder("brim_line_count") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor") / 100.0
|
brim_line_count = self._global_container_stack.getProperty("brim_line_count", "value")
|
||||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
bed_adhesion_size = skirt_brim_line_width * brim_line_count * initial_layer_line_width_factor / 100.0
|
||||||
for extruder_stack in used_extruders:
|
|
||||||
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
for extruder_stack in used_extruders:
|
||||||
#We don't create an additional line for the extruder we're printing the brim with.
|
bed_adhesion_size += extruder_stack.getProperty("skirt_brim_line_width", "value") * extruder_stack.getProperty("initial_layer_line_width_factor", "value") / 100.0
|
||||||
bed_adhesion_size -= self._getSettingFromAdhesionExtruder("skirt_brim_line_width", "value") * self._getSettingFromAdhesionExtruder("initial_layer_line_width_factor", "value") / 100.0
|
|
||||||
|
# We don't create an additional line for the extruder we're printing the brim with.
|
||||||
|
bed_adhesion_size -= skirt_brim_line_width * initial_layer_line_width_factor / 100.0
|
||||||
|
|
||||||
elif adhesion_type == "raft":
|
elif adhesion_type == "raft":
|
||||||
bed_adhesion_size = self._getSettingFromAdhesionExtruder("raft_margin")
|
bed_adhesion_size = self._global_container_stack.getProperty("raft_margin", "value")
|
||||||
|
|
||||||
elif adhesion_type == "none":
|
elif adhesion_type == "none":
|
||||||
bed_adhesion_size = 0
|
bed_adhesion_size = 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
|
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
|
||||||
|
|
||||||
support_expansion = 0
|
support_expansion = 0
|
||||||
if self._getSettingFromSupportInfillExtruder("support_offset") and self._global_container_stack.getProperty("support_enable", "value"):
|
support_enabled = self._global_container_stack.getProperty("support_enable", "value")
|
||||||
support_expansion += self._getSettingFromSupportInfillExtruder("support_offset")
|
support_offset = self._global_container_stack.getProperty("support_offset", "value")
|
||||||
|
if support_enabled and support_offset:
|
||||||
|
support_expansion += support_offset
|
||||||
|
|
||||||
farthest_shield_distance = 0
|
farthest_shield_distance = 0
|
||||||
if container_stack.getProperty("draft_shield_enabled", "value"):
|
if container_stack.getProperty("draft_shield_enabled", "value"):
|
||||||
|
|
|
@ -307,24 +307,23 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||||
self._onChanged()
|
self._onChanged()
|
||||||
|
|
||||||
## Private convenience function to get a setting from the correct extruder (as defined by limit_to_extruder property).
|
## Private convenience function to get a setting from the correct extruder (as defined by limit_to_extruder property).
|
||||||
def _getSettingProperty(self, setting_key, property = "value"):
|
def _getSettingProperty(self, setting_key, prop = "value"):
|
||||||
per_mesh_stack = self._node.callDecoration("getStack")
|
per_mesh_stack = self._node.callDecoration("getStack")
|
||||||
if per_mesh_stack:
|
if per_mesh_stack:
|
||||||
return per_mesh_stack.getProperty(setting_key, property)
|
return per_mesh_stack.getProperty(setting_key, prop)
|
||||||
|
|
||||||
multi_extrusion = self._global_stack.getProperty("machine_extruder_count", "value") > 1
|
|
||||||
if not multi_extrusion:
|
|
||||||
return self._global_stack.getProperty(setting_key, property)
|
|
||||||
|
|
||||||
extruder_index = self._global_stack.getProperty(setting_key, "limit_to_extruder")
|
extruder_index = self._global_stack.getProperty(setting_key, "limit_to_extruder")
|
||||||
if extruder_index == "-1": #No limit_to_extruder.
|
if extruder_index == "-1":
|
||||||
|
# No limit_to_extruder
|
||||||
extruder_stack_id = self._node.callDecoration("getActiveExtruder")
|
extruder_stack_id = self._node.callDecoration("getActiveExtruder")
|
||||||
if not extruder_stack_id: #Decoration doesn't exist.
|
if not extruder_stack_id:
|
||||||
|
# Decoration doesn't exist
|
||||||
extruder_stack_id = ExtruderManager.getInstance().extruderIds["0"]
|
extruder_stack_id = ExtruderManager.getInstance().extruderIds["0"]
|
||||||
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||||
return extruder_stack.getProperty(setting_key, property)
|
return extruder_stack.getProperty(setting_key, prop)
|
||||||
else: #Limit_to_extruder is set. The global stack handles this then.
|
else:
|
||||||
return self._global_stack.getProperty(setting_key, property)
|
# Limit_to_extruder is set. The global stack handles this then
|
||||||
|
return self._global_stack.getProperty(setting_key, prop)
|
||||||
|
|
||||||
## Returns true if node is a descendant or the same as the root node.
|
## Returns true if node is a descendant or the same as the root node.
|
||||||
def __isDescendant(self, root, node):
|
def __isDescendant(self, root, node):
|
||||||
|
|
|
@ -200,6 +200,7 @@ class CuraApplication(QtApplication):
|
||||||
|
|
||||||
self._machine_action_manager = MachineActionManager.MachineActionManager()
|
self._machine_action_manager = MachineActionManager.MachineActionManager()
|
||||||
self._machine_manager = None # This is initialized on demand.
|
self._machine_manager = None # This is initialized on demand.
|
||||||
|
self._extruder_manager = None
|
||||||
self._material_manager = None
|
self._material_manager = None
|
||||||
self._setting_inheritance_manager = None
|
self._setting_inheritance_manager = None
|
||||||
self._simple_mode_settings_manager = None
|
self._simple_mode_settings_manager = None
|
||||||
|
@ -260,14 +261,17 @@ class CuraApplication(QtApplication):
|
||||||
# Since they are empty, they should never be serialized and instead just programmatically created.
|
# Since they are empty, they should never be serialized and instead just programmatically created.
|
||||||
# We need them to simplify the switching between materials.
|
# We need them to simplify the switching between materials.
|
||||||
empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
||||||
|
|
||||||
empty_variant_container = copy.deepcopy(empty_container)
|
empty_variant_container = copy.deepcopy(empty_container)
|
||||||
empty_variant_container._id = "empty_variant"
|
empty_variant_container._id = "empty_variant"
|
||||||
empty_variant_container.addMetaDataEntry("type", "variant")
|
empty_variant_container.addMetaDataEntry("type", "variant")
|
||||||
ContainerRegistry.getInstance().addContainer(empty_variant_container)
|
ContainerRegistry.getInstance().addContainer(empty_variant_container)
|
||||||
|
|
||||||
empty_material_container = copy.deepcopy(empty_container)
|
empty_material_container = copy.deepcopy(empty_container)
|
||||||
empty_material_container._id = "empty_material"
|
empty_material_container._id = "empty_material"
|
||||||
empty_material_container.addMetaDataEntry("type", "material")
|
empty_material_container.addMetaDataEntry("type", "material")
|
||||||
ContainerRegistry.getInstance().addContainer(empty_material_container)
|
ContainerRegistry.getInstance().addContainer(empty_material_container)
|
||||||
|
|
||||||
empty_quality_container = copy.deepcopy(empty_container)
|
empty_quality_container = copy.deepcopy(empty_container)
|
||||||
empty_quality_container._id = "empty_quality"
|
empty_quality_container._id = "empty_quality"
|
||||||
empty_quality_container.setName("Not Supported")
|
empty_quality_container.setName("Not Supported")
|
||||||
|
@ -275,6 +279,7 @@ class CuraApplication(QtApplication):
|
||||||
empty_quality_container.addMetaDataEntry("type", "quality")
|
empty_quality_container.addMetaDataEntry("type", "quality")
|
||||||
empty_quality_container.addMetaDataEntry("supported", False)
|
empty_quality_container.addMetaDataEntry("supported", False)
|
||||||
ContainerRegistry.getInstance().addContainer(empty_quality_container)
|
ContainerRegistry.getInstance().addContainer(empty_quality_container)
|
||||||
|
|
||||||
empty_quality_changes_container = copy.deepcopy(empty_container)
|
empty_quality_changes_container = copy.deepcopy(empty_container)
|
||||||
empty_quality_changes_container._id = "empty_quality_changes"
|
empty_quality_changes_container._id = "empty_quality_changes"
|
||||||
empty_quality_changes_container.addMetaDataEntry("type", "quality_changes")
|
empty_quality_changes_container.addMetaDataEntry("type", "quality_changes")
|
||||||
|
@ -425,7 +430,7 @@ class CuraApplication(QtApplication):
|
||||||
def discardOrKeepProfileChangesClosed(self, option):
|
def discardOrKeepProfileChangesClosed(self, option):
|
||||||
if option == "discard":
|
if option == "discard":
|
||||||
global_stack = self.getGlobalContainerStack()
|
global_stack = self.getGlobalContainerStack()
|
||||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()):
|
||||||
extruder.getTop().clear()
|
extruder.getTop().clear()
|
||||||
global_stack.getTop().clear()
|
global_stack.getTop().clear()
|
||||||
|
|
||||||
|
@ -433,7 +438,7 @@ class CuraApplication(QtApplication):
|
||||||
# before slicing. To ensure that slicer uses right settings values
|
# before slicing. To ensure that slicer uses right settings values
|
||||||
elif option == "keep":
|
elif option == "keep":
|
||||||
global_stack = self.getGlobalContainerStack()
|
global_stack = self.getGlobalContainerStack()
|
||||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
for extruder in self._extruder_manager.getMachineExtruders(global_stack.getId()):
|
||||||
user_extruder_container = extruder.getTop()
|
user_extruder_container = extruder.getTop()
|
||||||
if user_extruder_container:
|
if user_extruder_container:
|
||||||
user_extruder_container.update()
|
user_extruder_container.update()
|
||||||
|
@ -699,16 +704,13 @@ class CuraApplication(QtApplication):
|
||||||
|
|
||||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
||||||
|
|
||||||
# Initialise extruder so as to listen to global container stack changes before the first global container stack is set.
|
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager)
|
||||||
ExtruderManager.getInstance()
|
|
||||||
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
||||||
qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager)
|
qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager)
|
||||||
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager",
|
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager)
|
||||||
self.getSettingInheritanceManager)
|
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
|
||||||
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager",
|
|
||||||
self.getSimpleModeSettingsManager)
|
|
||||||
|
|
||||||
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
||||||
|
|
||||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||||
|
|
||||||
|
@ -719,8 +721,8 @@ class CuraApplication(QtApplication):
|
||||||
if run_headless or self._engine.rootObjects:
|
if run_headless or self._engine.rootObjects:
|
||||||
self.closeSplash()
|
self.closeSplash()
|
||||||
|
|
||||||
for file in self.getCommandLineOption("file", []):
|
for file_name in self.getCommandLineOption("file", []):
|
||||||
self._openFile(file)
|
self._openFile(file_name)
|
||||||
for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading.
|
for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading.
|
||||||
self._openFile(file_name)
|
self._openFile(file_name)
|
||||||
|
|
||||||
|
@ -733,6 +735,11 @@ class CuraApplication(QtApplication):
|
||||||
self._machine_manager = MachineManager.createMachineManager()
|
self._machine_manager = MachineManager.createMachineManager()
|
||||||
return self._machine_manager
|
return self._machine_manager
|
||||||
|
|
||||||
|
def getExtruderManager(self, *args):
|
||||||
|
if self._extruder_manager is None:
|
||||||
|
self._extruder_manager = ExtruderManager.createExtruderManager()
|
||||||
|
return self._extruder_manager
|
||||||
|
|
||||||
def getMaterialManager(self, *args):
|
def getMaterialManager(self, *args):
|
||||||
if self._material_manager is None:
|
if self._material_manager is None:
|
||||||
self._material_manager = MaterialManager.createMaterialManager()
|
self._material_manager = MaterialManager.createMaterialManager()
|
||||||
|
@ -783,7 +790,6 @@ class CuraApplication(QtApplication):
|
||||||
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
||||||
|
|
||||||
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||||
|
|
||||||
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
||||||
qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel)
|
qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel)
|
||||||
qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel")
|
qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel")
|
||||||
|
@ -793,15 +799,12 @@ class CuraApplication(QtApplication):
|
||||||
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
|
||||||
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
|
||||||
qmlRegisterType(UserChangesModel, "Cura", 1, 1, "UserChangesModel")
|
qmlRegisterType(UserChangesModel, "Cura", 1, 1, "UserChangesModel")
|
||||||
|
|
||||||
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
|
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
|
||||||
|
|
||||||
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
|
||||||
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
actions_url = QUrl.fromLocalFile(os.path.abspath(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")))
|
||||||
qmlRegisterSingletonType(actions_url, "Cura", 1, 0, "Actions")
|
qmlRegisterSingletonType(actions_url, "Cura", 1, 0, "Actions")
|
||||||
|
|
||||||
engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.getInstance())
|
|
||||||
|
|
||||||
for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles):
|
for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles):
|
||||||
type_name = os.path.splitext(os.path.basename(path))[0]
|
type_name = os.path.splitext(os.path.basename(path))[0]
|
||||||
if type_name in ("Cura", "Actions"):
|
if type_name in ("Cura", "Actions"):
|
||||||
|
|
57
cura/PreviewPass.py
Normal file
57
cura/PreviewPass.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Uranium is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from UM.Application import Application
|
||||||
|
from UM.Resources import Resources
|
||||||
|
|
||||||
|
from UM.View.RenderPass import RenderPass
|
||||||
|
from UM.View.GL.OpenGL import OpenGL
|
||||||
|
from UM.View.RenderBatch import RenderBatch
|
||||||
|
|
||||||
|
|
||||||
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
MYPY = False
|
||||||
|
if MYPY:
|
||||||
|
from UM.Scene.Camera import Camera
|
||||||
|
|
||||||
|
## A render pass subclass that renders slicable objects with default parameters.
|
||||||
|
# It uses the active camera by default, but it can be overridden to use a different camera.
|
||||||
|
#
|
||||||
|
# This is useful to get a preview image of a scene taken from a different location as the active camera.
|
||||||
|
class PreviewPass(RenderPass):
|
||||||
|
def __init__(self, width: int, height: int):
|
||||||
|
super().__init__("preview", width, height, 0)
|
||||||
|
|
||||||
|
self._camera = None # type: Optional[Camera]
|
||||||
|
|
||||||
|
self._renderer = Application.getInstance().getRenderer()
|
||||||
|
|
||||||
|
self._shader = None
|
||||||
|
self._scene = Application.getInstance().getController().getScene()
|
||||||
|
|
||||||
|
# Set the camera to be used by this render pass
|
||||||
|
# if it's None, the active camera is used
|
||||||
|
def setCamera(self, camera: Optional["Camera"]):
|
||||||
|
self._camera = camera
|
||||||
|
|
||||||
|
def render(self) -> None:
|
||||||
|
if not self._shader:
|
||||||
|
self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "object.shader"))
|
||||||
|
|
||||||
|
# Create a new batch to be rendered
|
||||||
|
batch = RenderBatch(self._shader)
|
||||||
|
|
||||||
|
# Fill up the batch with objects that can be sliced. `
|
||||||
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
|
||||||
|
batch.addItem(node.getWorldTransformation(), node.getMeshData())
|
||||||
|
|
||||||
|
self.bind()
|
||||||
|
if self._camera is None:
|
||||||
|
batch.render(Application.getInstance().getController().getScene().getActiveCamera())
|
||||||
|
else:
|
||||||
|
batch.render(self._camera)
|
||||||
|
self.release()
|
|
@ -305,6 +305,9 @@ class PrintInformation(QObject):
|
||||||
|
|
||||||
# name is "" when I first had some meshes and afterwards I deleted them so the naming should start again
|
# name is "" when I first had some meshes and afterwards I deleted them so the naming should start again
|
||||||
if name == "" or (self._base_name == "" and self._base_name != name):
|
if name == "" or (self._base_name == "" and self._base_name != name):
|
||||||
|
# remove ".curaproject" suffix from (imported) the file name
|
||||||
|
if name.endswith(".curaproject"):
|
||||||
|
name = name[:name.rfind(".curaproject")]
|
||||||
self._base_name = name
|
self._base_name = name
|
||||||
self._updateJobName()
|
self._updateJobName()
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.Platform import Platform
|
from UM.Platform import Platform
|
||||||
from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with.
|
from UM.PluginRegistry import PluginRegistry # For getting the possible profile writers to write with.
|
||||||
from UM.Util import parseBool
|
from UM.Util import parseBool
|
||||||
|
|
||||||
from . import ExtruderStack
|
from . import ExtruderStack
|
||||||
|
@ -42,12 +42,13 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
# Global stack based on metadata information.
|
# Global stack based on metadata information.
|
||||||
@override(ContainerRegistry)
|
@override(ContainerRegistry)
|
||||||
def addContainer(self, container):
|
def addContainer(self, container):
|
||||||
|
|
||||||
# Note: Intentional check with type() because we want to ignore subclasses
|
# Note: Intentional check with type() because we want to ignore subclasses
|
||||||
if type(container) == ContainerStack:
|
if type(container) == ContainerStack:
|
||||||
container = self._convertContainerStack(container)
|
container = self._convertContainerStack(container)
|
||||||
|
|
||||||
if isinstance(container, InstanceContainer) and type(container) != type(self.getEmptyInstanceContainer()):
|
if isinstance(container, InstanceContainer) and type(container) != type(self.getEmptyInstanceContainer()):
|
||||||
#Check against setting version of the definition.
|
# Check against setting version of the definition.
|
||||||
required_setting_version = CuraApplication.SettingVersion
|
required_setting_version = CuraApplication.SettingVersion
|
||||||
actual_setting_version = int(container.getMetaDataEntry("setting_version", default = 0))
|
actual_setting_version = int(container.getMetaDataEntry("setting_version", default = 0))
|
||||||
if required_setting_version != actual_setting_version:
|
if required_setting_version != actual_setting_version:
|
||||||
|
@ -256,7 +257,8 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
@override(ContainerRegistry)
|
@override(ContainerRegistry)
|
||||||
def load(self):
|
def load(self):
|
||||||
super().load()
|
super().load()
|
||||||
self._fixupExtruders()
|
self._registerSingleExtrusionMachinesExtruderStacks()
|
||||||
|
self._connectUpgradedExtruderStacksToMachines()
|
||||||
|
|
||||||
## Update an imported profile to match the current machine configuration.
|
## Update an imported profile to match the current machine configuration.
|
||||||
#
|
#
|
||||||
|
@ -299,10 +301,13 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
|
|
||||||
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||||
del quality_type_criteria["definition"]
|
del quality_type_criteria["definition"]
|
||||||
materials = None
|
|
||||||
|
# materials = None
|
||||||
|
|
||||||
if "material" in quality_type_criteria:
|
if "material" in quality_type_criteria:
|
||||||
materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"])
|
# materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"])
|
||||||
del quality_type_criteria["material"]
|
del quality_type_criteria["material"]
|
||||||
|
|
||||||
# Do not filter quality containers here with materials because we are trying to import a profile, so it should
|
# Do not filter quality containers here with materials because we are trying to import a profile, so it should
|
||||||
# NOT be restricted by the active materials on the current machine.
|
# NOT be restricted by the active materials on the current machine.
|
||||||
materials = None
|
materials = None
|
||||||
|
@ -360,8 +365,8 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
return global_container_stack.material.getId()
|
return global_container_stack.material.getId()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
## Returns true if the current machien requires its own quality profiles
|
## Returns true if the current machine requires its own quality profiles
|
||||||
# \return true if the current machien requires its own quality profiles
|
# \return true if the current machine requires its own quality profiles
|
||||||
def _machineHasOwnQualities(self):
|
def _machineHasOwnQualities(self):
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
|
@ -394,12 +399,65 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||||
|
|
||||||
return new_stack
|
return new_stack
|
||||||
|
|
||||||
|
def _registerSingleExtrusionMachinesExtruderStacks(self):
|
||||||
|
machines = ContainerRegistry.getInstance().findContainerStacks(machine_extruder_trains = {"0": "fdmextruder"})
|
||||||
|
for machine in machines:
|
||||||
|
self.addExtruderStackForSingleExtrusionMachine(machine, "fdmextruder")
|
||||||
|
|
||||||
|
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id):
|
||||||
|
new_extruder_id = extruder_id
|
||||||
|
extruder_stack = None
|
||||||
|
|
||||||
|
# if extruders are defined in the machine definition use those instead
|
||||||
|
if machine.extruders and len(machine.extruders) > 0:
|
||||||
|
new_extruder_id = machine.extruders["0"].getId()
|
||||||
|
extruder_stack = machine.extruders["0"]
|
||||||
|
|
||||||
|
# if the extruder stack doesn't exist yet we create and add it
|
||||||
|
if not extruder_stack:
|
||||||
|
extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
|
||||||
|
if not extruder_definitions:
|
||||||
|
Logger.log("w", "Could not find definition containers for extruder %s", new_extruder_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
extruder_definition = extruder_definitions[0]
|
||||||
|
unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id)
|
||||||
|
|
||||||
|
extruder_stack = ExtruderStack.ExtruderStack(unique_name)
|
||||||
|
extruder_stack.setName(extruder_definition.getName())
|
||||||
|
extruder_stack.setDefinition(extruder_definition)
|
||||||
|
extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
|
||||||
|
extruder_stack.setNextStack(machine)
|
||||||
|
|
||||||
|
if machine.userChanges:
|
||||||
|
# set existing user changes if found
|
||||||
|
extruder_stack.setUserChanges(machine.userChanges)
|
||||||
|
else:
|
||||||
|
# create empty user changes container otherwise
|
||||||
|
user_container = InstanceContainer(extruder_stack.id + "_user")
|
||||||
|
user_container.addMetaDataEntry("type", "user")
|
||||||
|
user_container.addMetaDataEntry("machine", extruder_stack.getId())
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
|
user_container.setDefinition(extruder_definition)
|
||||||
|
extruder_stack.setUserChanges(user_container)
|
||||||
|
self.addContainer(user_container)
|
||||||
|
|
||||||
|
variant_id = "default"
|
||||||
|
if machine.variant.getId() != "empty_variant":
|
||||||
|
variant_id = machine.variant.getId()
|
||||||
|
extruder_stack.setVariantById(variant_id)
|
||||||
|
extruder_stack.setMaterialById("default")
|
||||||
|
extruder_stack.setQualityById("default")
|
||||||
|
|
||||||
|
self.addContainer(extruder_stack)
|
||||||
|
|
||||||
# Fix the extruders that were upgraded to ExtruderStack instances during addContainer.
|
# Fix the extruders that were upgraded to ExtruderStack instances during addContainer.
|
||||||
# The stacks are now responsible for setting the next stack on deserialize. However,
|
# The stacks are now responsible for setting the next stack on deserialize. However,
|
||||||
# due to problems with loading order, some stacks may not have the proper next stack
|
# due to problems with loading order, some stacks may not have the proper next stack
|
||||||
# set after upgrading, because the proper global stack was not yet loaded. This method
|
# set after upgrading, because the proper global stack was not yet loaded. This method
|
||||||
# makes sure those extruders also get the right stack set.
|
# makes sure those extruders also get the right stack set.
|
||||||
def _fixupExtruders(self):
|
def _connectUpgradedExtruderStacksToMachines(self):
|
||||||
extruder_stacks = self.findContainers(ExtruderStack.ExtruderStack)
|
extruder_stacks = self.findContainers(ExtruderStack.ExtruderStack)
|
||||||
for extruder_stack in extruder_stacks:
|
for extruder_stack in extruder_stacks:
|
||||||
if extruder_stack.getNextStack():
|
if extruder_stack.getNextStack():
|
||||||
|
|
|
@ -396,7 +396,9 @@ class CuraContainerStack(ContainerStack):
|
||||||
# \note This method assumes the stack has a valid machine definition.
|
# \note This method assumes the stack has a valid machine definition.
|
||||||
def findDefaultVariant(self) -> Optional[ContainerInterface]:
|
def findDefaultVariant(self) -> Optional[ContainerInterface]:
|
||||||
definition = self._getMachineDefinition()
|
definition = self._getMachineDefinition()
|
||||||
if not definition.getMetaDataEntry("has_variants"):
|
# has_variants can be overridden in other containers and stacks.
|
||||||
|
# In the case of UM2, it is overridden in the GlobalStack
|
||||||
|
if not self.getMetaDataEntry("has_variants"):
|
||||||
# If the machine does not use variants, we should never set a variant.
|
# If the machine does not use variants, we should never set a variant.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -47,21 +47,40 @@ class CuraStackBuilder:
|
||||||
|
|
||||||
new_global_stack.setName(generated_name)
|
new_global_stack.setName(generated_name)
|
||||||
|
|
||||||
for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
|
extruder_definition = registry.findDefinitionContainers(machine = machine_definition.getId())
|
||||||
position = extruder_definition.getMetaDataEntry("position", None)
|
|
||||||
if not position:
|
|
||||||
Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.id)
|
|
||||||
|
|
||||||
new_extruder_id = registry.uniqueName(extruder_definition.id)
|
if not extruder_definition:
|
||||||
|
# create extruder stack for single extrusion machines that have no separate extruder definition files
|
||||||
|
extruder_definition = registry.findDefinitionContainers(id = "fdmextruder")[0]
|
||||||
|
new_extruder_id = registry.uniqueName(machine_definition.getName() + " " + extruder_definition.id)
|
||||||
new_extruder = cls.createExtruderStack(
|
new_extruder = cls.createExtruderStack(
|
||||||
new_extruder_id,
|
new_extruder_id,
|
||||||
definition = extruder_definition,
|
definition=extruder_definition,
|
||||||
machine_definition = machine_definition,
|
machine_definition=machine_definition,
|
||||||
quality = "default",
|
quality="default",
|
||||||
material = "default",
|
material="default",
|
||||||
variant = "default",
|
variant="default",
|
||||||
next_stack = new_global_stack
|
next_stack=new_global_stack
|
||||||
)
|
)
|
||||||
|
new_global_stack.addExtruder(new_extruder)
|
||||||
|
else:
|
||||||
|
# create extruder stack for each found extruder definition
|
||||||
|
for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
|
||||||
|
position = extruder_definition.getMetaDataEntry("position", None)
|
||||||
|
if not position:
|
||||||
|
Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.id)
|
||||||
|
|
||||||
|
new_extruder_id = registry.uniqueName(extruder_definition.id)
|
||||||
|
new_extruder = cls.createExtruderStack(
|
||||||
|
new_extruder_id,
|
||||||
|
definition = extruder_definition,
|
||||||
|
machine_definition = machine_definition,
|
||||||
|
quality = "default",
|
||||||
|
material = "default",
|
||||||
|
variant = "default",
|
||||||
|
next_stack = new_global_stack
|
||||||
|
)
|
||||||
|
new_global_stack.addExtruder(new_extruder)
|
||||||
|
|
||||||
return new_global_stack
|
return new_global_stack
|
||||||
|
|
||||||
|
@ -79,7 +98,9 @@ class CuraStackBuilder:
|
||||||
stack.setName(definition.getName())
|
stack.setName(definition.getName())
|
||||||
stack.setDefinition(definition)
|
stack.setDefinition(definition)
|
||||||
stack.addMetaDataEntry("position", definition.getMetaDataEntry("position"))
|
stack.addMetaDataEntry("position", definition.getMetaDataEntry("position"))
|
||||||
if "next_stack" in kwargs: #Add stacks before containers are added, since they may trigger a setting update.
|
|
||||||
|
if "next_stack" in kwargs:
|
||||||
|
# Add stacks before containers are added, since they may trigger a setting update.
|
||||||
stack.setNextStack(kwargs["next_stack"])
|
stack.setNextStack(kwargs["next_stack"])
|
||||||
|
|
||||||
user_container = InstanceContainer(new_stack_id + "_user")
|
user_container = InstanceContainer(new_stack_id + "_user")
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
# Copyright (c) 2017 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.
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant #For communicating data and events to Qt.
|
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
|
|
||||||
from UM.Application import Application #To get the global container stack to find the current machine.
|
from UM.Application import Application # To get the global container stack to find the current machine.
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Decorators import deprecated
|
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Scene.Selection import Selection
|
from UM.Scene.Selection import Selection
|
||||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID.
|
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
|
||||||
from UM.Settings.SettingFunction import SettingFunction
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
from UM.Settings.ContainerStack import ContainerStack
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
from UM.Settings.Interfaces import DefinitionContainerInterface
|
|
||||||
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
||||||
from typing import Optional, List, TYPE_CHECKING, Union
|
from typing import Optional, List, TYPE_CHECKING, Union
|
||||||
|
|
||||||
|
@ -28,6 +25,20 @@ if TYPE_CHECKING:
|
||||||
#
|
#
|
||||||
# This keeps a list of extruder stacks for each machine.
|
# This keeps a list of extruder stacks for each machine.
|
||||||
class ExtruderManager(QObject):
|
class ExtruderManager(QObject):
|
||||||
|
|
||||||
|
## Registers listeners and such to listen to changes to the extruders.
|
||||||
|
def __init__(self, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self._extruder_trains = {} # Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
|
||||||
|
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
|
||||||
|
self._selected_object_extruders = []
|
||||||
|
self._global_container_stack_definition_id = None
|
||||||
|
self._addCurrentMachineExtruders()
|
||||||
|
|
||||||
|
Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
|
||||||
|
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
|
||||||
|
|
||||||
## Signal to notify other components when the list of extruders for a machine definition changes.
|
## Signal to notify other components when the list of extruders for a machine definition changes.
|
||||||
extrudersChanged = pyqtSignal(QVariant)
|
extrudersChanged = pyqtSignal(QVariant)
|
||||||
|
|
||||||
|
@ -38,18 +49,6 @@ class ExtruderManager(QObject):
|
||||||
## Notify when the user switches the currently active extruder.
|
## Notify when the user switches the currently active extruder.
|
||||||
activeExtruderChanged = pyqtSignal()
|
activeExtruderChanged = pyqtSignal()
|
||||||
|
|
||||||
## Registers listeners and such to listen to changes to the extruders.
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
|
|
||||||
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
|
|
||||||
self._selected_object_extruders = []
|
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
|
|
||||||
self._global_container_stack_definition_id = None
|
|
||||||
self._addCurrentMachineExtruders()
|
|
||||||
|
|
||||||
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
|
|
||||||
|
|
||||||
## Gets the unique identifier of the currently active extruder stack.
|
## Gets the unique identifier of the currently active extruder stack.
|
||||||
#
|
#
|
||||||
# The currently active extruder stack is the stack that is currently being
|
# The currently active extruder stack is the stack that is currently being
|
||||||
|
@ -59,10 +58,10 @@ class ExtruderManager(QObject):
|
||||||
@pyqtProperty(str, notify = activeExtruderChanged)
|
@pyqtProperty(str, notify = activeExtruderChanged)
|
||||||
def activeExtruderStackId(self) -> Optional[str]:
|
def activeExtruderStackId(self) -> Optional[str]:
|
||||||
if not Application.getInstance().getGlobalContainerStack():
|
if not Application.getInstance().getGlobalContainerStack():
|
||||||
return None # No active machine, so no active extruder.
|
return None # No active machine, so no active extruder.
|
||||||
try:
|
try:
|
||||||
return self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
return self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
||||||
except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
|
except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
## Return extruder count according to extruder trains.
|
## Return extruder count according to extruder trains.
|
||||||
|
@ -76,23 +75,23 @@ class ExtruderManager(QObject):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
## Gets a dict with the extruder stack ids with the extruder number as the key.
|
## Gets a dict with the extruder stack ids with the extruder number as the key.
|
||||||
# The key "-1" indicates the global stack id.
|
|
||||||
#
|
|
||||||
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
||||||
def extruderIds(self):
|
def extruderIds(self):
|
||||||
extruder_stack_ids = {}
|
extruder_stack_ids = {}
|
||||||
|
|
||||||
global_stack_id = Application.getInstance().getGlobalContainerStack().getId()
|
global_stack_id = Application.getInstance().getGlobalContainerStack().getId()
|
||||||
extruder_stack_ids["-1"] = global_stack_id
|
|
||||||
if global_stack_id in self._extruder_trains:
|
if global_stack_id in self._extruder_trains:
|
||||||
for position in self._extruder_trains[global_stack_id]:
|
for position in self._extruder_trains[global_stack_id]:
|
||||||
extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId()
|
extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId()
|
||||||
|
|
||||||
return extruder_stack_ids
|
return extruder_stack_ids
|
||||||
|
|
||||||
@pyqtSlot(str, result = str)
|
@pyqtSlot(str, result = str)
|
||||||
def getQualityChangesIdByExtruderStackId(self, id: str) -> str:
|
def getQualityChangesIdByExtruderStackId(self, extruder_stack_id: str) -> str:
|
||||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
||||||
extruder = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position]
|
extruder = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position]
|
||||||
if extruder.getId() == id:
|
if extruder.getId() == extruder_stack_id:
|
||||||
return extruder.qualityChanges.getId()
|
return extruder.qualityChanges.getId()
|
||||||
|
|
||||||
## The instance of the singleton pattern.
|
## The instance of the singleton pattern.
|
||||||
|
@ -100,6 +99,10 @@ class ExtruderManager(QObject):
|
||||||
# It's None if the extruder manager hasn't been created yet.
|
# It's None if the extruder manager hasn't been created yet.
|
||||||
__instance = None
|
__instance = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def createExtruderManager():
|
||||||
|
return ExtruderManager().getInstance()
|
||||||
|
|
||||||
## Gets an instance of the extruder manager, or creates one if no instance
|
## Gets an instance of the extruder manager, or creates one if no instance
|
||||||
# exists yet.
|
# exists yet.
|
||||||
#
|
#
|
||||||
|
@ -185,6 +188,7 @@ class ExtruderManager(QObject):
|
||||||
if global_container_stack.getId() in self._extruder_trains:
|
if global_container_stack.getId() in self._extruder_trains:
|
||||||
if str(self._active_extruder_index) in self._extruder_trains[global_container_stack.getId()]:
|
if str(self._active_extruder_index) in self._extruder_trains[global_container_stack.getId()]:
|
||||||
return self._extruder_trains[global_container_stack.getId()][str(self._active_extruder_index)]
|
return self._extruder_trains[global_container_stack.getId()][str(self._active_extruder_index)]
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
## Get an extruder stack by index
|
## Get an extruder stack by index
|
||||||
|
@ -203,40 +207,6 @@ class ExtruderManager(QObject):
|
||||||
result.append(self.getExtruderStack(i))
|
result.append(self.getExtruderStack(i))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
## Adds all extruders of a specific machine definition to the extruder
|
|
||||||
# manager.
|
|
||||||
#
|
|
||||||
# \param machine_definition The machine definition to add the extruders for.
|
|
||||||
# \param machine_id The machine_id to add the extruders for.
|
|
||||||
@deprecated("Use CuraStackBuilder", "2.6")
|
|
||||||
def addMachineExtruders(self, machine_definition: DefinitionContainerInterface, machine_id: str) -> None:
|
|
||||||
changed = False
|
|
||||||
machine_definition_id = machine_definition.getId()
|
|
||||||
if machine_id not in self._extruder_trains:
|
|
||||||
self._extruder_trains[machine_id] = { }
|
|
||||||
changed = True
|
|
||||||
container_registry = ContainerRegistry.getInstance()
|
|
||||||
if container_registry:
|
|
||||||
# Add the extruder trains that don't exist yet.
|
|
||||||
for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition_id):
|
|
||||||
position = extruder_definition.getMetaDataEntry("position", None)
|
|
||||||
if not position:
|
|
||||||
Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
|
||||||
if not container_registry.findContainerStacks(machine = machine_id, position = position): # Doesn't exist yet.
|
|
||||||
self.createExtruderTrain(extruder_definition, machine_definition, position, machine_id)
|
|
||||||
changed = True
|
|
||||||
|
|
||||||
# Gets the extruder trains that we just created as well as any that still existed.
|
|
||||||
extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_id)
|
|
||||||
for extruder_train in extruder_trains:
|
|
||||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
|
||||||
|
|
||||||
# regardless of what the next stack is, we have to set it again, because of signal routing.
|
|
||||||
extruder_train.setNextStack(Application.getInstance().getGlobalContainerStack())
|
|
||||||
changed = True
|
|
||||||
if changed:
|
|
||||||
self.extrudersChanged.emit(machine_id)
|
|
||||||
|
|
||||||
def registerExtruder(self, extruder_train, machine_id):
|
def registerExtruder(self, extruder_train, machine_id):
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
|
@ -256,138 +226,6 @@ class ExtruderManager(QObject):
|
||||||
if changed:
|
if changed:
|
||||||
self.extrudersChanged.emit(machine_id)
|
self.extrudersChanged.emit(machine_id)
|
||||||
|
|
||||||
## Creates a container stack for an extruder train.
|
|
||||||
#
|
|
||||||
# The container stack has an extruder definition at the bottom, which is
|
|
||||||
# linked to a machine definition. Then it has a variant profile, a material
|
|
||||||
# profile, a quality profile and a user profile, in that order.
|
|
||||||
#
|
|
||||||
# The resulting container stack is added to the registry.
|
|
||||||
#
|
|
||||||
# \param extruder_definition The extruder to create the extruder train for.
|
|
||||||
# \param machine_definition The machine that the extruder train belongs to.
|
|
||||||
# \param position The position of this extruder train in the extruder slots of the machine.
|
|
||||||
# \param machine_id The id of the "global" stack this extruder is linked to.
|
|
||||||
@deprecated("Use CuraStackBuilder::createExtruderStack", "2.6")
|
|
||||||
def createExtruderTrain(self, extruder_definition: DefinitionContainerInterface, machine_definition: DefinitionContainerInterface,
|
|
||||||
position, machine_id: str) -> None:
|
|
||||||
# Cache some things.
|
|
||||||
container_registry = ContainerRegistry.getInstance()
|
|
||||||
machine_definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_definition)
|
|
||||||
|
|
||||||
# Create a container stack for this extruder.
|
|
||||||
extruder_stack_id = container_registry.uniqueName(extruder_definition.getId())
|
|
||||||
container_stack = ContainerStack(extruder_stack_id)
|
|
||||||
container_stack.setName(extruder_definition.getName()) # Take over the display name to display the stack with.
|
|
||||||
container_stack.addMetaDataEntry("type", "extruder_train")
|
|
||||||
container_stack.addMetaDataEntry("machine", machine_id)
|
|
||||||
container_stack.addMetaDataEntry("position", position)
|
|
||||||
container_stack.addContainer(extruder_definition)
|
|
||||||
|
|
||||||
# Find the variant to use for this extruder.
|
|
||||||
variant = container_registry.findInstanceContainers(id = "empty_variant")[0]
|
|
||||||
if machine_definition.getMetaDataEntry("has_variants"):
|
|
||||||
# First add any variant. Later, overwrite with preference if the preference is valid.
|
|
||||||
variants = container_registry.findInstanceContainers(definition = machine_definition_id, type = "variant")
|
|
||||||
if len(variants) >= 1:
|
|
||||||
variant = variants[0]
|
|
||||||
preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant")
|
|
||||||
if preferred_variant_id:
|
|
||||||
preferred_variants = container_registry.findInstanceContainers(id = preferred_variant_id, definition = machine_definition_id, type = "variant")
|
|
||||||
if len(preferred_variants) >= 1:
|
|
||||||
variant = preferred_variants[0]
|
|
||||||
else:
|
|
||||||
Logger.log("w", "The preferred variant \"%s\" of machine %s doesn't exist or is not a variant profile.", preferred_variant_id, machine_id)
|
|
||||||
# And leave it at the default variant.
|
|
||||||
container_stack.addContainer(variant)
|
|
||||||
|
|
||||||
# Find a material to use for this variant.
|
|
||||||
material = container_registry.findInstanceContainers(id = "empty_material")[0]
|
|
||||||
if machine_definition.getMetaDataEntry("has_materials"):
|
|
||||||
# First add any material. Later, overwrite with preference if the preference is valid.
|
|
||||||
machine_has_variant_materials = machine_definition.getMetaDataEntry("has_variant_materials", default = False)
|
|
||||||
if machine_has_variant_materials or machine_has_variant_materials == "True":
|
|
||||||
materials = container_registry.findInstanceContainers(type = "material", definition = machine_definition_id, variant = variant.getId())
|
|
||||||
else:
|
|
||||||
materials = container_registry.findInstanceContainers(type = "material", definition = machine_definition_id)
|
|
||||||
if len(materials) >= 1:
|
|
||||||
material = materials[0]
|
|
||||||
preferred_material_id = machine_definition.getMetaDataEntry("preferred_material")
|
|
||||||
if preferred_material_id:
|
|
||||||
global_stack = ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
|
||||||
if global_stack:
|
|
||||||
approximate_material_diameter = str(round(global_stack[0].getProperty("material_diameter", "value")))
|
|
||||||
else:
|
|
||||||
approximate_material_diameter = str(round(machine_definition.getProperty("material_diameter", "value")))
|
|
||||||
|
|
||||||
search_criteria = { "type": "material", "id": preferred_material_id, "approximate_diameter": approximate_material_diameter}
|
|
||||||
if machine_definition.getMetaDataEntry("has_machine_materials"):
|
|
||||||
search_criteria["definition"] = machine_definition_id
|
|
||||||
|
|
||||||
if machine_definition.getMetaDataEntry("has_variants") and variant:
|
|
||||||
search_criteria["variant"] = variant.id
|
|
||||||
else:
|
|
||||||
search_criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
preferred_materials = container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if len(preferred_materials) >= 1:
|
|
||||||
# In some cases we get multiple materials. In that case, prefer materials that are marked as read only.
|
|
||||||
read_only_preferred_materials = [preferred_material for preferred_material in preferred_materials if preferred_material.isReadOnly()]
|
|
||||||
if len(read_only_preferred_materials) >= 1:
|
|
||||||
material = read_only_preferred_materials[0]
|
|
||||||
else:
|
|
||||||
material = preferred_materials[0]
|
|
||||||
else:
|
|
||||||
Logger.log("w", "The preferred material \"%s\" of machine %s doesn't exist or is not a material profile.", preferred_material_id, machine_id)
|
|
||||||
# And leave it at the default material.
|
|
||||||
container_stack.addContainer(material)
|
|
||||||
|
|
||||||
# Find a quality to use for this extruder.
|
|
||||||
quality = container_registry.getEmptyInstanceContainer()
|
|
||||||
|
|
||||||
search_criteria = { "type": "quality" }
|
|
||||||
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
|
||||||
search_criteria["definition"] = machine_definition_id
|
|
||||||
if machine_definition.getMetaDataEntry("has_materials") and material:
|
|
||||||
search_criteria["material"] = material.id
|
|
||||||
else:
|
|
||||||
search_criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
preferred_quality = machine_definition.getMetaDataEntry("preferred_quality")
|
|
||||||
if preferred_quality:
|
|
||||||
search_criteria["id"] = preferred_quality
|
|
||||||
|
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
|
||||||
if not containers and preferred_quality:
|
|
||||||
Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality, machine_id)
|
|
||||||
search_criteria.pop("id", None)
|
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
|
||||||
if containers:
|
|
||||||
quality = containers[0]
|
|
||||||
|
|
||||||
container_stack.addContainer(quality)
|
|
||||||
|
|
||||||
empty_quality_changes = container_registry.findInstanceContainers(id = "empty_quality_changes")[0]
|
|
||||||
container_stack.addContainer(empty_quality_changes)
|
|
||||||
|
|
||||||
user_profile = container_registry.findInstanceContainers(type = "user", extruder = extruder_stack_id)
|
|
||||||
if user_profile: # There was already a user profile, loaded from settings.
|
|
||||||
user_profile = user_profile[0]
|
|
||||||
else:
|
|
||||||
user_profile = InstanceContainer(extruder_stack_id + "_current_settings") # Add an empty user profile.
|
|
||||||
user_profile.addMetaDataEntry("type", "user")
|
|
||||||
user_profile.addMetaDataEntry("extruder", extruder_stack_id)
|
|
||||||
from cura.CuraApplication import CuraApplication
|
|
||||||
user_profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
|
||||||
user_profile.setDefinition(machine_definition)
|
|
||||||
container_registry.addContainer(user_profile)
|
|
||||||
container_stack.addContainer(user_profile)
|
|
||||||
|
|
||||||
# regardless of what the next stack is, we have to set it again, because of signal routing.
|
|
||||||
container_stack.setNextStack(Application.getInstance().getGlobalContainerStack())
|
|
||||||
|
|
||||||
container_registry.addContainer(container_stack)
|
|
||||||
|
|
||||||
def getAllExtruderValues(self, setting_key):
|
def getAllExtruderValues(self, setting_key):
|
||||||
return self.getAllExtruderSettings(setting_key, "value")
|
return self.getAllExtruderSettings(setting_key, "value")
|
||||||
|
|
||||||
|
@ -396,16 +234,12 @@ class ExtruderManager(QObject):
|
||||||
# \param setting_key \type{str} The setting to get the property of.
|
# \param setting_key \type{str} The setting to get the property of.
|
||||||
# \param property \type{str} The property to get.
|
# \param property \type{str} The property to get.
|
||||||
# \return \type{List} the list of results
|
# \return \type{List} the list of results
|
||||||
def getAllExtruderSettings(self, setting_key, property):
|
def getAllExtruderSettings(self, setting_key: str, prop: str):
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
|
||||||
if global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
|
|
||||||
return [global_container_stack.getProperty(setting_key, property)]
|
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for index in self.extruderIds:
|
for index in self.extruderIds:
|
||||||
extruder_stack_id = self.extruderIds[str(index)]
|
extruder_stack_id = self.extruderIds[str(index)]
|
||||||
stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = extruder_stack_id)[0]
|
||||||
result.append(stack.getProperty(setting_key, property))
|
result.append(extruder_stack.getProperty(setting_key, prop))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
## Gets the extruder stacks that are actually being used at the moment.
|
## Gets the extruder stacks that are actually being used at the moment.
|
||||||
|
@ -422,20 +256,25 @@ class ExtruderManager(QObject):
|
||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
container_registry = ContainerRegistry.getInstance()
|
container_registry = ContainerRegistry.getInstance()
|
||||||
|
|
||||||
if global_stack.getProperty("machine_extruder_count", "value") <= 1: #For single extrusion.
|
|
||||||
return [global_stack]
|
|
||||||
|
|
||||||
used_extruder_stack_ids = set()
|
used_extruder_stack_ids = set()
|
||||||
|
|
||||||
#Get the extruders of all meshes in the scene.
|
# Get the extruders of all meshes in the scene
|
||||||
support_enabled = False
|
support_enabled = False
|
||||||
support_bottom_enabled = False
|
support_bottom_enabled = False
|
||||||
support_roof_enabled = False
|
support_roof_enabled = False
|
||||||
|
|
||||||
scene_root = Application.getInstance().getController().getScene().getRoot()
|
scene_root = Application.getInstance().getController().getScene().getRoot()
|
||||||
meshes = [node for node in DepthFirstIterator(scene_root) if type(node) is SceneNode and node.isSelectable()] #Only use the nodes that will be printed.
|
|
||||||
|
# If no extruders are registered in the extruder manager yet, return an empty array
|
||||||
|
if len(self.extruderIds) == 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Get the extruders of all printable meshes in the scene
|
||||||
|
meshes = [node for node in DepthFirstIterator(scene_root) if type(node) is SceneNode and node.isSelectable()]
|
||||||
for mesh in meshes:
|
for mesh in meshes:
|
||||||
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
|
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
|
||||||
if not extruder_stack_id: #No per-object settings for this node.
|
if not extruder_stack_id:
|
||||||
|
# No per-object settings for this node
|
||||||
extruder_stack_id = self.extruderIds["0"]
|
extruder_stack_id = self.extruderIds["0"]
|
||||||
used_extruder_stack_ids.add(extruder_stack_id)
|
used_extruder_stack_ids.add(extruder_stack_id)
|
||||||
|
|
||||||
|
@ -471,9 +310,10 @@ class ExtruderManager(QObject):
|
||||||
if support_roof_enabled:
|
if support_roof_enabled:
|
||||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_roof_extruder_nr", "value"))])
|
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_roof_extruder_nr", "value"))])
|
||||||
|
|
||||||
#The platform adhesion extruder. Not used if using none.
|
# The platform adhesion extruder. Not used if using none.
|
||||||
if global_stack.getProperty("adhesion_type", "value") != "none":
|
if global_stack.getProperty("adhesion_type", "value") != "none":
|
||||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))])
|
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
||||||
except IndexError: # One or more of the extruders was not found.
|
except IndexError: # One or more of the extruders was not found.
|
||||||
|
@ -520,10 +360,6 @@ class ExtruderManager(QObject):
|
||||||
result = []
|
result = []
|
||||||
machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value")
|
machine_extruder_count = global_stack.getProperty("machine_extruder_count", "value")
|
||||||
|
|
||||||
# In case the printer is using one extruder, shouldn't exist active extruder stacks
|
|
||||||
if machine_extruder_count == 1:
|
|
||||||
return result
|
|
||||||
|
|
||||||
if global_stack and global_stack.getId() in self._extruder_trains:
|
if global_stack and global_stack.getId() in self._extruder_trains:
|
||||||
for extruder in sorted(self._extruder_trains[global_stack.getId()]):
|
for extruder in sorted(self._extruder_trains[global_stack.getId()]):
|
||||||
result.append(self._extruder_trains[global_stack.getId()][extruder])
|
result.append(self._extruder_trains[global_stack.getId()][extruder])
|
||||||
|
@ -536,24 +372,39 @@ class ExtruderManager(QObject):
|
||||||
self._global_container_stack_definition_id = global_container_stack.getBottom().getId()
|
self._global_container_stack_definition_id = global_container_stack.getBottom().getId()
|
||||||
self.globalContainerStackDefinitionChanged.emit()
|
self.globalContainerStackDefinitionChanged.emit()
|
||||||
|
|
||||||
# If the global container changed, the number of extruders could be changed and so the active_extruder_index is updated
|
# If the global container changed, the machine changed and might have extruders that were not registered yet
|
||||||
extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
|
self._addCurrentMachineExtruders()
|
||||||
if extruder_count > 1:
|
|
||||||
if self._active_extruder_index == -1:
|
|
||||||
self.setActiveExtruderIndex(0)
|
|
||||||
else:
|
|
||||||
if self._active_extruder_index != -1:
|
|
||||||
self.setActiveExtruderIndex(-1)
|
|
||||||
|
|
||||||
self.activeExtruderChanged.emit()
|
|
||||||
|
|
||||||
self.resetSelectedObjectExtruders()
|
self.resetSelectedObjectExtruders()
|
||||||
|
|
||||||
## Adds the extruders of the currently active machine.
|
## Adds the extruders of the currently active machine.
|
||||||
def _addCurrentMachineExtruders(self) -> None:
|
def _addCurrentMachineExtruders(self) -> None:
|
||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_stack and global_stack.getBottom():
|
extruders_changed = False
|
||||||
self.addMachineExtruders(global_stack.getBottom(), global_stack.getId())
|
|
||||||
|
if global_stack:
|
||||||
|
container_registry = ContainerRegistry.getInstance()
|
||||||
|
global_stack_id = global_stack.getId()
|
||||||
|
|
||||||
|
# Gets the extruder trains that we just created as well as any that still existed.
|
||||||
|
extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = global_stack_id)
|
||||||
|
|
||||||
|
# Make sure the extruder trains for the new machine can be placed in the set of sets
|
||||||
|
if global_stack_id not in self._extruder_trains:
|
||||||
|
self._extruder_trains[global_stack_id] = {}
|
||||||
|
extruders_changed = True
|
||||||
|
|
||||||
|
# Register the extruder trains by position
|
||||||
|
for extruder_train in extruder_trains:
|
||||||
|
self._extruder_trains[global_stack_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
||||||
|
|
||||||
|
# regardless of what the next stack is, we have to set it again, because of signal routing. ???
|
||||||
|
extruder_train.setNextStack(global_stack)
|
||||||
|
extruders_changed = True
|
||||||
|
|
||||||
|
if extruders_changed:
|
||||||
|
self.extrudersChanged.emit(global_stack_id)
|
||||||
|
self.setActiveExtruderIndex(0)
|
||||||
|
|
||||||
## Get all extruder values for a certain setting.
|
## Get all extruder values for a certain setting.
|
||||||
#
|
#
|
||||||
|
@ -632,7 +483,7 @@ class ExtruderManager(QObject):
|
||||||
#
|
#
|
||||||
# This is exposed to qml for display purposes
|
# This is exposed to qml for display purposes
|
||||||
#
|
#
|
||||||
# \param key The key of the setting to retieve values for.
|
# \param key The key of the setting to retrieve values for.
|
||||||
#
|
#
|
||||||
# \return String representing the extruder values
|
# \return String representing the extruder values
|
||||||
@pyqtSlot(str, result="QVariant")
|
@pyqtSlot(str, result="QVariant")
|
||||||
|
@ -656,7 +507,8 @@ class ExtruderManager(QObject):
|
||||||
value = extruder.getRawProperty(key, "value")
|
value = extruder.getRawProperty(key, "value")
|
||||||
if isinstance(value, SettingFunction):
|
if isinstance(value, SettingFunction):
|
||||||
value = value(extruder)
|
value = value(extruder)
|
||||||
else: #Just a value from global.
|
else:
|
||||||
|
# Just a value from global.
|
||||||
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -115,6 +115,11 @@ class ExtruderStack(CuraContainerStack):
|
||||||
if has_global_dependencies:
|
if has_global_dependencies:
|
||||||
self.getNextStack().propertiesChanged.emit(key, properties)
|
self.getNextStack().propertiesChanged.emit(key, properties)
|
||||||
|
|
||||||
|
def findDefaultVariant(self):
|
||||||
|
# The default variant is defined in the machine stack and/or definition, so use the machine stack to find
|
||||||
|
# the default variant.
|
||||||
|
return self.getNextStack().findDefaultVariant()
|
||||||
|
|
||||||
|
|
||||||
extruder_stack_mime = MimeType(
|
extruder_stack_mime = MimeType(
|
||||||
name = "application/x-cura-extruderstack",
|
name = "application/x-cura-extruderstack",
|
||||||
|
|
|
@ -71,13 +71,13 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
self._add_global = False
|
self._add_global = False
|
||||||
self._simple_names = False
|
self._simple_names = False
|
||||||
|
|
||||||
self._active_machine_extruders = [] # type: Iterable[ExtruderStack]
|
self._active_machine_extruders = [] # type: Iterable[ExtruderStack]
|
||||||
self._add_optional_extruder = False
|
self._add_optional_extruder = False
|
||||||
|
|
||||||
#Listen to changes.
|
# Listen to changes
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._extrudersChanged) #When the machine is swapped we must update the active machine extruders.
|
Application.getInstance().globalContainerStackChanged.connect(self._extrudersChanged) # When the machine is swapped we must update the active machine extruders
|
||||||
ExtruderManager.getInstance().extrudersChanged.connect(self._extrudersChanged) #When the extruders change we must link to the stack-changed signal of the new extruder.
|
ExtruderManager.getInstance().extrudersChanged.connect(self._extrudersChanged) # When the extruders change we must link to the stack-changed signal of the new extruder
|
||||||
self._extrudersChanged() #Also calls _updateExtruders.
|
self._extrudersChanged() # Also calls _updateExtruders
|
||||||
|
|
||||||
def setAddGlobal(self, add):
|
def setAddGlobal(self, add):
|
||||||
if add != self._add_global:
|
if add != self._add_global:
|
||||||
|
@ -128,21 +128,24 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
def _extrudersChanged(self, machine_id = None):
|
def _extrudersChanged(self, machine_id = None):
|
||||||
if machine_id is not None:
|
if machine_id is not None:
|
||||||
if Application.getInstance().getGlobalContainerStack() is None:
|
if Application.getInstance().getGlobalContainerStack() is None:
|
||||||
return #No machine, don't need to update the current machine's extruders.
|
# No machine, don't need to update the current machine's extruders
|
||||||
|
return
|
||||||
if machine_id != Application.getInstance().getGlobalContainerStack().getId():
|
if machine_id != Application.getInstance().getGlobalContainerStack().getId():
|
||||||
return #Not the current machine.
|
# Not the current machine
|
||||||
#Unlink from old extruders.
|
return
|
||||||
|
|
||||||
|
# Unlink from old extruders
|
||||||
for extruder in self._active_machine_extruders:
|
for extruder in self._active_machine_extruders:
|
||||||
extruder.containersChanged.disconnect(self._onExtruderStackContainersChanged)
|
extruder.containersChanged.disconnect(self._onExtruderStackContainersChanged)
|
||||||
|
|
||||||
#Link to new extruders.
|
# Link to new extruders
|
||||||
self._active_machine_extruders = []
|
self._active_machine_extruders = []
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
extruder_manager = ExtruderManager.getInstance()
|
||||||
for extruder in extruder_manager.getExtruderStacks():
|
for extruder in extruder_manager.getExtruderStacks():
|
||||||
extruder.containersChanged.connect(self._onExtruderStackContainersChanged)
|
extruder.containersChanged.connect(self._onExtruderStackContainersChanged)
|
||||||
self._active_machine_extruders.append(extruder)
|
self._active_machine_extruders.append(extruder)
|
||||||
|
|
||||||
self._updateExtruders() #Since the new extruders may have different properties, update our own model.
|
self._updateExtruders() # Since the new extruders may have different properties, update our own model.
|
||||||
|
|
||||||
def _onExtruderStackContainersChanged(self, container):
|
def _onExtruderStackContainersChanged(self, container):
|
||||||
# Update when there is an empty container or material change
|
# Update when there is an empty container or material change
|
||||||
|
@ -150,7 +153,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
|
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
|
||||||
self._updateExtruders()
|
self._updateExtruders()
|
||||||
|
|
||||||
|
|
||||||
modelChanged = pyqtSignal()
|
modelChanged = pyqtSignal()
|
||||||
|
|
||||||
def _updateExtruders(self):
|
def _updateExtruders(self):
|
||||||
|
@ -161,14 +163,17 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
# This should be called whenever the list of extruders changes.
|
# This should be called whenever the list of extruders changes.
|
||||||
@UM.FlameProfiler.profile
|
@UM.FlameProfiler.profile
|
||||||
def __updateExtruders(self):
|
def __updateExtruders(self):
|
||||||
changed = False
|
extruders_changed = False
|
||||||
|
|
||||||
if self.rowCount() != 0:
|
if self.rowCount() != 0:
|
||||||
changed = True
|
extruders_changed = True
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
|
|
||||||
|
# TODO: remove this - CURA-4482
|
||||||
if self._add_global:
|
if self._add_global:
|
||||||
material = global_container_stack.material
|
material = global_container_stack.material
|
||||||
color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0]
|
color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0]
|
||||||
|
@ -180,40 +185,44 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
"definition": ""
|
"definition": ""
|
||||||
}
|
}
|
||||||
items.append(item)
|
items.append(item)
|
||||||
changed = True
|
extruders_changed = True
|
||||||
|
|
||||||
|
# get machine extruder count for verification
|
||||||
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
|
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
|
||||||
manager = ExtruderManager.getInstance()
|
|
||||||
for extruder in manager.getMachineExtruders(global_container_stack.getId()):
|
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()):
|
||||||
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
|
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
|
||||||
try:
|
try:
|
||||||
position = int(position)
|
position = int(position)
|
||||||
except ValueError: #Not a proper int.
|
except ValueError:
|
||||||
|
# Not a proper int.
|
||||||
position = -1
|
position = -1
|
||||||
if position >= machine_extruder_count:
|
if position >= machine_extruder_count:
|
||||||
continue
|
continue
|
||||||
extruder_name = extruder.getName()
|
|
||||||
material = extruder.material
|
|
||||||
variant = extruder.variant
|
|
||||||
|
|
||||||
default_color = self.defaultColors[position] if position >= 0 and position < len(self.defaultColors) else self.defaultColors[0]
|
default_color = self.defaultColors[position] if 0 <= position < len(self.defaultColors) else self.defaultColors[0]
|
||||||
color = material.getMetaDataEntry("color_code", default = default_color) if material else default_color
|
color = extruder.material.getMetaDataEntry("color_code", default = default_color) if extruder.material else default_color
|
||||||
item = { #Construct an item with only the relevant information.
|
|
||||||
|
# construct an item with only the relevant information
|
||||||
|
item = {
|
||||||
"id": extruder.getId(),
|
"id": extruder.getId(),
|
||||||
"name": extruder_name,
|
"name": extruder.getName(),
|
||||||
"color": color,
|
"color": color,
|
||||||
"index": position,
|
"index": position,
|
||||||
"definition": extruder.getBottom().getId(),
|
"definition": extruder.getBottom().getId(),
|
||||||
"material": material.getName() if material else "",
|
"material": extruder.material.getName() if extruder.material else "",
|
||||||
"variant": variant.getName() if variant else "",
|
"variant": extruder.variant.getName() if extruder.variant else "", # e.g. print core
|
||||||
}
|
}
|
||||||
items.append(item)
|
|
||||||
changed = True
|
|
||||||
|
|
||||||
if changed:
|
items.append(item)
|
||||||
|
extruders_changed = True
|
||||||
|
|
||||||
|
if extruders_changed:
|
||||||
|
# sort by extruder index
|
||||||
items.sort(key = lambda i: i["index"])
|
items.sort(key = lambda i: i["index"])
|
||||||
|
|
||||||
# We need optional extruder to be last, so add it after we do sorting.
|
# We need optional extruder to be last, so add it after we do sorting.
|
||||||
# This way we can simply intrepret the -1 of the index as the last item (which it now always is)
|
# This way we can simply interpret the -1 of the index as the last item (which it now always is)
|
||||||
if self._add_optional_extruder:
|
if self._add_optional_extruder:
|
||||||
item = {
|
item = {
|
||||||
"id": "",
|
"id": "",
|
||||||
|
@ -223,5 +232,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||||
"definition": ""
|
"definition": ""
|
||||||
}
|
}
|
||||||
items.append(item)
|
items.append(item)
|
||||||
|
|
||||||
self.setItems(items)
|
self.setItems(items)
|
||||||
self.modelChanged.emit()
|
self.modelChanged.emit()
|
||||||
|
|
|
@ -23,9 +23,9 @@ class GlobalStack(CuraContainerStack):
|
||||||
def __init__(self, container_id: str, *args, **kwargs):
|
def __init__(self, container_id: str, *args, **kwargs):
|
||||||
super().__init__(container_id, *args, **kwargs)
|
super().__init__(container_id, *args, **kwargs)
|
||||||
|
|
||||||
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
||||||
|
|
||||||
self._extruders = {}
|
self._extruders = {} # type: Dict[str, "ExtruderStack"]
|
||||||
|
|
||||||
# This property is used to track which settings we are calculating the "resolve" for
|
# This property is used to track which settings we are calculating the "resolve" for
|
||||||
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
||||||
|
@ -61,13 +61,6 @@ class GlobalStack(CuraContainerStack):
|
||||||
# \throws Exceptions.TooManyExtrudersError Raised when trying to add an extruder while we
|
# \throws Exceptions.TooManyExtrudersError Raised when trying to add an extruder while we
|
||||||
# already have the maximum number of extruders.
|
# already have the maximum number of extruders.
|
||||||
def addExtruder(self, extruder: ContainerStack) -> None:
|
def addExtruder(self, extruder: ContainerStack) -> None:
|
||||||
extruder_count = self.getProperty("machine_extruder_count", "value")
|
|
||||||
|
|
||||||
if extruder_count <= 1:
|
|
||||||
Logger.log("i", "Not adding extruder[%s] to [%s] because it is a single-extrusion machine.",
|
|
||||||
extruder.id, self.id)
|
|
||||||
return
|
|
||||||
|
|
||||||
position = extruder.getMetaDataEntry("position")
|
position = extruder.getMetaDataEntry("position")
|
||||||
if position is None:
|
if position is None:
|
||||||
Logger.log("w", "No position defined for extruder {extruder}, cannot add it to stack {stack}", extruder = extruder.id, stack = self.id)
|
Logger.log("w", "No position defined for extruder {extruder}, cannot add it to stack {stack}", extruder = extruder.id, stack = self.id)
|
||||||
|
|
|
@ -107,9 +107,8 @@ class MachineManager(QObject):
|
||||||
if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacks(id = active_machine_id):
|
if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacks(id = active_machine_id):
|
||||||
# An active machine was saved, so restore it.
|
# An active machine was saved, so restore it.
|
||||||
self.setActiveMachine(active_machine_id)
|
self.setActiveMachine(active_machine_id)
|
||||||
if self._global_container_stack and self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
# Make sure _active_container_stack is properly initiated
|
||||||
# Make sure _active_container_stack is properly initiated
|
ExtruderManager.getInstance().setActiveExtruderIndex(0)
|
||||||
ExtruderManager.getInstance().setActiveExtruderIndex(0)
|
|
||||||
|
|
||||||
self._auto_materials_changed = {}
|
self._auto_materials_changed = {}
|
||||||
self._auto_hotends_changed = {}
|
self._auto_hotends_changed = {}
|
||||||
|
@ -162,7 +161,7 @@ class MachineManager(QObject):
|
||||||
|
|
||||||
@pyqtProperty(int, constant=True)
|
@pyqtProperty(int, constant=True)
|
||||||
def totalNumberOfSettings(self) -> int:
|
def totalNumberOfSettings(self) -> int:
|
||||||
return len(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0].getAllKeys())
|
return len(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0].getAllKeys())
|
||||||
|
|
||||||
def _onHotendIdChanged(self, index: Union[str, int], hotend_id: str) -> None:
|
def _onHotendIdChanged(self, index: Union[str, int], hotend_id: str) -> None:
|
||||||
if not self._global_container_stack:
|
if not self._global_container_stack:
|
||||||
|
@ -258,13 +257,13 @@ class MachineManager(QObject):
|
||||||
|
|
||||||
if old_index is not None:
|
if old_index is not None:
|
||||||
extruder_manager.setActiveExtruderIndex(old_index)
|
extruder_manager.setActiveExtruderIndex(old_index)
|
||||||
self._auto_hotends_changed = {} #Processed all of them now.
|
self._auto_hotends_changed = {} # Processed all of them now.
|
||||||
|
|
||||||
def _onGlobalContainerChanged(self):
|
def _onGlobalContainerChanged(self):
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
try:
|
try:
|
||||||
self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged)
|
self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged)
|
||||||
except TypeError: #pyQtSignal gives a TypeError when disconnecting from something that was already disconnected.
|
except TypeError: # pyQtSignal gives a TypeError when disconnecting from something that was already disconnected.
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
||||||
|
@ -274,52 +273,38 @@ class MachineManager(QObject):
|
||||||
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
material = self._global_container_stack.material
|
|
||||||
material.nameChanged.disconnect(self._onMaterialNameChanged)
|
|
||||||
|
|
||||||
quality = self._global_container_stack.quality
|
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
quality.nameChanged.disconnect(self._onQualityNameChanged)
|
extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
||||||
|
extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
||||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
|
||||||
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
|
||||||
extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
|
||||||
extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
|
||||||
|
|
||||||
|
# update the local global container stack reference
|
||||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
|
||||||
self.globalContainerChanged.emit()
|
self.globalContainerChanged.emit()
|
||||||
|
|
||||||
|
# after switching the global stack we reconnect all the signals and set the variant and material references
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId())
|
Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId())
|
||||||
|
|
||||||
self._global_container_stack.nameChanged.connect(self._onMachineNameChanged)
|
self._global_container_stack.nameChanged.connect(self._onMachineNameChanged)
|
||||||
self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
||||||
self._global_container_stack.propertyChanged.connect(self._onPropertyChanged)
|
self._global_container_stack.propertyChanged.connect(self._onPropertyChanged)
|
||||||
|
|
||||||
if self._global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
# set the global variant to empty as we now use the extruder stack at all times - CURA-4482
|
||||||
# For multi-extrusion machines, we do not want variant or material profiles in the stack,
|
global_variant = self._global_container_stack.variant
|
||||||
# because these are extruder specific and may cause wrong values to be used for extruders
|
if global_variant != self._empty_variant_container:
|
||||||
# that did not specify a value in the extruder.
|
self._global_container_stack.setVariant(self._empty_variant_container)
|
||||||
global_variant = self._global_container_stack.variant
|
|
||||||
if global_variant != self._empty_variant_container:
|
|
||||||
self._global_container_stack.setVariant(self._empty_variant_container)
|
|
||||||
|
|
||||||
global_material = self._global_container_stack.material
|
# set the global material to empty as we now use the extruder stack at all times - CURA-4482
|
||||||
if global_material != self._empty_material_container:
|
global_material = self._global_container_stack.material
|
||||||
self._global_container_stack.setMaterial(self._empty_material_container)
|
if global_material != self._empty_material_container:
|
||||||
|
self._global_container_stack.setMaterial(self._empty_material_container)
|
||||||
|
|
||||||
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks(): #Listen for changes on all extruder stacks.
|
# Listen for changes on all extruder stacks
|
||||||
extruder_stack.propertyChanged.connect(self._onPropertyChanged)
|
for extruder_stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
extruder_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
extruder_stack.propertyChanged.connect(self._onPropertyChanged)
|
||||||
|
extruder_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
||||||
else:
|
|
||||||
material = self._global_container_stack.material
|
|
||||||
material.nameChanged.connect(self._onMaterialNameChanged)
|
|
||||||
|
|
||||||
quality = self._global_container_stack.quality
|
|
||||||
quality.nameChanged.connect(self._onQualityNameChanged)
|
|
||||||
|
|
||||||
self._active_container_stack = self._global_container_stack
|
|
||||||
self.activeStackChanged.emit()
|
|
||||||
|
|
||||||
self._error_check_timer.start()
|
self._error_check_timer.start()
|
||||||
|
|
||||||
|
@ -336,8 +321,6 @@ class MachineManager(QObject):
|
||||||
old_active_container_stack = self._active_container_stack
|
old_active_container_stack = self._active_container_stack
|
||||||
|
|
||||||
self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||||
if not self._active_container_stack:
|
|
||||||
self._active_container_stack = self._global_container_stack
|
|
||||||
|
|
||||||
self._error_check_timer.start()
|
self._error_check_timer.start()
|
||||||
|
|
||||||
|
@ -384,15 +367,6 @@ class MachineManager(QObject):
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "Failed creating a new machine!")
|
Logger.log("w", "Failed creating a new machine!")
|
||||||
|
|
||||||
## Create a name that is not empty and unique
|
|
||||||
# \param container_type \type{string} Type of the container (machine, quality, ...)
|
|
||||||
# \param current_name \type{} Current name of the container, which may be an acceptable option
|
|
||||||
# \param new_name \type{string} Base name, which may not be unique
|
|
||||||
# \param fallback_name \type{string} Name to use when (stripped) new_name is empty
|
|
||||||
# \return \type{string} Name that is unique for the specified type and name/id
|
|
||||||
def _createUniqueName(self, container_type: str, current_name: str, new_name: str, fallback_name: str) -> str:
|
|
||||||
return ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
|
|
||||||
|
|
||||||
def _checkStacksHaveErrors(self) -> bool:
|
def _checkStacksHaveErrors(self) -> bool:
|
||||||
if self._global_container_stack is None: #No active machine.
|
if self._global_container_stack is None: #No active machine.
|
||||||
return False
|
return False
|
||||||
|
@ -732,15 +706,13 @@ class MachineManager(QObject):
|
||||||
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
|
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def copyValueToExtruders(self, key: str):
|
def copyValueToExtruders(self, key: str):
|
||||||
if not self._active_container_stack or self._global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
new_value = self._active_container_stack.getProperty(key, "value")
|
new_value = self._active_container_stack.getProperty(key, "value")
|
||||||
stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
|
extruder_stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
|
||||||
stacks.append(self._global_container_stack)
|
|
||||||
for extruder_stack in stacks:
|
# check in which stack the value has to be replaced
|
||||||
|
for extruder_stack in extruder_stacks:
|
||||||
if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value:
|
if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value:
|
||||||
extruder_stack.getTop().setProperty(key, "value", new_value)
|
extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved
|
||||||
|
|
||||||
## Set the active material by switching out a container
|
## Set the active material by switching out a container
|
||||||
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
||||||
|
@ -947,35 +919,46 @@ class MachineManager(QObject):
|
||||||
global_container_stack = self._global_container_stack
|
global_container_stack = self._global_container_stack
|
||||||
if not global_container_stack:
|
if not global_container_stack:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
||||||
|
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
if extruder_stacks:
|
|
||||||
stacks = extruder_stacks
|
|
||||||
else:
|
|
||||||
stacks = [global_container_stack]
|
|
||||||
|
|
||||||
for stack in stacks:
|
# find qualities for extruders
|
||||||
material = stack.material
|
for extruder_stack in extruder_stacks:
|
||||||
|
material = extruder_stack.material
|
||||||
|
|
||||||
# TODO: fix this
|
# TODO: fix this
|
||||||
if self._new_material_container and stack.getId() == self._active_container_stack.getId():
|
if self._new_material_container and extruder_stack.getId() == self._active_container_stack.getId():
|
||||||
material = self._new_material_container
|
material = self._new_material_container
|
||||||
|
|
||||||
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
||||||
|
|
||||||
if not quality:
|
if not quality:
|
||||||
# No quality profile is found for this quality type.
|
# No quality profile is found for this quality type.
|
||||||
quality = self._empty_quality_container
|
quality = self._empty_quality_container
|
||||||
result.append({"stack": stack, "quality": quality, "quality_changes": empty_quality_changes})
|
|
||||||
|
|
||||||
if extruder_stacks:
|
result.append({
|
||||||
# Add an extra entry for the global stack.
|
"stack": extruder_stack,
|
||||||
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = "True")
|
"quality": quality,
|
||||||
|
"quality_changes": empty_quality_changes
|
||||||
|
})
|
||||||
|
|
||||||
if not global_quality:
|
# also find a global quality for the machine
|
||||||
global_quality = self._empty_quality_container
|
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = "True")
|
||||||
|
|
||||||
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": empty_quality_changes})
|
# if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482
|
||||||
|
if not global_quality and len(extruder_stacks) == 1:
|
||||||
|
global_quality = result[0]["quality"]
|
||||||
|
|
||||||
|
# if there is still no global quality, set it to empty (not supported)
|
||||||
|
if not global_quality:
|
||||||
|
global_quality = self._empty_quality_container
|
||||||
|
|
||||||
|
result.append({
|
||||||
|
"stack": global_container_stack,
|
||||||
|
"quality": global_quality,
|
||||||
|
"quality_changes": empty_quality_changes
|
||||||
|
})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -988,10 +971,8 @@ class MachineManager(QObject):
|
||||||
quality_manager = QualityManager.getInstance()
|
quality_manager = QualityManager.getInstance()
|
||||||
|
|
||||||
global_container_stack = self._global_container_stack
|
global_container_stack = self._global_container_stack
|
||||||
global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
|
||||||
|
quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, global_machine_definition)
|
||||||
quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name,
|
|
||||||
global_machine_definition)
|
|
||||||
|
|
||||||
global_quality_changes = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") is None]
|
global_quality_changes = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") is None]
|
||||||
if global_quality_changes:
|
if global_quality_changes:
|
||||||
|
@ -1002,27 +983,22 @@ class MachineManager(QObject):
|
||||||
|
|
||||||
material = global_container_stack.material
|
material = global_container_stack.material
|
||||||
|
|
||||||
|
# find a quality type that matches both machine and materials
|
||||||
if self._new_material_container and self._active_container_stack.getId() == global_container_stack.getId():
|
if self._new_material_container and self._active_container_stack.getId() == global_container_stack.getId():
|
||||||
material = self._new_material_container
|
material = self._new_material_container
|
||||||
|
|
||||||
# For the global stack, find a quality which matches the quality_type in
|
# For the global stack, find a quality which matches the quality_type in
|
||||||
# the quality changes profile and also satisfies any material constraints.
|
# the quality changes profile and also satisfies any material constraints.
|
||||||
quality_type = global_quality_changes.getMetaDataEntry("quality_type")
|
quality_type = global_quality_changes.getMetaDataEntry("quality_type")
|
||||||
if global_container_stack.getProperty("machine_extruder_count", "value") > 1:
|
|
||||||
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = True)
|
|
||||||
else:
|
|
||||||
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
|
||||||
if not global_quality:
|
|
||||||
global_quality = self._empty_quality_container
|
|
||||||
|
|
||||||
# Find the values for each extruder.
|
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
|
|
||||||
for stack in extruder_stacks:
|
# append the extruder quality changes
|
||||||
extruder_definition = quality_manager.getParentMachineDefinition(stack.getBottom())
|
for extruder_stack in extruder_stacks:
|
||||||
|
extruder_definition = quality_manager.getParentMachineDefinition(extruder_stack.definition)
|
||||||
|
|
||||||
|
quality_changes_list = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") == extruder_definition.getId()]
|
||||||
|
|
||||||
quality_changes_list = [qcp for qcp in quality_changes_profiles
|
|
||||||
if qcp.getMetaDataEntry("extruder") == extruder_definition.getId()]
|
|
||||||
if quality_changes_list:
|
if quality_changes_list:
|
||||||
quality_changes = quality_changes_list[0]
|
quality_changes = quality_changes_list[0]
|
||||||
else:
|
else:
|
||||||
|
@ -1030,24 +1006,39 @@ class MachineManager(QObject):
|
||||||
if not quality_changes:
|
if not quality_changes:
|
||||||
quality_changes = self._empty_quality_changes_container
|
quality_changes = self._empty_quality_changes_container
|
||||||
|
|
||||||
material = stack.material
|
material = extruder_stack.material
|
||||||
|
|
||||||
if self._new_material_container and self._active_container_stack.getId() == stack.getId():
|
if self._new_material_container and self._active_container_stack.getId() == extruder_stack.getId():
|
||||||
material = self._new_material_container
|
material = self._new_material_container
|
||||||
|
|
||||||
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
||||||
if not quality: #No quality profile found for this quality type.
|
|
||||||
|
if not quality:
|
||||||
|
# No quality profile found for this quality type.
|
||||||
quality = self._empty_quality_container
|
quality = self._empty_quality_container
|
||||||
|
|
||||||
result.append({"stack": stack, "quality": quality, "quality_changes": quality_changes})
|
result.append({
|
||||||
|
"stack": extruder_stack,
|
||||||
|
"quality": quality,
|
||||||
|
"quality_changes": quality_changes
|
||||||
|
})
|
||||||
|
|
||||||
if extruder_stacks:
|
# append the global quality changes
|
||||||
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material], global_quality = "True")
|
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material], global_quality = "True")
|
||||||
if not global_quality:
|
|
||||||
global_quality = self._empty_quality_container
|
# if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482
|
||||||
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes})
|
if not global_quality and len(extruder_stacks) == 1:
|
||||||
else:
|
global_quality = result[0]["quality"]
|
||||||
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes})
|
|
||||||
|
# if still no global quality changes are found we set it to empty (not supported)
|
||||||
|
if not global_quality:
|
||||||
|
global_quality = self._empty_quality_container
|
||||||
|
|
||||||
|
result.append({
|
||||||
|
"stack": global_container_stack,
|
||||||
|
"quality": global_quality,
|
||||||
|
"quality_changes": global_quality_changes
|
||||||
|
})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -1156,10 +1147,11 @@ class MachineManager(QObject):
|
||||||
|
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str)
|
||||||
def renameMachine(self, machine_id: str, new_name: str):
|
def renameMachine(self, machine_id: str, new_name: str):
|
||||||
containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
container_registry = ContainerRegistry.getInstance()
|
||||||
if containers:
|
machine_stack = container_registry.findContainerStacks(id = machine_id)
|
||||||
new_name = self._createUniqueName("machine", containers[0].getName(), new_name, containers[0].getBottom().getName())
|
if machine_stack:
|
||||||
containers[0].setName(new_name)
|
new_name = container_registry.createUniqueName("machine", machine_stack[0].getName(), new_name, machine_stack[0].getBottom().getName())
|
||||||
|
machine_stack[0].setName(new_name)
|
||||||
self.globalContainerChanged.emit()
|
self.globalContainerChanged.emit()
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
|
@ -1183,15 +1175,14 @@ class MachineManager(QObject):
|
||||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||||
def hasMaterials(self) -> bool:
|
def hasMaterials(self) -> bool:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return bool(self._global_container_stack.getMetaDataEntry("has_materials", False))
|
return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False))
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||||
def hasVariants(self) -> bool:
|
def hasVariants(self) -> bool:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return bool(self._global_container_stack.getMetaDataEntry("has_variants", False))
|
return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_variants", False))
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
## Property to indicate if a machine has "specialized" material profiles.
|
## Property to indicate if a machine has "specialized" material profiles.
|
||||||
|
@ -1199,8 +1190,7 @@ class MachineManager(QObject):
|
||||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||||
def filterMaterialsByMachine(self) -> bool:
|
def filterMaterialsByMachine(self) -> bool:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return bool(self._global_container_stack.getMetaDataEntry("has_machine_materials", False))
|
return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_machine_materials", False))
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
## Property to indicate if a machine has "specialized" quality profiles.
|
## Property to indicate if a machine has "specialized" quality profiles.
|
||||||
|
@ -1208,7 +1198,7 @@ class MachineManager(QObject):
|
||||||
@pyqtProperty(bool, notify = globalContainerChanged)
|
@pyqtProperty(bool, notify = globalContainerChanged)
|
||||||
def filterQualityByMachine(self) -> bool:
|
def filterQualityByMachine(self) -> bool:
|
||||||
if self._global_container_stack:
|
if self._global_container_stack:
|
||||||
return bool(self._global_container_stack.getMetaDataEntry("has_machine_quality", False))
|
return Util.parseBool(self._global_container_stack.getMetaDataEntry("has_machine_quality", False))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
## Get the Definition ID of a machine (specified by ID)
|
## Get the Definition ID of a machine (specified by ID)
|
||||||
|
@ -1221,7 +1211,7 @@ class MachineManager(QObject):
|
||||||
return containers[0].getBottom().getId()
|
return containers[0].getBottom().getId()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def createMachineManager(engine=None, script_engine=None):
|
def createMachineManager():
|
||||||
return MachineManager()
|
return MachineManager()
|
||||||
|
|
||||||
@deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7")
|
@deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7")
|
||||||
|
|
|
@ -12,6 +12,11 @@ from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
|
||||||
from cura.QualityManager import QualityManager
|
from cura.QualityManager import QualityManager
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
|
from typing import List, TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
|
||||||
|
|
||||||
## QML Model for listing the current list of valid quality profiles.
|
## QML Model for listing the current list of valid quality profiles.
|
||||||
#
|
#
|
||||||
|
@ -27,7 +32,6 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
self.addRoleName(self.AvailableRole, "available")
|
self.addRoleName(self.AvailableRole, "available")
|
||||||
|
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._update)
|
Application.getInstance().globalContainerStackChanged.connect(self._update)
|
||||||
|
|
||||||
Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update)
|
Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update)
|
||||||
Application.getInstance().getMachineManager().activeStackChanged.connect(self._update)
|
Application.getInstance().getMachineManager().activeStackChanged.connect(self._update)
|
||||||
Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update)
|
Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update)
|
||||||
|
@ -54,18 +58,12 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack is None:
|
if global_container_stack is None:
|
||||||
return []
|
return []
|
||||||
global_stack_definition = global_container_stack.getBottom()
|
|
||||||
|
global_stack_definition = global_container_stack.definition
|
||||||
|
|
||||||
# Get the list of extruders and place the selected extruder at the front of the list.
|
# Get the list of extruders and place the selected extruder at the front of the list.
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
extruder_stacks = self._getOrderedExtruderStacksList()
|
||||||
active_extruder = extruder_manager.getActiveExtruderStack()
|
materials = [extruder.material for extruder in extruder_stacks]
|
||||||
extruder_stacks = extruder_manager.getActiveExtruderStacks()
|
|
||||||
materials = [global_container_stack.material]
|
|
||||||
|
|
||||||
if active_extruder in extruder_stacks:
|
|
||||||
extruder_stacks.remove(active_extruder)
|
|
||||||
extruder_stacks = [active_extruder] + extruder_stacks
|
|
||||||
materials = [extruder.material for extruder in extruder_stacks]
|
|
||||||
|
|
||||||
# Fetch the list of usable qualities across all extruders.
|
# Fetch the list of usable qualities across all extruders.
|
||||||
# The actual list of quality profiles come from the first extruder in the extruder list.
|
# The actual list of quality profiles come from the first extruder in the extruder list.
|
||||||
|
@ -100,32 +98,12 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
if global_container_stack is None:
|
if global_container_stack is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Detecting if the machine has multiple extrusion
|
extruder_stacks = self._getOrderedExtruderStacksList()
|
||||||
multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
container_registry = ContainerRegistry.getInstance()
|
||||||
|
|
||||||
# Get the list of extruders and place the selected extruder at the front of the list.
|
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
|
||||||
active_extruder = extruder_manager.getActiveExtruderStack()
|
|
||||||
extruder_stacks = extruder_manager.getActiveExtruderStacks()
|
|
||||||
|
|
||||||
if multiple_extrusion:
|
|
||||||
# Place the active extruder at the front of the list.
|
|
||||||
# This is a workaround checking if there is an active_extruder or not before moving it to the front of the list.
|
|
||||||
# Actually, when a printer has multiple extruders, should exist always an active_extruder. However, in some
|
|
||||||
# cases the active_extruder is still None.
|
|
||||||
if active_extruder in extruder_stacks:
|
|
||||||
extruder_stacks.remove(active_extruder)
|
|
||||||
new_extruder_stacks = []
|
|
||||||
if active_extruder is not None:
|
|
||||||
new_extruder_stacks = [active_extruder]
|
|
||||||
extruder_stacks = new_extruder_stacks + extruder_stacks
|
|
||||||
|
|
||||||
# Get a list of usable/available qualities for this machine and material
|
# Get a list of usable/available qualities for this machine and material
|
||||||
qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
|
qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
|
||||||
|
|
||||||
container_registry = ContainerRegistry.getInstance()
|
|
||||||
machine_manager = Application.getInstance().getMachineManager()
|
|
||||||
|
|
||||||
unit = global_container_stack.getBottom().getProperty("layer_height", "unit")
|
unit = global_container_stack.getBottom().getProperty("layer_height", "unit")
|
||||||
if not unit:
|
if not unit:
|
||||||
unit = ""
|
unit = ""
|
||||||
|
@ -190,6 +168,8 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
yield item
|
yield item
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
machine_manager = Application.getInstance().getMachineManager()
|
||||||
|
|
||||||
# Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
|
# Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
|
||||||
quality_type = profile.getMetaDataEntry("quality_type", None)
|
quality_type = profile.getMetaDataEntry("quality_type", None)
|
||||||
if quality_type:
|
if quality_type:
|
||||||
|
@ -201,7 +181,8 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
else:
|
else:
|
||||||
# No global container stack in the results:
|
# No global container stack in the results:
|
||||||
if quality_results:
|
if quality_results:
|
||||||
quality = quality_results[0]["quality"] # Take any of the extruders.
|
# Take any of the extruders.
|
||||||
|
quality = quality_results[0]["quality"]
|
||||||
else:
|
else:
|
||||||
quality = None
|
quality = None
|
||||||
if quality and quality.hasProperty("layer_height", "value"):
|
if quality and quality.hasProperty("layer_height", "value"):
|
||||||
|
@ -211,13 +192,27 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
|
|
||||||
# Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
|
# Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
|
||||||
skip_until_container = global_container_stack.material
|
skip_until_container = global_container_stack.material
|
||||||
if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): #No material in stack.
|
if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No material in stack.
|
||||||
skip_until_container = global_container_stack.variant
|
skip_until_container = global_container_stack.variant
|
||||||
if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): #No variant in stack.
|
if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No variant in stack.
|
||||||
skip_until_container = global_container_stack.getBottom()
|
skip_until_container = global_container_stack.getBottom()
|
||||||
self._setItemLayerHeight(item, global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId()), unit) # Fall through to the currently loaded material.
|
self._setItemLayerHeight(item, global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId()), unit) # Fall through to the currently loaded material.
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
def _setItemLayerHeight(self, item, value, unit):
|
## Get a list of extruder stacks with the active extruder at the front of the list.
|
||||||
|
@staticmethod
|
||||||
|
def _getOrderedExtruderStacksList() -> List["ExtruderStack"]:
|
||||||
|
extruder_manager = ExtruderManager.getInstance()
|
||||||
|
extruder_stacks = extruder_manager.getActiveExtruderStacks()
|
||||||
|
active_extruder = extruder_manager.getActiveExtruderStack()
|
||||||
|
|
||||||
|
if active_extruder in extruder_stacks:
|
||||||
|
extruder_stacks.remove(active_extruder)
|
||||||
|
extruder_stacks = [active_extruder] + extruder_stacks
|
||||||
|
|
||||||
|
return extruder_stacks
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _setItemLayerHeight(item, value, unit):
|
||||||
item["layer_height"] = str(value) + unit
|
item["layer_height"] = str(value) + unit
|
||||||
item["layer_height_without_unit"] = str(value)
|
item["layer_height_without_unit"] = str(value)
|
||||||
|
|
|
@ -22,47 +22,23 @@ class QualityAndUserProfilesModel(ProfilesModel):
|
||||||
|
|
||||||
# Fetch the list of quality changes.
|
# Fetch the list of quality changes.
|
||||||
quality_manager = QualityManager.getInstance()
|
quality_manager = QualityManager.getInstance()
|
||||||
machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
|
||||||
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
|
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
|
||||||
|
|
||||||
# Detecting if the machine has multiple extrusion
|
|
||||||
multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
|
||||||
# Get the list of extruders
|
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
extruder_manager = ExtruderManager.getInstance()
|
||||||
active_extruder = extruder_manager.getActiveExtruderStack()
|
active_extruder = extruder_manager.getActiveExtruderStack()
|
||||||
extruder_stacks = extruder_manager.getActiveExtruderStacks()
|
extruder_stacks = self._getOrderedExtruderStacksList()
|
||||||
if multiple_extrusion:
|
|
||||||
# Place the active extruder at the front of the list.
|
|
||||||
# This is a workaround checking if there is an active_extruder or not before moving it to the front of the list.
|
|
||||||
# Actually, when a printer has multiple extruders, should exist always an active_extruder. However, in some
|
|
||||||
# cases the active_extruder is still None.
|
|
||||||
if active_extruder in extruder_stacks:
|
|
||||||
extruder_stacks.remove(active_extruder)
|
|
||||||
new_extruder_stacks = []
|
|
||||||
if active_extruder is not None:
|
|
||||||
new_extruder_stacks = [active_extruder]
|
|
||||||
else:
|
|
||||||
# if there is no active extruder, use the first one in the active extruder stacks
|
|
||||||
active_extruder = extruder_stacks[0]
|
|
||||||
extruder_stacks = new_extruder_stacks + extruder_stacks
|
|
||||||
|
|
||||||
# Fetch the list of useable qualities across all extruders.
|
# Fetch the list of usable qualities across all extruders.
|
||||||
# The actual list of quality profiles come from the first extruder in the extruder list.
|
# The actual list of quality profiles come from the first extruder in the extruder list.
|
||||||
quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
|
quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
|
||||||
extruder_stacks)
|
|
||||||
|
|
||||||
# Filter the quality_change by the list of available quality_types
|
# Filter the quality_change by the list of available quality_types
|
||||||
quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
|
quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
|
||||||
|
filtered_quality_changes = [qc for qc in quality_changes_list if
|
||||||
if multiple_extrusion:
|
qc.getMetaDataEntry("quality_type") in quality_type_set and
|
||||||
# If the printer has multiple extruders then quality changes related to the current extruder are kept
|
qc.getMetaDataEntry("extruder") is not None and
|
||||||
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and
|
(qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
|
||||||
qc.getMetaDataEntry("extruder") is not None and
|
qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())]
|
||||||
(qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
|
|
||||||
qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())]
|
|
||||||
else:
|
|
||||||
# If not, the quality changes of the global stack are selected
|
|
||||||
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and
|
|
||||||
qc.getMetaDataEntry("extruder") is None]
|
|
||||||
|
|
||||||
return quality_list + filtered_quality_changes
|
return quality_list + filtered_quality_changes
|
||||||
|
|
|
@ -224,7 +224,6 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
|
||||||
if self._extruder_id == "" and settable_per_extruder:
|
if self._extruder_id == "" and settable_per_extruder:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
label = definition.label
|
label = definition.label
|
||||||
if self._i18n_catalog:
|
if self._i18n_catalog:
|
||||||
label = self._i18n_catalog.i18nc(definition.key + " label", label)
|
label = self._i18n_catalog.i18nc(definition.key + " label", label)
|
||||||
|
|
|
@ -47,21 +47,20 @@ class SettingInheritanceManager(QObject):
|
||||||
|
|
||||||
@pyqtSlot(str, str, result = "QStringList")
|
@pyqtSlot(str, str, result = "QStringList")
|
||||||
def getOverridesForExtruder(self, key, extruder_index):
|
def getOverridesForExtruder(self, key, extruder_index):
|
||||||
multi_extrusion = self._global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
result = []
|
||||||
if not multi_extrusion:
|
|
||||||
return self._settings_with_inheritance_warning
|
|
||||||
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
|
||||||
if not extruder:
|
|
||||||
Logger.log("w", "Unable to find extruder for current machine with index %s", extruder_index)
|
|
||||||
return []
|
|
||||||
|
|
||||||
definitions = self._global_container_stack.definition.findDefinitions(key=key)
|
extruder_stack = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||||
|
if not extruder_stack:
|
||||||
|
Logger.log("w", "Unable to find extruder for current machine with index %s", extruder_index)
|
||||||
|
return result
|
||||||
|
|
||||||
|
definitions = self._global_container_stack.definition.findDefinitions(key = key)
|
||||||
if not definitions:
|
if not definitions:
|
||||||
Logger.log("w", "Could not find definition for key [%s] (2)", key)
|
Logger.log("w", "Could not find definition for key [%s] (2)", key)
|
||||||
return []
|
return result
|
||||||
result = []
|
|
||||||
for key in definitions[0].getAllKeys():
|
for key in definitions[0].getAllKeys():
|
||||||
if self._settingIsOverwritingInheritance(key, extruder):
|
if self._settingIsOverwritingInheritance(key, extruder_stack):
|
||||||
result.append(key)
|
result.append(key)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -78,8 +77,8 @@ class SettingInheritanceManager(QObject):
|
||||||
|
|
||||||
def _onActiveExtruderChanged(self):
|
def _onActiveExtruderChanged(self):
|
||||||
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
|
||||||
if not new_active_stack:
|
# if not new_active_stack:
|
||||||
new_active_stack = self._global_container_stack
|
# new_active_stack = self._global_container_stack
|
||||||
|
|
||||||
if new_active_stack != self._active_container_stack: # Check if changed
|
if new_active_stack != self._active_container_stack: # Check if changed
|
||||||
if self._active_container_stack: # Disconnect signal from old container (if any)
|
if self._active_container_stack: # Disconnect signal from old container (if any)
|
||||||
|
|
|
@ -35,11 +35,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||||
self._stack = PerObjectContainerStack(stack_id = id(self))
|
self._stack = PerObjectContainerStack(stack_id = 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()
|
||||||
if ExtruderManager.getInstance().extruderCount > 1:
|
|
||||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
|
||||||
else:
|
|
||||||
self._extruder_stack = None
|
|
||||||
|
|
||||||
self._stack.propertyChanged.connect(self._onSettingChanged)
|
self._stack.propertyChanged.connect(self._onSettingChanged)
|
||||||
|
|
||||||
|
|
|
@ -22,47 +22,23 @@ class UserProfilesModel(ProfilesModel):
|
||||||
|
|
||||||
# Fetch the list of quality changes.
|
# Fetch the list of quality changes.
|
||||||
quality_manager = QualityManager.getInstance()
|
quality_manager = QualityManager.getInstance()
|
||||||
machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
|
||||||
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
|
quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
|
||||||
|
|
||||||
# Detecting if the machine has multiple extrusion
|
|
||||||
multiple_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
|
||||||
# Get the list of extruders and place the selected extruder at the front of the list.
|
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
extruder_manager = ExtruderManager.getInstance()
|
||||||
active_extruder = extruder_manager.getActiveExtruderStack()
|
active_extruder = extruder_manager.getActiveExtruderStack()
|
||||||
extruder_stacks = extruder_manager.getActiveExtruderStacks()
|
extruder_stacks = self._getOrderedExtruderStacksList()
|
||||||
if multiple_extrusion:
|
|
||||||
# Place the active extruder at the front of the list.
|
|
||||||
# This is a workaround checking if there is an active_extruder or not before moving it to the front of the list.
|
|
||||||
# Actually, when a printer has multiple extruders, should exist always an active_extruder. However, in some
|
|
||||||
# cases the active_extruder is still None.
|
|
||||||
if active_extruder in extruder_stacks:
|
|
||||||
extruder_stacks.remove(active_extruder)
|
|
||||||
new_extruder_stacks = []
|
|
||||||
if active_extruder is not None:
|
|
||||||
new_extruder_stacks = [active_extruder]
|
|
||||||
else:
|
|
||||||
# if there is no active extruder, use the first one in the active extruder stacks
|
|
||||||
active_extruder = extruder_stacks[0]
|
|
||||||
extruder_stacks = new_extruder_stacks + extruder_stacks
|
|
||||||
|
|
||||||
# Fetch the list of useable qualities across all extruders.
|
# Fetch the list of usable qualities across all extruders.
|
||||||
# The actual list of quality profiles come from the first extruder in the extruder list.
|
# The actual list of quality profiles come from the first extruder in the extruder list.
|
||||||
quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack,
|
quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
|
||||||
extruder_stacks)
|
|
||||||
|
|
||||||
# Filter the quality_change by the list of available quality_types
|
# Filter the quality_change by the list of available quality_types
|
||||||
quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
|
quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
|
||||||
|
filtered_quality_changes = [qc for qc in quality_changes_list if
|
||||||
if multiple_extrusion:
|
qc.getMetaDataEntry("quality_type") in quality_type_set and
|
||||||
# If the printer has multiple extruders then quality changes related to the current extruder are kept
|
qc.getMetaDataEntry("extruder") is not None and
|
||||||
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and
|
(qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
|
||||||
qc.getMetaDataEntry("extruder") is not None and
|
qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())]
|
||||||
(qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
|
|
||||||
qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())]
|
|
||||||
else:
|
|
||||||
# If not, the quality changes of the global stack are selected
|
|
||||||
filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and
|
|
||||||
qc.getMetaDataEntry("extruder") is None]
|
|
||||||
|
|
||||||
return filtered_quality_changes
|
return filtered_quality_changes
|
||||||
|
|
|
@ -107,20 +107,13 @@ class ThreeMFReader(MeshReader):
|
||||||
um_node.addDecorator(SettingOverrideDecorator())
|
um_node.addDecorator(SettingOverrideDecorator())
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
|
||||||
# Ensure the correct next container for the SettingOverride decorator is set.
|
# Ensure the correct next container for the SettingOverride decorator is set.
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
default_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
||||||
|
|
||||||
# Ensure that all extruder data is reset
|
if default_stack:
|
||||||
if not multi_extrusion:
|
um_node.callDecoration("setActiveExtruder", default_stack.getId())
|
||||||
default_stack_id = global_container_stack.getId()
|
|
||||||
else:
|
|
||||||
default_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
|
||||||
if default_stack:
|
|
||||||
default_stack_id = default_stack.getId()
|
|
||||||
else:
|
|
||||||
default_stack_id = global_container_stack.getId()
|
|
||||||
um_node.callDecoration("setActiveExtruder", default_stack_id)
|
|
||||||
|
|
||||||
# Get the definition & set it
|
# Get the definition & set it
|
||||||
definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
|
definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
|
||||||
|
@ -139,7 +132,7 @@ class ThreeMFReader(MeshReader):
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "Unable to find extruder in position %s", setting_value)
|
Logger.log("w", "Unable to find extruder in position %s", setting_value)
|
||||||
continue
|
continue
|
||||||
setting_container.setProperty(key,"value", setting_value)
|
setting_container.setProperty(key, "value", setting_value)
|
||||||
|
|
||||||
if len(um_node.getChildren()) > 0:
|
if len(um_node.getChildren()) > 0:
|
||||||
group_decorator = GroupDecorator()
|
group_decorator = GroupDecorator()
|
||||||
|
|
|
@ -644,9 +644,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
# Get the stack(s) saved in the workspace.
|
# Get the stack(s) saved in the workspace.
|
||||||
Logger.log("d", "Workspace loading is checking stacks containers...")
|
Logger.log("d", "Workspace loading is checking stacks containers...")
|
||||||
|
|
||||||
# --
|
|
||||||
# load global stack file
|
# load global stack file
|
||||||
try:
|
try:
|
||||||
|
stack = None
|
||||||
|
|
||||||
if self._resolve_strategies["machine"] == "override":
|
if self._resolve_strategies["machine"] == "override":
|
||||||
container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
|
container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
|
||||||
stack = container_stacks[0]
|
stack = container_stacks[0]
|
||||||
|
@ -682,12 +683,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
self._container_registry.addContainer(stack)
|
self._container_registry.addContainer(stack)
|
||||||
containers_added.append(stack)
|
containers_added.append(stack)
|
||||||
else:
|
else:
|
||||||
Logger.log("e", "Resolve strategy of %s for machine is not supported",
|
Logger.log("e", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
|
||||||
self._resolve_strategies["machine"])
|
|
||||||
|
|
||||||
# Create a new definition_changes container if it was empty
|
# Create a new definition_changes container if it was empty
|
||||||
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
||||||
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings"))
|
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
|
||||||
global_stack = stack
|
global_stack = stack
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
except:
|
except:
|
||||||
|
@ -697,16 +697,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
self._container_registry.removeContainer(container.getId())
|
self._container_registry.removeContainer(container.getId())
|
||||||
return
|
return
|
||||||
|
|
||||||
#
|
|
||||||
# Use the number of extruders from the global stack instead of the number of extruder stacks this project file
|
|
||||||
# contains. The Custom FDM Printer can have multiple extruders, but the actual number of extruders in used is
|
|
||||||
# defined in the global stack.
|
|
||||||
# Because for single-extrusion machines, there won't be an extruder stack, so relying on the the extruder count
|
|
||||||
# in the global stack can avoid problems in those cases.
|
|
||||||
#
|
|
||||||
extruder_count_from_global_stack = global_stack.getProperty("machine_extruder_count", "value")
|
|
||||||
|
|
||||||
# --
|
|
||||||
# load extruder stack files
|
# load extruder stack files
|
||||||
try:
|
try:
|
||||||
for extruder_stack_file in extruder_stack_files:
|
for extruder_stack_file in extruder_stack_files:
|
||||||
|
@ -749,9 +739,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
|
|
||||||
# Create a new definition_changes container if it was empty
|
# Create a new definition_changes container if it was empty
|
||||||
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
|
||||||
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings"))
|
stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
|
||||||
if global_stack.getProperty("machine_extruder_count", "value") > 1:
|
|
||||||
extruder_stacks.append(stack)
|
extruder_stacks.append(stack)
|
||||||
|
|
||||||
|
# If not extruder stacks were saved in the project file (pre 3.1) create one manually
|
||||||
|
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
|
||||||
|
if not extruder_stacks:
|
||||||
|
self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder")
|
||||||
|
|
||||||
except:
|
except:
|
||||||
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
|
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
|
||||||
# Something went really wrong. Try to remove any data that we added.
|
# Something went really wrong. Try to remove any data that we added.
|
||||||
|
@ -784,7 +780,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
for stack in [global_stack] + extruder_stacks:
|
for stack in [global_stack] + extruder_stacks:
|
||||||
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
||||||
|
|
||||||
#
|
|
||||||
# Replacing the old containers if resolve is "new".
|
# Replacing the old containers if resolve is "new".
|
||||||
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
|
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
|
||||||
# MUST get updated too.
|
# MUST get updated too.
|
||||||
|
|
|
@ -87,7 +87,7 @@ class ThreeMFWriter(MeshWriter):
|
||||||
if stack is not None:
|
if stack is not None:
|
||||||
changed_setting_keys = set(stack.getTop().getAllKeys())
|
changed_setting_keys = set(stack.getTop().getAllKeys())
|
||||||
|
|
||||||
# Ensure that we save the extruder used for this object.
|
# Ensure that we save the extruder used for this object in a multi-extrusion setup
|
||||||
if stack.getProperty("machine_extruder_count", "value") > 1:
|
if stack.getProperty("machine_extruder_count", "value") > 1:
|
||||||
changed_setting_keys.add("extruder_nr")
|
changed_setting_keys.add("extruder_nr")
|
||||||
|
|
||||||
|
|
|
@ -149,13 +149,9 @@ class StartSliceJob(Job):
|
||||||
self._buildGlobalSettingsMessage(stack)
|
self._buildGlobalSettingsMessage(stack)
|
||||||
self._buildGlobalInheritsStackMessage(stack)
|
self._buildGlobalInheritsStackMessage(stack)
|
||||||
|
|
||||||
# Only add extruder stacks if there are multiple extruders
|
# Build messages for extruder stacks
|
||||||
# Single extruder machines only use the global stack to store setting values
|
for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
|
||||||
if stack.getProperty("machine_extruder_count", "value") > 1:
|
self._buildExtruderMessage(extruder_stack)
|
||||||
for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
|
|
||||||
self._buildExtruderMessage(extruder_stack)
|
|
||||||
else:
|
|
||||||
self._buildExtruderMessageFromGlobalStack(stack)
|
|
||||||
|
|
||||||
for group in object_groups:
|
for group in object_groups:
|
||||||
group_message = self._slice_message.addRepeatedMessage("object_lists")
|
group_message = self._slice_message.addRepeatedMessage("object_lists")
|
||||||
|
@ -241,19 +237,6 @@ class StartSliceJob(Job):
|
||||||
setting.value = str(stack.getProperty(key, "value")).encode("utf-8")
|
setting.value = str(stack.getProperty(key, "value")).encode("utf-8")
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
## Create extruder message from global stack
|
|
||||||
def _buildExtruderMessageFromGlobalStack(self, stack):
|
|
||||||
message = self._slice_message.addRepeatedMessage("extruders")
|
|
||||||
|
|
||||||
for key in stack.getAllKeys():
|
|
||||||
# Do not send settings that are not settable_per_extruder.
|
|
||||||
if not stack.getProperty(key, "settable_per_extruder"):
|
|
||||||
continue
|
|
||||||
setting = message.getMessage("settings").addRepeatedMessage("settings")
|
|
||||||
setting.name = key
|
|
||||||
setting.value = str(stack.getProperty(key, "value")).encode("utf-8")
|
|
||||||
Job.yieldThread()
|
|
||||||
|
|
||||||
## Sends all global settings to the engine.
|
## Sends all global settings to the engine.
|
||||||
#
|
#
|
||||||
# The settings are taken from the global stack. This does not include any
|
# The settings are taken from the global stack. This does not include any
|
||||||
|
|
|
@ -54,6 +54,7 @@ class GCodeReader(MeshReader):
|
||||||
self._previous_z = 0
|
self._previous_z = 0
|
||||||
self._layer_data_builder = LayerDataBuilder.LayerDataBuilder()
|
self._layer_data_builder = LayerDataBuilder.LayerDataBuilder()
|
||||||
self._center_is_zero = False
|
self._center_is_zero = False
|
||||||
|
self._is_absolute_positioning = True # It can be absolute (G90) or relative (G91)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _getValue(line, code):
|
def _getValue(line, code):
|
||||||
|
@ -135,16 +136,22 @@ class GCodeReader(MeshReader):
|
||||||
|
|
||||||
def _gCode0(self, position, params, path):
|
def _gCode0(self, position, params, path):
|
||||||
x, y, z, e = position
|
x, y, z, e = position
|
||||||
x = params.x if params.x is not None else x
|
if self._is_absolute_positioning:
|
||||||
y = params.y if params.y is not None else y
|
x = params.x if params.x is not None else x
|
||||||
z = params.z if params.z is not None else position.z
|
y = params.y if params.y is not None else y
|
||||||
|
z = params.z if params.z is not None else position.z
|
||||||
|
else:
|
||||||
|
x += params.x if params.x is not None else x
|
||||||
|
y += params.y if params.y is not None else y
|
||||||
|
z += params.z if params.z is not None else position.z
|
||||||
|
|
||||||
if params.e is not None:
|
if params.e is not None:
|
||||||
if params.e > e[self._extruder_number]:
|
new_extrusion_value = params.e if self._is_absolute_positioning else e[self._extruder_number] + params.e
|
||||||
|
if new_extrusion_value > e[self._extruder_number]:
|
||||||
path.append([x, y, z, self._layer_type]) # extrusion
|
path.append([x, y, z, self._layer_type]) # extrusion
|
||||||
else:
|
else:
|
||||||
path.append([x, y, z, LayerPolygon.MoveRetractionType]) # retraction
|
path.append([x, y, z, LayerPolygon.MoveRetractionType]) # retraction
|
||||||
e[self._extruder_number] = params.e
|
e[self._extruder_number] = new_extrusion_value
|
||||||
|
|
||||||
# Only when extruding we can determine the latest known "layer height" which is the difference in height between extrusions
|
# Only when extruding we can determine the latest known "layer height" which is the difference in height between extrusions
|
||||||
# Also, 1.5 is a heuristic for any priming or whatsoever, we skip those.
|
# Also, 1.5 is a heuristic for any priming or whatsoever, we skip those.
|
||||||
|
@ -166,6 +173,16 @@ class GCodeReader(MeshReader):
|
||||||
0,
|
0,
|
||||||
position.e)
|
position.e)
|
||||||
|
|
||||||
|
## Set the absolute positioning
|
||||||
|
def _gCode90(self, position, params, path):
|
||||||
|
self._is_absolute_positioning = True
|
||||||
|
return position
|
||||||
|
|
||||||
|
## Set the relative positioning
|
||||||
|
def _gCode91(self, position, params, path):
|
||||||
|
self._is_absolute_positioning = False
|
||||||
|
return position
|
||||||
|
|
||||||
## Reset the current position to the values specified.
|
## Reset the current position to the values specified.
|
||||||
# For example: G92 X10 will set the X to 10 without any physical motion.
|
# For example: G92 X10 will set the X to 10 without any physical motion.
|
||||||
def _gCode92(self, position, params, path):
|
def _gCode92(self, position, params, path):
|
||||||
|
@ -196,7 +213,7 @@ class GCodeReader(MeshReader):
|
||||||
z = float(item[1:])
|
z = float(item[1:])
|
||||||
if item[0] == "E":
|
if item[0] == "E":
|
||||||
e = float(item[1:])
|
e = float(item[1:])
|
||||||
if (x is not None and x < 0) or (y is not None and y < 0):
|
if self._is_absolute_positioning and ((x is not None and x < 0) or (y is not None and y < 0)):
|
||||||
self._center_is_zero = True
|
self._center_is_zero = True
|
||||||
params = self._position(x, y, z, e)
|
params = self._position(x, y, z, e)
|
||||||
return func(position, params, path)
|
return func(position, params, path)
|
||||||
|
|
|
@ -116,8 +116,7 @@ class MachineSettingsAction(MachineAction):
|
||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def setMachineExtruderCount(self, extruder_count):
|
def setMachineExtruderCount(self, extruder_count):
|
||||||
machine_manager = Application.getInstance().getMachineManager()
|
extruder_manager = Application.getInstance().getExtruderManager()
|
||||||
extruder_manager = ExtruderManager.getInstance()
|
|
||||||
|
|
||||||
definition_changes_container = self._global_container_stack.definitionChanges
|
definition_changes_container = self._global_container_stack.definitionChanges
|
||||||
if not self._global_container_stack or definition_changes_container == self._empty_container:
|
if not self._global_container_stack or definition_changes_container == self._empty_container:
|
||||||
|
@ -127,34 +126,6 @@ class MachineSettingsAction(MachineAction):
|
||||||
if extruder_count == previous_extruder_count:
|
if extruder_count == previous_extruder_count:
|
||||||
return
|
return
|
||||||
|
|
||||||
extruder_material_id = None
|
|
||||||
extruder_variant_id = None
|
|
||||||
if extruder_count == 1:
|
|
||||||
# Get the material and variant of the first extruder before setting the number extruders to 1
|
|
||||||
if machine_manager.hasMaterials:
|
|
||||||
extruder_material_id = machine_manager.allActiveMaterialIds[extruder_manager.extruderIds["0"]]
|
|
||||||
if machine_manager.hasVariants:
|
|
||||||
extruder_variant_id = machine_manager.allActiveVariantIds[extruder_manager.extruderIds["0"]]
|
|
||||||
|
|
||||||
# Copy any settable_per_extruder setting value from the extruders to the global stack
|
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
|
||||||
extruder_stacks.reverse() # make sure the first extruder is done last, so its settings override any higher extruder settings
|
|
||||||
|
|
||||||
global_user_container = self._global_container_stack.getTop()
|
|
||||||
for extruder_stack in extruder_stacks:
|
|
||||||
extruder_index = extruder_stack.getMetaDataEntry("position")
|
|
||||||
extruder_user_container = extruder_stack.getTop()
|
|
||||||
for setting_instance in extruder_user_container.findInstances():
|
|
||||||
setting_key = setting_instance.definition.key
|
|
||||||
settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
|
||||||
|
|
||||||
if settable_per_extruder:
|
|
||||||
limit_to_extruder = self._global_container_stack.getProperty(setting_key, "limit_to_extruder")
|
|
||||||
|
|
||||||
if limit_to_extruder == "-1" or limit_to_extruder == extruder_index:
|
|
||||||
global_user_container.setProperty(setting_key, "value", extruder_user_container.getProperty(setting_key, "value"))
|
|
||||||
extruder_user_container.removeInstance(setting_key)
|
|
||||||
|
|
||||||
# reset all extruder number settings whose value is no longer valid
|
# reset all extruder number settings whose value is no longer valid
|
||||||
for setting_instance in self._global_container_stack.userChanges.findInstances():
|
for setting_instance in self._global_container_stack.userChanges.findInstances():
|
||||||
setting_key = setting_instance.definition.key
|
setting_key = setting_instance.definition.key
|
||||||
|
@ -177,52 +148,29 @@ class MachineSettingsAction(MachineAction):
|
||||||
|
|
||||||
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
|
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
|
||||||
|
|
||||||
if extruder_count > 1:
|
# Make sure one of the extruder stacks is active
|
||||||
# Multiextrusion
|
extruder_manager.setActiveExtruderIndex(0)
|
||||||
|
|
||||||
# Make sure one of the extruder stacks is active
|
# Move settable_per_extruder values out of the global container
|
||||||
if extruder_manager.activeExtruderIndex == -1:
|
# After CURA-4482 this should not be the case anymore, but we still want to support older project files.
|
||||||
extruder_manager.setActiveExtruderIndex(0)
|
global_user_container = self._global_container_stack.getTop()
|
||||||
|
|
||||||
# Move settable_per_extruder values out of the global container
|
if previous_extruder_count == 1:
|
||||||
if previous_extruder_count == 1:
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
global_user_container = self._global_container_stack.getTop()
|
||||||
global_user_container = self._global_container_stack.getTop()
|
|
||||||
|
|
||||||
for setting_instance in global_user_container.findInstances():
|
for setting_instance in global_user_container.findInstances():
|
||||||
setting_key = setting_instance.definition.key
|
setting_key = setting_instance.definition.key
|
||||||
settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
||||||
if settable_per_extruder:
|
|
||||||
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
|
|
||||||
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
|
|
||||||
extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
|
||||||
global_user_container.removeInstance(setting_key)
|
|
||||||
else:
|
|
||||||
# Single extrusion
|
|
||||||
|
|
||||||
# Make sure the machine stack is active
|
if settable_per_extruder:
|
||||||
if extruder_manager.activeExtruderIndex > -1:
|
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
|
||||||
extruder_manager.setActiveExtruderIndex(-1)
|
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
|
||||||
|
extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
||||||
# Restore material and variant on global stack
|
global_user_container.removeInstance(setting_key)
|
||||||
# MachineManager._onGlobalContainerChanged removes the global material and variant of multiextruder machines
|
|
||||||
if extruder_material_id or extruder_variant_id:
|
|
||||||
# Prevent the DiscardOrKeepProfileChangesDialog from popping up (twice) if there are user changes
|
|
||||||
# The dialog is not relevant here, since we're restoring the previous situation as good as possible
|
|
||||||
preferences = Preferences.getInstance()
|
|
||||||
choice_on_profile_override = preferences.getValue("cura/choice_on_profile_override")
|
|
||||||
preferences.setValue("cura/choice_on_profile_override", "always_keep")
|
|
||||||
|
|
||||||
if extruder_material_id:
|
|
||||||
machine_manager.setActiveMaterial(extruder_material_id)
|
|
||||||
if extruder_variant_id:
|
|
||||||
machine_manager.setActiveVariant(extruder_variant_id)
|
|
||||||
|
|
||||||
preferences.setValue("cura/choice_on_profile_override", choice_on_profile_override)
|
|
||||||
|
|
||||||
self.forceUpdate()
|
self.forceUpdate()
|
||||||
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def forceUpdate(self):
|
def forceUpdate(self):
|
||||||
# Force rebuilding the build volume by reloading the global container stack.
|
# Force rebuilding the build volume by reloading the global container stack.
|
||||||
|
@ -275,16 +223,13 @@ class MachineSettingsAction(MachineAction):
|
||||||
if not self._global_container_stack.getMetaDataEntry("has_materials", False):
|
if not self._global_container_stack.getMetaDataEntry("has_materials", False):
|
||||||
return
|
return
|
||||||
|
|
||||||
machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
material = ExtruderManager.getInstance().getActiveExtruderStack().material
|
||||||
if machine_extruder_count > 1:
|
|
||||||
material = ExtruderManager.getInstance().getActiveExtruderStack().material
|
|
||||||
else:
|
|
||||||
material = self._global_container_stack.material
|
|
||||||
material_diameter = material.getProperty("material_diameter", "value")
|
material_diameter = material.getProperty("material_diameter", "value")
|
||||||
if not material_diameter: # in case of "empty" material
|
if not material_diameter:
|
||||||
|
# in case of "empty" material
|
||||||
material_diameter = 0
|
material_diameter = 0
|
||||||
material_approximate_diameter = str(round(material_diameter))
|
|
||||||
|
|
||||||
|
material_approximate_diameter = str(round(material_diameter))
|
||||||
definition_changes = self._global_container_stack.definitionChanges
|
definition_changes = self._global_container_stack.definitionChanges
|
||||||
machine_diameter = definition_changes.getProperty("material_diameter", "value")
|
machine_diameter = definition_changes.getProperty("material_diameter", "value")
|
||||||
if not machine_diameter:
|
if not machine_diameter:
|
||||||
|
@ -294,10 +239,7 @@ class MachineSettingsAction(MachineAction):
|
||||||
if material_approximate_diameter != machine_approximate_diameter:
|
if material_approximate_diameter != machine_approximate_diameter:
|
||||||
Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
|
Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
|
||||||
|
|
||||||
if machine_extruder_count > 1:
|
stacks = ExtruderManager.getInstance().getExtruderStacks()
|
||||||
stacks = ExtruderManager.getInstance().getExtruderStacks()
|
|
||||||
else:
|
|
||||||
stacks = [self._global_container_stack]
|
|
||||||
|
|
||||||
if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
|
if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
|
||||||
materials_definition = self._global_container_stack.definition.getId()
|
materials_definition = self._global_container_stack.definition.getId()
|
||||||
|
@ -338,7 +280,7 @@ class MachineSettingsAction(MachineAction):
|
||||||
search_criteria["id"] = stack.getMetaDataEntry("preferred_material")
|
search_criteria["id"] = stack.getMetaDataEntry("preferred_material")
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
||||||
if not materials:
|
if not materials:
|
||||||
# Preferrd material with new diameter is not found, search for any material
|
# Preferred material with new diameter is not found, search for any material
|
||||||
search_criteria.pop("id", None)
|
search_criteria.pop("id", None)
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
||||||
if not materials:
|
if not materials:
|
||||||
|
|
|
@ -112,31 +112,26 @@ class PerObjectSettingsTool(Tool):
|
||||||
def _onGlobalContainerChanged(self):
|
def _onGlobalContainerChanged(self):
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
|
|
||||||
|
# used for enabling or disabling per extruder settings per object
|
||||||
self._multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
self._multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||||
|
|
||||||
# Ensure that all extruder data is reset
|
extruder_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
||||||
if not self._multi_extrusion:
|
|
||||||
default_stack_id = global_container_stack.getId()
|
|
||||||
else:
|
|
||||||
default_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
|
||||||
if default_stack:
|
|
||||||
default_stack_id = default_stack.getId()
|
|
||||||
else:
|
|
||||||
default_stack_id = global_container_stack.getId()
|
|
||||||
|
|
||||||
root_node = Application.getInstance().getController().getScene().getRoot()
|
if extruder_stack:
|
||||||
for node in DepthFirstIterator(root_node):
|
root_node = Application.getInstance().getController().getScene().getRoot()
|
||||||
new_stack_id = default_stack_id
|
for node in DepthFirstIterator(root_node):
|
||||||
# Get position of old extruder stack for this node
|
new_stack_id = extruder_stack.getId()
|
||||||
old_extruder_pos = node.callDecoration("getActiveExtruderPosition")
|
# Get position of old extruder stack for this node
|
||||||
if old_extruder_pos is not None:
|
old_extruder_pos = node.callDecoration("getActiveExtruderPosition")
|
||||||
# Fetch current (new) extruder stack at position
|
if old_extruder_pos is not None:
|
||||||
new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos)
|
# Fetch current (new) extruder stack at position
|
||||||
if new_stack:
|
new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos)
|
||||||
new_stack_id = new_stack.getId()
|
if new_stack:
|
||||||
node.callDecoration("setActiveExtruder", new_stack_id)
|
new_stack_id = new_stack.getId()
|
||||||
|
node.callDecoration("setActiveExtruder", new_stack_id)
|
||||||
|
|
||||||
self._updateEnabled()
|
self._updateEnabled()
|
||||||
|
|
||||||
def _updateEnabled(self):
|
def _updateEnabled(self):
|
||||||
selected_objects = Selection.getAllSelectedObjects()
|
selected_objects = Selection.getAllSelectedObjects()
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
from . import RemovableDrivePlugin
|
from . import RemovableDrivePlugin
|
||||||
|
|
||||||
from UM.Logger import Logger
|
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -15,12 +13,12 @@ import plistlib
|
||||||
class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
|
class OSXRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
|
||||||
def checkRemovableDrives(self):
|
def checkRemovableDrives(self):
|
||||||
drives = {}
|
drives = {}
|
||||||
p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout = subprocess.PIPE)
|
p = subprocess.Popen(["system_profiler", "SPUSBDataType", "-xml"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
|
||||||
plist = plistlib.loads(p.communicate()[0])
|
plist = plistlib.loads(p.communicate()[0])
|
||||||
|
|
||||||
result = self._recursiveSearch(plist, "removable_media")
|
result = self._recursiveSearch(plist, "removable_media")
|
||||||
|
|
||||||
p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE)
|
p = subprocess.Popen(["system_profiler", "SPCardReaderDataType", "-xml"], stdout=subprocess.PIPE, stderr = subprocess.PIPE)
|
||||||
plist = plistlib.loads(p.communicate()[0])
|
plist = plistlib.loads(p.communicate()[0])
|
||||||
|
|
||||||
result.extend(self._recursiveSearch(plist, "removable_media"))
|
result.extend(self._recursiveSearch(plist, "removable_media"))
|
||||||
|
|
|
@ -87,15 +87,10 @@ class SliceInfo(Extension):
|
||||||
|
|
||||||
data["active_machine"] = {"definition_id": global_container_stack.definition.getId(), "manufacturer": global_container_stack.definition.getMetaData().get("manufacturer","")}
|
data["active_machine"] = {"definition_id": global_container_stack.definition.getId(), "manufacturer": global_container_stack.definition.getMetaData().get("manufacturer","")}
|
||||||
|
|
||||||
|
# add extruder specific data to slice info
|
||||||
data["extruders"] = []
|
data["extruders"] = []
|
||||||
extruder_count = len(global_container_stack.extruders)
|
extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
|
||||||
extruders = []
|
extruders = sorted(extruders, key = lambda extruder: extruder.getMetaDataEntry("position"))
|
||||||
if extruder_count > 1:
|
|
||||||
extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
|
|
||||||
extruders = sorted(extruders, key = lambda extruder: extruder.getMetaDataEntry("position"))
|
|
||||||
|
|
||||||
if not extruders:
|
|
||||||
extruders = [global_container_stack]
|
|
||||||
|
|
||||||
for extruder in extruders:
|
for extruder in extruders:
|
||||||
extruder_dict = dict()
|
extruder_dict = dict()
|
||||||
|
|
|
@ -54,19 +54,10 @@ class SolidView(View):
|
||||||
self._non_printing_shader.setUniformValue("u_diffuseColor", Color(*self._theme.getColor("model_non_printing").getRgb()))
|
self._non_printing_shader.setUniformValue("u_diffuseColor", Color(*self._theme.getColor("model_non_printing").getRgb()))
|
||||||
self._non_printing_shader.setUniformValue("u_opacity", 0.6)
|
self._non_printing_shader.setUniformValue("u_opacity", 0.6)
|
||||||
|
|
||||||
multi_extrusion = False
|
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
support_extruder_nr = global_container_stack.getProperty("support_extruder_nr", "value")
|
||||||
|
support_angle_stack = ExtruderManager.getInstance().getExtruderStack(support_extruder_nr)
|
||||||
if multi_extrusion:
|
|
||||||
support_extruder_nr = global_container_stack.getProperty("support_extruder_nr", "value")
|
|
||||||
support_angle_stack = ExtruderManager.getInstance().getExtruderStack(support_extruder_nr)
|
|
||||||
if not support_angle_stack:
|
|
||||||
support_angle_stack = global_container_stack
|
|
||||||
else:
|
|
||||||
support_angle_stack = global_container_stack
|
|
||||||
|
|
||||||
if Preferences.getInstance().getValue("view/show_overhang"):
|
if Preferences.getInstance().getValue("view/show_overhang"):
|
||||||
angle = support_angle_stack.getProperty("support_angle", "value")
|
angle = support_angle_stack.getProperty("support_angle", "value")
|
||||||
|
@ -79,7 +70,6 @@ class SolidView(View):
|
||||||
else:
|
else:
|
||||||
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))
|
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))
|
||||||
|
|
||||||
|
|
||||||
for node in DepthFirstIterator(scene.getRoot()):
|
for node in DepthFirstIterator(scene.getRoot()):
|
||||||
if not node.render(renderer):
|
if not node.render(renderer):
|
||||||
if node.getMeshData() and node.isVisible():
|
if node.getMeshData() and node.isVisible():
|
||||||
|
@ -88,32 +78,26 @@ class SolidView(View):
|
||||||
|
|
||||||
per_mesh_stack = node.callDecoration("getStack")
|
per_mesh_stack = node.callDecoration("getStack")
|
||||||
|
|
||||||
if not multi_extrusion:
|
# Get color to render this mesh in from ExtrudersModel
|
||||||
if global_container_stack:
|
extruder_index = 0
|
||||||
material = global_container_stack.findContainer({ "type": "material" })
|
extruder_id = node.callDecoration("getActiveExtruder")
|
||||||
material_color = material.getMetaDataEntry("color_code", default = self._extruders_model.defaultColors[0]) if material else self._extruders_model.defaultColors[0]
|
if extruder_id:
|
||||||
else:
|
extruder_index = max(0, self._extruders_model.find("id", extruder_id))
|
||||||
material_color = self._extruders_model.defaultColors[0]
|
|
||||||
else:
|
|
||||||
# Get color to render this mesh in from ExtrudersModel
|
|
||||||
extruder_index = 0
|
|
||||||
extruder_id = node.callDecoration("getActiveExtruder")
|
|
||||||
if extruder_id:
|
|
||||||
extruder_index = max(0, self._extruders_model.find("id", extruder_id))
|
|
||||||
|
|
||||||
# Use the support extruder instead of the active extruder if this is a support_mesh
|
# Use the support extruder instead of the active extruder if this is a support_mesh
|
||||||
if per_mesh_stack:
|
if per_mesh_stack:
|
||||||
if per_mesh_stack.getProperty("support_mesh", "value"):
|
if per_mesh_stack.getProperty("support_mesh", "value"):
|
||||||
extruder_index = int(global_container_stack.getProperty("support_extruder_nr", "value"))
|
extruder_index = int(global_container_stack.getProperty("support_extruder_nr", "value"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
material_color = self._extruders_model.getItem(extruder_index)["color"]
|
material_color = self._extruders_model.getItem(extruder_index)["color"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
material_color = self._extruders_model.defaultColors[0]
|
material_color = self._extruders_model.defaultColors[0]
|
||||||
|
|
||||||
|
if extruder_index != ExtruderManager.getInstance().activeExtruderIndex:
|
||||||
|
# Shade objects that are printed with the non-active extruder 25% darker
|
||||||
|
shade_factor = 0.6
|
||||||
|
|
||||||
if extruder_index != ExtruderManager.getInstance().activeExtruderIndex:
|
|
||||||
# Shade objects that are printed with the non-active extruder 25% darker
|
|
||||||
shade_factor = 0.6
|
|
||||||
try:
|
try:
|
||||||
# Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
|
# Colors are passed as rgb hex strings (eg "#ffffff"), and the shader needs
|
||||||
# an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
|
# an rgba list of floats (eg [1.0, 1.0, 1.0, 1.0])
|
||||||
|
|
|
@ -37,7 +37,7 @@ class UM2UpgradeSelection(MachineAction):
|
||||||
def setHasVariants(self, has_variants = True):
|
def setHasVariants(self, has_variants = True):
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
if global_container_stack:
|
if global_container_stack:
|
||||||
variant_container = global_container_stack.variant
|
variant_container = global_container_stack.extruders["0"].variant
|
||||||
variant_index = global_container_stack.getContainerIndex(variant_container)
|
variant_index = global_container_stack.getContainerIndex(variant_container)
|
||||||
|
|
||||||
if has_variants:
|
if has_variants:
|
||||||
|
@ -52,7 +52,7 @@ class UM2UpgradeSelection(MachineAction):
|
||||||
search_criteria = { "type": "variant", "definition": "ultimaker2", "id": "*0.4*" }
|
search_criteria = { "type": "variant", "definition": "ultimaker2", "id": "*0.4*" }
|
||||||
containers = self._container_registry.findInstanceContainers(**search_criteria)
|
containers = self._container_registry.findInstanceContainers(**search_criteria)
|
||||||
if containers:
|
if containers:
|
||||||
global_container_stack.variant = containers[0]
|
global_container_stack.extruders["0"].variant = containers[0]
|
||||||
else:
|
else:
|
||||||
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
|
# 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.
|
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
|
||||||
|
|
|
@ -549,7 +549,7 @@ class XmlMaterialProfile(InstanceContainer):
|
||||||
|
|
||||||
definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id)
|
definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = machine_id)
|
||||||
if not definitions:
|
if not definitions:
|
||||||
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
# Logger.log("w", "No definition found for machine ID %s", machine_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
definition = definitions[0]
|
definition = definitions[0]
|
||||||
|
|
|
@ -7,10 +7,6 @@
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "rikky",
|
"author": "rikky",
|
||||||
"manufacturer": "101Hero",
|
"manufacturer": "101Hero",
|
||||||
"machine_extruder_trains":
|
|
||||||
{
|
|
||||||
"0": "fdmextruder"
|
|
||||||
},
|
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"platform": "101hero-platform.stl",
|
"platform": "101hero-platform.stl",
|
||||||
"supports_usb_connection": true
|
"supports_usb_connection": true
|
||||||
|
|
|
@ -10,11 +10,7 @@
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"icon": "icon_ultimaker2",
|
"icon": "icon_ultimaker2",
|
||||||
"supports_usb_connection": true,
|
"supports_usb_connection": true,
|
||||||
"platform": "3dator_platform.stl",
|
"platform": "3dator_platform.stl"
|
||||||
"machine_extruder_trains":
|
|
||||||
{
|
|
||||||
"0": "fdmextruder"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
@ -29,7 +25,6 @@
|
||||||
"layer_height": { "default_value": 0.2 },
|
"layer_height": { "default_value": 0.2 },
|
||||||
"speed_print": { "default_value": 50 },
|
"speed_print": { "default_value": 50 },
|
||||||
"speed_infill": { "default_value": 60 },
|
"speed_infill": { "default_value": 60 },
|
||||||
"machine_extruder_count": { "default_value": 1 },
|
|
||||||
"machine_heated_bed": { "default_value": true },
|
"machine_heated_bed": { "default_value": true },
|
||||||
"machine_center_is_zero": { "default_value": false },
|
"machine_center_is_zero": { "default_value": false },
|
||||||
"machine_height": { "default_value": 260 },
|
"machine_height": { "default_value": 260 },
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"author": "Ultimaker",
|
"author": "Ultimaker",
|
||||||
"manufacturer": "Unknown",
|
"manufacturer": "Unknown",
|
||||||
"setting_version": 1,
|
"setting_version": 1,
|
||||||
"visible": false
|
"visible": false,
|
||||||
|
"position": "0"
|
||||||
},
|
},
|
||||||
"settings":
|
"settings":
|
||||||
{
|
{
|
||||||
|
|
|
@ -1340,6 +1340,124 @@
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_enabled":
|
||||||
|
{
|
||||||
|
"label": "Enable Ironing",
|
||||||
|
"description": "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_only_highest_layer":
|
||||||
|
{
|
||||||
|
"label": "Iron Only Highest Layer",
|
||||||
|
"description": "Only perform ironing on the very last layer of the mesh. This saves time if the lower layers don't need a smooth surface finish.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_pattern":
|
||||||
|
{
|
||||||
|
"label": "Ironing Pattern",
|
||||||
|
"description": "The pattern to use for ironing top surfaces.",
|
||||||
|
"type": "enum",
|
||||||
|
"options":
|
||||||
|
{
|
||||||
|
"concentric": "Concentric",
|
||||||
|
"zigzag": "Zig Zag"
|
||||||
|
},
|
||||||
|
"default_value": "zigzag",
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_line_spacing":
|
||||||
|
{
|
||||||
|
"label": "Ironing Line Spacing",
|
||||||
|
"description": "The distance between the lines of ironing.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "mm",
|
||||||
|
"default_value": 0.1,
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"maximum_value_warning": "machine_nozzle_tip_outer_diameter",
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_flow":
|
||||||
|
{
|
||||||
|
"label": "Ironing Flow",
|
||||||
|
"description": "The amount of material, relative to a normal skin line, to extrude during ironing. Keeping the nozzle filled helps filling some of the crevices of the top surface, but too much results in overextrusion and blips on the side of the surface.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "%",
|
||||||
|
"default_value": 10.0,
|
||||||
|
"minimum_value": "0",
|
||||||
|
"maximum_value_warning": "50",
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"ironing_inset":
|
||||||
|
{
|
||||||
|
"label": "Ironing Inset",
|
||||||
|
"description": "A distance to keep from the edges of the model. Ironing all the way to the edge of the mesh may result in a jagged edge on your print.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "mm",
|
||||||
|
"default_value": 0.35,
|
||||||
|
"value": "wall_line_width_0 / 2",
|
||||||
|
"minimum_value_warning": "0",
|
||||||
|
"maximum_value_warning": "wall_line_width_0",
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"speed_ironing":
|
||||||
|
{
|
||||||
|
"label": "Ironing Speed",
|
||||||
|
"description": "The speed at which to pass over the top surface.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "mm/s",
|
||||||
|
"default_value": 20.0,
|
||||||
|
"value": "speed_topbottom * 20 / 30",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||||
|
"maximum_value_warning": "100",
|
||||||
|
"enabled": "ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"acceleration_ironing":
|
||||||
|
{
|
||||||
|
"label": "Ironing Acceleration",
|
||||||
|
"description": "The acceleration with which ironing is performed.",
|
||||||
|
"unit": "mm/s²",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0.1",
|
||||||
|
"minimum_value_warning": "100",
|
||||||
|
"maximum_value_warning": "10000",
|
||||||
|
"default_value": 3000,
|
||||||
|
"value": "acceleration_topbottom",
|
||||||
|
"enabled": "resolveOrValue('acceleration_enabled') and ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"jerk_ironing":
|
||||||
|
{
|
||||||
|
"label": "Ironing Jerk",
|
||||||
|
"description": "The maximum instantaneous velocity change while performing ironing.",
|
||||||
|
"unit": "mm/s",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"maximum_value_warning": "50",
|
||||||
|
"default_value": 20,
|
||||||
|
"value": "jerk_topbottom",
|
||||||
|
"enabled": "resolveOrValue('jerk_enabled') and ironing_enabled",
|
||||||
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -3495,7 +3613,7 @@
|
||||||
"minimum_value_warning": "support_line_width",
|
"minimum_value_warning": "support_line_width",
|
||||||
"default_value": 2.66,
|
"default_value": 2.66,
|
||||||
"enabled": "support_enable",
|
"enabled": "support_enable",
|
||||||
"value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == 'grid' else (3 if support_pattern == 'triangles' else 1))",
|
"value": "0 if support_infill_rate == 0 else (support_line_width * 100) / support_infill_rate * (2 if support_pattern == 'grid' else (3 if support_pattern == 'triangles' else 1))",
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
|
@ -4132,30 +4250,6 @@
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"limit_to_extruder": "adhesion_extruder_nr"
|
"limit_to_extruder": "adhesion_extruder_nr"
|
||||||
},
|
},
|
||||||
"z_offset_layer_0":
|
|
||||||
{
|
|
||||||
"label": "Initial Layer Z Offset",
|
|
||||||
"description": "The extruder is offset from the normal height of the first layer by this amount. It can be positive (raised) or negative (lowered). Some filament types adhere to the build plate better if the extruder is raised slightly.",
|
|
||||||
"unit": "mm",
|
|
||||||
"type": "float",
|
|
||||||
"default_value": 0,
|
|
||||||
"minimum_value_warning": "0",
|
|
||||||
"maximum_value_warning": "layer_height_0",
|
|
||||||
"enabled": "resolveOrValue('adhesion_type') != 'raft'",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": false
|
|
||||||
},
|
|
||||||
"z_offset_taper_layers":
|
|
||||||
{
|
|
||||||
"label": "Z Offset Taper Layers",
|
|
||||||
"description": "When non-zero, the Z offset is reduced to 0 over that many layers. A value of 0 means that the Z offset remains constant for all the layers in the print.",
|
|
||||||
"type": "int",
|
|
||||||
"default_value": 0,
|
|
||||||
"minimum_value": "0",
|
|
||||||
"enabled": "resolveOrValue('adhesion_type') != 'raft' and z_offset_layer_0 != 0",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": false
|
|
||||||
},
|
|
||||||
"raft_margin":
|
"raft_margin":
|
||||||
{
|
{
|
||||||
"label": "Raft Extra Margin",
|
"label": "Raft Extra Margin",
|
||||||
|
@ -5099,7 +5193,8 @@
|
||||||
"default_value": false,
|
"default_value": false,
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_skip_some_zags": {
|
"support_skip_some_zags":
|
||||||
|
{
|
||||||
"label": "Break Up Support In Chunks",
|
"label": "Break Up Support In Chunks",
|
||||||
"description": "Skip some support line connections to make the support structure easier to break away. This setting is applicable to the Zig Zag support infill pattern.",
|
"description": "Skip some support line connections to make the support structure easier to break away. This setting is applicable to the Zig Zag support infill pattern.",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
|
@ -5107,35 +5202,36 @@
|
||||||
"enabled": "support_enable and (support_pattern == 'zigzag')",
|
"enabled": "support_enable and (support_pattern == 'zigzag')",
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"support_skip_zag_per_mm":
|
||||||
|
{
|
||||||
|
"label": "Support Chunk Size",
|
||||||
|
"description": "Leave out a connection between support lines once every N millimeter to make the support structure easier to break away.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "mm",
|
||||||
|
"default_value": 20,
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "support_line_distance",
|
||||||
|
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"children": {
|
"children":
|
||||||
"support_skip_zag_per_mm": {
|
{
|
||||||
"label": "Support Chunk Size",
|
"support_zag_skip_count":
|
||||||
"description": "Leave out a connection between support lines once every N millimeter to make the support structure easier to break away.",
|
{
|
||||||
"type": "float",
|
"label": "Support Chunk Line Count",
|
||||||
"unit": "mm",
|
"description": "Skip one in every N connection lines to make the support structure easier to break away.",
|
||||||
"default_value": 20,
|
"type": "int",
|
||||||
"minimum_value": "0",
|
"default_value": 5,
|
||||||
"minimum_value_warning": "support_line_distance",
|
"value": "0 if support_line_distance == 0 else round(support_skip_zag_per_mm / support_line_distance)",
|
||||||
|
"minimum_value": "1",
|
||||||
|
"minimum_value_warning": "3",
|
||||||
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
|
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true
|
||||||
"children": {
|
|
||||||
"support_zag_skip_count": {
|
|
||||||
"label": "Support Chunk Line Count",
|
|
||||||
"description": "Skip one in every N connection lines to make the support structure easier to break away.",
|
|
||||||
"type": "int",
|
|
||||||
"default_value": 5,
|
|
||||||
"value": "round(support_skip_zag_per_mm / support_line_distance)",
|
|
||||||
"minimum_value": "1",
|
|
||||||
"minimum_value_warning": "3",
|
|
||||||
"enabled": "support_enable and (support_pattern == 'zigzag') and support_skip_some_zags",
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -5835,124 +5931,6 @@
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": false,
|
"settable_per_extruder": false,
|
||||||
"settable_per_meshgroup": false
|
"settable_per_meshgroup": false
|
||||||
},
|
|
||||||
"ironing_enabled":
|
|
||||||
{
|
|
||||||
"label": "Enable Ironing",
|
|
||||||
"description": "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface.",
|
|
||||||
"type": "bool",
|
|
||||||
"default_value": false,
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"ironing_only_highest_layer":
|
|
||||||
{
|
|
||||||
"label": "Iron Only Highest Layer",
|
|
||||||
"description": "Only perform ironing on the very last layer of the mesh. This saves time if the lower layers don't need a smooth surface finish.",
|
|
||||||
"type": "bool",
|
|
||||||
"default_value": false,
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"ironing_pattern":
|
|
||||||
{
|
|
||||||
"label": "Ironing Pattern",
|
|
||||||
"description": "The pattern to use for ironing top surfaces.",
|
|
||||||
"type": "enum",
|
|
||||||
"options":
|
|
||||||
{
|
|
||||||
"concentric": "Concentric",
|
|
||||||
"zigzag": "Zig Zag"
|
|
||||||
},
|
|
||||||
"default_value": "zigzag",
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"ironing_line_spacing":
|
|
||||||
{
|
|
||||||
"label": "Ironing Line Spacing",
|
|
||||||
"description": "The distance between the lines of ironing.",
|
|
||||||
"type": "float",
|
|
||||||
"unit": "mm",
|
|
||||||
"default_value": 0.1,
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"maximum_value_warning": "machine_nozzle_tip_outer_diameter",
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"ironing_flow":
|
|
||||||
{
|
|
||||||
"label": "Ironing Flow",
|
|
||||||
"description": "The amount of material, relative to a normal skin line, to extrude during ironing. Keeping the nozzle filled helps filling some of the crevices of the top surface, but too much results in overextrusion and blips on the side of the surface.",
|
|
||||||
"type": "float",
|
|
||||||
"unit": "%",
|
|
||||||
"default_value": 10.0,
|
|
||||||
"minimum_value": "0",
|
|
||||||
"maximum_value_warning": "50",
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"ironing_inset":
|
|
||||||
{
|
|
||||||
"label": "Ironing Inset",
|
|
||||||
"description": "A distance to keep from the edges of the model. Ironing all the way to the edge of the mesh may result in a jagged edge on your print.",
|
|
||||||
"type": "float",
|
|
||||||
"unit": "mm",
|
|
||||||
"default_value": 0.35,
|
|
||||||
"value": "wall_line_width_0 / 2",
|
|
||||||
"minimum_value_warning": "0",
|
|
||||||
"maximum_value_warning": "wall_line_width_0",
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"speed_ironing":
|
|
||||||
{
|
|
||||||
"label": "Ironing Speed",
|
|
||||||
"description": "The speed at which to pass over the top surface.",
|
|
||||||
"type": "float",
|
|
||||||
"unit": "mm/s",
|
|
||||||
"default_value": 20.0,
|
|
||||||
"value": "speed_topbottom * 20 / 30",
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
|
||||||
"maximum_value_warning": "100",
|
|
||||||
"enabled": "ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"acceleration_ironing":
|
|
||||||
{
|
|
||||||
"label": "Ironing Acceleration",
|
|
||||||
"description": "The acceleration with which ironing is performed.",
|
|
||||||
"unit": "mm/s²",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0.1",
|
|
||||||
"minimum_value_warning": "100",
|
|
||||||
"maximum_value_warning": "10000",
|
|
||||||
"default_value": 3000,
|
|
||||||
"value": "acceleration_topbottom",
|
|
||||||
"enabled": "resolveOrValue('acceleration_enabled') and ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"jerk_ironing":
|
|
||||||
{
|
|
||||||
"label": "Ironing Jerk",
|
|
||||||
"description": "The maximum instantaneous velocity change while performing ironing.",
|
|
||||||
"unit": "mm/s",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"maximum_value_warning": "50",
|
|
||||||
"default_value": 20,
|
|
||||||
"value": "jerk_topbottom",
|
|
||||||
"enabled": "resolveOrValue('jerk_enabled') and ironing_enabled",
|
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"material_diameter": {
|
"material_diameter": {
|
||||||
"default_value": 1.75,
|
"default_value": 1.75
|
||||||
},
|
},
|
||||||
"machine_width": {
|
"machine_width": {
|
||||||
"default_value": 200
|
"default_value": 200
|
||||||
|
|
4389
resources/i18n/ja_JP/cura.po
Normal file
4389
resources/i18n/ja_JP/cura.po
Normal file
File diff suppressed because it is too large
Load diff
|
@ -177,7 +177,7 @@ UM.MainWindow
|
||||||
|
|
||||||
MenuSeparator { }
|
MenuSeparator { }
|
||||||
|
|
||||||
MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: ExtruderManager.setActiveExtruderIndex(model.index) }
|
MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) }
|
||||||
}
|
}
|
||||||
onObjectAdded: settingsMenu.insertItem(index, object)
|
onObjectAdded: settingsMenu.insertItem(index, object)
|
||||||
onObjectRemoved: settingsMenu.removeItem(object)
|
onObjectRemoved: settingsMenu.removeItem(object)
|
||||||
|
|
|
@ -18,7 +18,7 @@ Button
|
||||||
style: UM.Theme.styles.tool_button;
|
style: UM.Theme.styles.tool_button;
|
||||||
iconSource: UM.Theme.getIcon("extruder_button")
|
iconSource: UM.Theme.getIcon("extruder_button")
|
||||||
|
|
||||||
checked: ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1
|
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1
|
||||||
enabled: UM.Selection.hasSelection
|
enabled: UM.Selection.hasSelection
|
||||||
|
|
||||||
property color customColor: base.hovered ? UM.Theme.getColor("button_hover") : UM.Theme.getColor("button");
|
property color customColor: base.hovered ? UM.Theme.getColor("button_hover") : UM.Theme.getColor("button");
|
||||||
|
|
|
@ -31,7 +31,7 @@ Menu
|
||||||
visible: base.shouldShowExtruders
|
visible: base.shouldShowExtruders
|
||||||
enabled: UM.Selection.hasSelection
|
enabled: UM.Selection.hasSelection
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: ExtruderManager.selectedObjectExtruders.indexOf(model.id) != -1
|
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(model.id) != -1
|
||||||
onTriggered: CuraActions.setExtruderForSelection(model.id)
|
onTriggered: CuraActions.setExtruderForSelection(model.id)
|
||||||
shortcut: "Ctrl+" + (model.index + 1)
|
shortcut: "Ctrl+" + (model.index + 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,16 +78,16 @@ Menu
|
||||||
{
|
{
|
||||||
text: model.name
|
text: model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]]
|
checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
onTriggered:
|
onTriggered:
|
||||||
{
|
{
|
||||||
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
|
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
|
||||||
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
|
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
|
||||||
var activeExtruderIndex = ExtruderManager.activeExtruderIndex;
|
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
||||||
Cura.MachineManager.setActiveMaterial(model.id);
|
Cura.MachineManager.setActiveMaterial(model.id);
|
||||||
ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onObjectAdded: menu.insertItem(index, object)
|
onObjectAdded: menu.insertItem(index, object)
|
||||||
|
@ -121,16 +121,16 @@ Menu
|
||||||
{
|
{
|
||||||
text: model.name
|
text: model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.id == Cura.MachineManager.allActiveMaterialIds[ExtruderManager.extruderIds[extruderIndex]]
|
checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
onTriggered:
|
onTriggered:
|
||||||
{
|
{
|
||||||
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
|
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
|
||||||
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
|
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
|
||||||
var activeExtruderIndex = ExtruderManager.activeExtruderIndex;
|
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
||||||
Cura.MachineManager.setActiveMaterial(model.id);
|
Cura.MachineManager.setActiveMaterial(model.id);
|
||||||
ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onObjectAdded: brandMaterialsMenu.insertItem(index, object)
|
onObjectAdded: brandMaterialsMenu.insertItem(index, object)
|
||||||
|
|
|
@ -44,15 +44,15 @@ Menu
|
||||||
visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex && !isClusterPrinter
|
visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex && !isClusterPrinter
|
||||||
onTriggered:
|
onTriggered:
|
||||||
{
|
{
|
||||||
var activeExtruderIndex = ExtruderManager.activeExtruderIndex;
|
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
||||||
var hotendId = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex];
|
var hotendId = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex];
|
||||||
var itemIndex = nozzleInstantiator.model.find("name", hotendId);
|
var itemIndex = nozzleInstantiator.model.find("name", hotendId);
|
||||||
if(itemIndex > -1)
|
if(itemIndex > -1)
|
||||||
{
|
{
|
||||||
Cura.MachineManager.setActiveVariant(nozzleInstantiator.model.getItem(itemIndex).id);
|
Cura.MachineManager.setActiveVariant(nozzleInstantiator.model.getItem(itemIndex).id);
|
||||||
}
|
}
|
||||||
ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,14 +75,14 @@ Menu
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: model.name
|
text: model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model.id == Cura.MachineManager.allActiveVariantIds[ExtruderManager.extruderIds[extruderIndex]]
|
checked: model.id == Cura.MachineManager.allActiveVariantIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
onTriggered:
|
onTriggered:
|
||||||
{
|
{
|
||||||
var activeExtruderIndex = ExtruderManager.activeExtruderIndex;
|
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
|
||||||
Cura.MachineManager.setActiveVariant(model.id);
|
Cura.MachineManager.setActiveVariant(model.id);
|
||||||
ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onObjectAdded: menu.insertItem(index, object)
|
onObjectAdded: menu.insertItem(index, object)
|
||||||
|
|
|
@ -41,7 +41,7 @@ Menu
|
||||||
|
|
||||||
MenuItem
|
MenuItem
|
||||||
{
|
{
|
||||||
text: model.name + " - " + model.layer_height
|
text: model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: Cura.MachineManager.activeQualityChangesId == model.id
|
checked: Cura.MachineManager.activeQualityChangesId == model.id
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
|
|
|
@ -208,7 +208,7 @@ UM.ManagementPage
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
currentIndex: ExtruderManager.extruderCount > 0 ? ExtruderManager.activeExtruderIndex + 1 : 0
|
currentIndex: Cura.ExtruderManager.extruderCount > 0 ? Cura.ExtruderManager.activeExtruderIndex + 1 : 0
|
||||||
|
|
||||||
ProfileTab
|
ProfileTab
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,7 @@ Column
|
||||||
|
|
||||||
Label //Extruder name.
|
Label //Extruder name.
|
||||||
{
|
{
|
||||||
text: ExtruderManager.getExtruderName(index) != "" ? ExtruderManager.getExtruderName(index) : catalog.i18nc("@label", "Extruder")
|
text: Cura.ExtruderManager.getExtruderName(index) != "" ? Cura.ExtruderManager.getExtruderName(index) : catalog.i18nc("@label", "Extruder")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
|
@ -157,7 +157,7 @@ Item {
|
||||||
var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders") + ".";
|
var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders") + ".";
|
||||||
if ((resolve != "None") && (stackLevel != 0)) {
|
if ((resolve != "None") && (stackLevel != 0)) {
|
||||||
// We come here if a setting has a resolve and the setting is not manually edited.
|
// We come here if a setting has a resolve and the setting is not manually edited.
|
||||||
tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + ExtruderManager.getInstanceExtruderValues(definition.key) + "].";
|
tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "].";
|
||||||
}
|
}
|
||||||
base.showTooltip(tooltipText);
|
base.showTooltip(tooltipText);
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ Item
|
||||||
Behavior on opacity { NumberAnimation { duration: 100 } }
|
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||||
enabled:
|
enabled:
|
||||||
{
|
{
|
||||||
if(!ExtruderManager.activeExtruderStackId && machineExtruderCount.properties.value > 1)
|
if (!Cura.ExtruderManager.activeExtruderStackId && machineExtruderCount.properties.value > 1)
|
||||||
{
|
{
|
||||||
// disable all controls on the global tab, except categories
|
// disable all controls on the global tab, except categories
|
||||||
return model.type == "category"
|
return model.type == "category"
|
||||||
|
@ -345,12 +345,12 @@ Item
|
||||||
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
|
if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
|
||||||
{
|
{
|
||||||
//We have limit_to_extruder, so pick that stack.
|
//We have limit_to_extruder, so pick that stack.
|
||||||
return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
|
return Cura.ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
|
||||||
}
|
}
|
||||||
if(ExtruderManager.activeExtruderStackId)
|
if(Cura.ExtruderManager.activeExtruderStackId)
|
||||||
{
|
{
|
||||||
//We're on an extruder tab. Pick the current extruder.
|
//We're on an extruder tab. Pick the current extruder.
|
||||||
return ExtruderManager.activeExtruderStackId;
|
return Cura.ExtruderManager.activeExtruderStackId;
|
||||||
}
|
}
|
||||||
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
|
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
|
||||||
return activeMachineId;
|
return activeMachineId;
|
||||||
|
|
|
@ -14,7 +14,7 @@ Column
|
||||||
{
|
{
|
||||||
id: base;
|
id: base;
|
||||||
|
|
||||||
property int currentExtruderIndex: ExtruderManager.activeExtruderIndex;
|
property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex;
|
||||||
property bool currentExtruderVisible: extrudersList.visible;
|
property bool currentExtruderVisible: extrudersList.visible;
|
||||||
|
|
||||||
spacing: Math.floor(UM.Theme.getSize("sidebar_margin").width * 0.9)
|
spacing: Math.floor(UM.Theme.getSize("sidebar_margin").width * 0.9)
|
||||||
|
@ -93,7 +93,7 @@ Column
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
|
forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
|
||||||
ExtruderManager.setActiveExtruderIndex(index);
|
Cura.ExtruderManager.setActiveExtruderIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
style: ButtonStyle
|
style: ButtonStyle
|
||||||
|
|
|
@ -19,7 +19,7 @@ Item
|
||||||
property Action configureSettings;
|
property Action configureSettings;
|
||||||
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
|
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
|
||||||
property variant maximumPrintTime: PrintInformation.maximumPrintTime;
|
property variant maximumPrintTime: PrintInformation.maximumPrintTime;
|
||||||
property bool settingsEnabled: ExtruderManager.activeExtruderStackId || machineExtruderCount.properties.value == 1
|
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || machineExtruderCount.properties.value == 1
|
||||||
|
|
||||||
Component.onCompleted: PrintInformation.enabled = true
|
Component.onCompleted: PrintInformation.enabled = true
|
||||||
Component.onDestruction: PrintInformation.enabled = false
|
Component.onDestruction: PrintInformation.enabled = false
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_abs_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
cool_fan_speed = 40
|
||||||
|
infill_overlap = 15
|
||||||
|
material_final_print_temperature = =material_print_temperature - 5
|
||||||
|
prime_tower_enable = True
|
||||||
|
prime_tower_purge_volume = 0.6
|
||||||
|
prime_tower_size = 12
|
||||||
|
prime_tower_wall_thickness = 0.9
|
||||||
|
retraction_prime_speed = 25
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 30 / 55)
|
||||||
|
wall_thickness = 0.92
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_cpe_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
infill_overlap = =10 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0
|
||||||
|
prime_tower_size = 12
|
||||||
|
prime_tower_wall_thickness = 0.9
|
||||||
|
retraction_extrusion_window = 0.5
|
||||||
|
speed_infill = 40
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 30 / 55)
|
||||||
|
top_bottom_thickness = 0.8
|
||||||
|
wall_thickness = 0.92
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_nylon_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
cool_min_layer_time_fan_speed_max = 20
|
||||||
|
cool_min_speed = 12
|
||||||
|
infill_line_width = =round(line_width * 0.5 / 0.4, 2)
|
||||||
|
infill_overlap = =10 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0
|
||||||
|
machine_nozzle_cool_down_speed = 0.9
|
||||||
|
machine_nozzle_heat_up_speed = 2.0
|
||||||
|
ooze_shield_angle = 40
|
||||||
|
raft_acceleration = =acceleration_layer_0
|
||||||
|
raft_airgap = =round(layer_height_0 * 0.85, 2)
|
||||||
|
raft_interface_thickness = =round(machine_nozzle_size * 0.3 / 0.4, 3)
|
||||||
|
raft_jerk = =jerk_layer_0
|
||||||
|
raft_margin = 10
|
||||||
|
raft_surface_thickness = =round(machine_nozzle_size * 0.2 / 0.4, 2)
|
||||||
|
retraction_extrusion_window = =retraction_amount
|
||||||
|
retraction_min_travel = =line_width * 2
|
||||||
|
skin_overlap = 50
|
||||||
|
speed_print = 70
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 30 / 70)
|
||||||
|
speed_wall = =math.ceil(speed_print * 30 / 70)
|
||||||
|
switch_extruder_prime_speed = 30
|
||||||
|
switch_extruder_retraction_amount = 30
|
||||||
|
switch_extruder_retraction_speeds = 40
|
||||||
|
wall_line_width_x = =wall_line_width
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine - Experimental
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_pc_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 4000
|
||||||
|
adhesion_type = brim
|
||||||
|
brim_width = 20
|
||||||
|
cool_fan_full_at_height = =layer_height_0 + layer_height
|
||||||
|
cool_fan_speed_max = 50
|
||||||
|
cool_min_layer_time_fan_speed_max = 5
|
||||||
|
cool_min_speed = 5
|
||||||
|
infill_line_width = =line_width
|
||||||
|
infill_pattern = triangles
|
||||||
|
infill_wipe_dist = 0.1
|
||||||
|
jerk_enabled = True
|
||||||
|
jerk_print = 25
|
||||||
|
machine_min_cool_heat_time_window = 15
|
||||||
|
multiple_mesh_overlap = 0
|
||||||
|
ooze_shield_angle = 40
|
||||||
|
prime_tower_enable = True
|
||||||
|
retraction_count_max = 80
|
||||||
|
retraction_hop = 2
|
||||||
|
retraction_hop_enabled = True
|
||||||
|
retraction_hop_only_when_collides = True
|
||||||
|
retraction_min_travel = 0.8
|
||||||
|
retraction_prime_speed = 15
|
||||||
|
skin_overlap = 30
|
||||||
|
speed_layer_0 = 25
|
||||||
|
speed_print = 50
|
||||||
|
speed_topbottom = 25
|
||||||
|
speed_travel = 250
|
||||||
|
speed_wall = =math.ceil(speed_print * 40 / 50)
|
||||||
|
speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
|
||||||
|
support_bottom_distance = =support_z_distance
|
||||||
|
support_interface_density = 87.5
|
||||||
|
support_interface_pattern = lines
|
||||||
|
switch_extruder_prime_speed = 15
|
||||||
|
switch_extruder_retraction_amount = 20
|
||||||
|
switch_extruder_retraction_speeds = 35
|
||||||
|
wall_0_inset = 0
|
||||||
|
wall_line_width_x = =line_width
|
||||||
|
wall_thickness = 1.2
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_pla_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
brim_width = 8
|
||||||
|
cool_fan_full_at_height = =layer_height_0
|
||||||
|
cool_min_speed = 10
|
||||||
|
infill_overlap = 10
|
||||||
|
infill_pattern = grid
|
||||||
|
machine_nozzle_cool_down_speed = 0.9
|
||||||
|
machine_nozzle_heat_up_speed = 2.0
|
||||||
|
material_final_print_temperature = =max(-273.15, material_print_temperature - 15)
|
||||||
|
material_initial_print_temperature = =max(-273.15, material_print_temperature - 10)
|
||||||
|
material_print_temperature = 190
|
||||||
|
retraction_extrusion_window = =retraction_amount
|
||||||
|
retraction_hop = 0.2
|
||||||
|
skin_overlap = 5
|
||||||
|
speed_layer_0 = 30
|
||||||
|
speed_print = 30
|
||||||
|
speed_travel_layer_0 = 120
|
||||||
|
speed_wall = 25
|
||||||
|
speed_wall_0 = 20
|
||||||
|
top_bottom_thickness = 0.72
|
||||||
|
travel_avoid_distance = 0.4
|
||||||
|
wall_0_inset = 0.015
|
||||||
|
wall_0_wipe_dist = 0.25
|
||||||
|
wall_thickness = 0.7
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine - Experimental
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_pp_ultimaker3_AA_0.25
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 4000
|
||||||
|
brim_width = 10
|
||||||
|
cool_fan_speed_max = 100
|
||||||
|
cool_min_layer_time_fan_speed_max = 5
|
||||||
|
cool_min_speed = 2.5
|
||||||
|
infill_line_width = =round(line_width * 0.38 / 0.38, 2)
|
||||||
|
infill_pattern = tetrahedral
|
||||||
|
infill_wipe_dist = 0.1
|
||||||
|
jerk_enabled = True
|
||||||
|
jerk_print = 25
|
||||||
|
line_width = =machine_nozzle_size * 0.92
|
||||||
|
machine_min_cool_heat_time_window = 15
|
||||||
|
material_bed_temperature_layer_0 = 90
|
||||||
|
material_final_print_temperature = 195
|
||||||
|
material_initial_print_temperature = 200
|
||||||
|
material_print_temperature = 205
|
||||||
|
material_print_temperature_layer_0 = 208
|
||||||
|
multiple_mesh_overlap = 0
|
||||||
|
prime_tower_enable = False
|
||||||
|
prime_tower_size = 16
|
||||||
|
prime_tower_wipe_enabled = True
|
||||||
|
retraction_count_max = 6
|
||||||
|
retraction_extra_prime_amount = 0.2
|
||||||
|
retraction_extrusion_window = 6.5
|
||||||
|
retraction_hop = 2
|
||||||
|
retraction_hop_enabled = True
|
||||||
|
retraction_hop_only_when_collides = True
|
||||||
|
retraction_min_travel = 0.8
|
||||||
|
retraction_prime_speed = 13
|
||||||
|
speed_equalize_flow_enabled = True
|
||||||
|
speed_layer_0 = 15
|
||||||
|
speed_print = 25
|
||||||
|
speed_travel = 300
|
||||||
|
speed_travel_layer_0 = 50
|
||||||
|
speed_wall = =math.ceil(speed_print * 25 / 25)
|
||||||
|
speed_wall_0 = =math.ceil(speed_wall * 25 / 25)
|
||||||
|
support_angle = 50
|
||||||
|
switch_extruder_prime_speed = 15
|
||||||
|
switch_extruder_retraction_amount = 20
|
||||||
|
switch_extruder_retraction_speeds = 35
|
||||||
|
top_bottom_thickness = 1
|
||||||
|
travel_avoid_distance = 3
|
||||||
|
wall_0_inset = 0
|
||||||
|
wall_line_width_x = =line_width
|
||||||
|
wall_thickness = =line_width * 3
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fast
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = draft
|
||||||
|
material = generic_bam_ultimaker3_AA_0.4
|
||||||
|
weight = -2
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
|
||||||
|
cool_fan_speed_max = =cool_fan_speed
|
||||||
|
machine_nozzle_cool_down_speed = 0.75
|
||||||
|
machine_nozzle_heat_up_speed = 1.6
|
||||||
|
material_print_temperature = =230
|
||||||
|
material_standby_temperature = 100
|
||||||
|
# prime_tower_enable: see CURA-4248
|
||||||
|
prime_tower_enable = =min(extruderValues('material_surface_energy')) < 100
|
||||||
|
skin_overlap = 20
|
||||||
|
speed_layer_0 = 20
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 35 / 70)
|
||||||
|
speed_wall = =math.ceil(speed_print * 50 / 70)
|
||||||
|
speed_wall_0 = =math.ceil(speed_wall * 35 / 50)
|
||||||
|
top_bottom_thickness = 1
|
||||||
|
wall_thickness = 1
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_density = =min(extruderValues('material_surface_energy'))
|
||||||
|
support_interface_pattern = ='lines' if support_interface_density < 100 else 'concentric'
|
||||||
|
support_top_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 2) * layer_height
|
||||||
|
support_bottom_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 2) * layer_height
|
||||||
|
support_angle = 45
|
||||||
|
support_join_distance = 5
|
||||||
|
support_offset = 2
|
||||||
|
support_pattern = triangles
|
||||||
|
support_infill_rate = 10
|
|
@ -0,0 +1,38 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Normal
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = fast
|
||||||
|
material = generic_bam_ultimaker3_AA_0.4
|
||||||
|
weight = -1
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
default_material_print_temperature = 225
|
||||||
|
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
|
||||||
|
cool_fan_speed_max = =cool_fan_speed
|
||||||
|
machine_nozzle_cool_down_speed = 0.75
|
||||||
|
machine_nozzle_heat_up_speed = 1.6
|
||||||
|
material_standby_temperature = 100
|
||||||
|
# prime_tower_enable: see CURA-4248
|
||||||
|
prime_tower_enable = =min(extruderValues('material_surface_energy')) < 100
|
||||||
|
speed_print = 80
|
||||||
|
speed_layer_0 = 20
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 30 / 80)
|
||||||
|
speed_wall = =math.ceil(speed_print * 40 / 80)
|
||||||
|
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
|
||||||
|
top_bottom_thickness = 1
|
||||||
|
wall_thickness = 1
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_density = =min(extruderValues('material_surface_energy'))
|
||||||
|
support_interface_pattern = ='lines' if support_interface_density < 100 else 'concentric'
|
||||||
|
support_top_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 1) * layer_height
|
||||||
|
support_bottom_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 2) * layer_height
|
||||||
|
support_angle = 45
|
||||||
|
support_join_distance = 5
|
||||||
|
support_offset = 2
|
||||||
|
support_pattern = triangles
|
||||||
|
support_infill_rate = 10
|
|
@ -0,0 +1,36 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = Fine
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
material = generic_bam_ultimaker3_AA_0.4
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
default_material_print_temperature = 225
|
||||||
|
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
|
||||||
|
cool_fan_speed_max = =cool_fan_speed
|
||||||
|
cool_min_speed = 7
|
||||||
|
machine_nozzle_cool_down_speed = 0.75
|
||||||
|
machine_nozzle_heat_up_speed = 1.6
|
||||||
|
material_standby_temperature = 100
|
||||||
|
# prime_tower_enable: see CURA-4248
|
||||||
|
prime_tower_enable = =min(extruderValues('material_surface_energy')) < 100
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_layer_0 = 20
|
||||||
|
top_bottom_thickness = 1
|
||||||
|
wall_thickness = 1
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_density = =min(extruderValues('material_surface_energy'))
|
||||||
|
support_interface_pattern = ='lines' if support_interface_density < 100 else 'concentric'
|
||||||
|
support_top_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 1) * layer_height
|
||||||
|
support_bottom_distance = =math.ceil(min(extruderValues('material_adhesion_tendency')) / 2) * layer_height
|
||||||
|
support_angle = 45
|
||||||
|
support_join_distance = 5
|
||||||
|
support_offset = 2
|
||||||
|
support_pattern = triangles
|
||||||
|
support_infill_rate = 10
|
|
@ -83,8 +83,8 @@
|
||||||
|
|
||||||
"error": [255, 140, 0, 255],
|
"error": [255, 140, 0, 255],
|
||||||
"sidebar_header_bar": [31, 36, 39, 255],
|
"sidebar_header_bar": [31, 36, 39, 255],
|
||||||
"sidebar_header_active": [31, 36, 39, 255],
|
"sidebar_header_active": [68, 72, 75, 255],
|
||||||
"sidebar_header_hover": [31, 36, 39, 255],
|
"sidebar_header_hover": [68, 72, 75, 255],
|
||||||
"sidebar_header_highlight": [68, 192, 255, 255],
|
"sidebar_header_highlight": [68, 192, 255, 255],
|
||||||
"sidebar_header_highlight_hover": [68, 192, 255, 255],
|
"sidebar_header_highlight_hover": [68, 192, 255, 255],
|
||||||
"sidebar_header_text_inactive": [255, 255, 255, 255],
|
"sidebar_header_text_inactive": [255, 255, 255, 255],
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
"button_text_hover": [255, 255, 255, 255],
|
"button_text_hover": [255, 255, 255, 255],
|
||||||
"button_text_active": [255, 255, 255, 255],
|
"button_text_active": [255, 255, 255, 255],
|
||||||
"button_text_active_hover": [255, 255, 255, 255],
|
"button_text_active_hover": [255, 255, 255, 255],
|
||||||
"button_disabled": [24, 41, 77, 255],
|
"button_disabled": [31, 36, 39, 255],
|
||||||
"button_disabled_text": [255, 255, 255, 101],
|
"button_disabled_text": [255, 255, 255, 101],
|
||||||
|
|
||||||
"button_tooltip": [31, 36, 39, 255],
|
"button_tooltip": [31, 36, 39, 255],
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
"action_button_text": [0, 0, 0, 255],
|
"action_button_text": [0, 0, 0, 255],
|
||||||
"action_button_border": [127, 127, 127, 255],
|
"action_button_border": [127, 127, 127, 255],
|
||||||
"action_button_hovered": [255, 255, 255, 255],
|
"action_button_hovered": [255, 255, 255, 255],
|
||||||
"action_button_hovered_text": [24, 41, 77, 255],
|
"action_button_hovered_text": [31, 36, 39, 255],
|
||||||
"action_button_hovered_border": [12, 169, 227, 255],
|
"action_button_hovered_border": [12, 169, 227, 255],
|
||||||
"action_button_active": [255, 255, 255, 255],
|
"action_button_active": [255, 255, 255, 255],
|
||||||
"action_button_active_text": [0, 0, 0, 255],
|
"action_button_active_text": [0, 0, 0, 255],
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
"print_button_ready_pressed_border": [30, 186, 245, 243],
|
"print_button_ready_pressed_border": [30, 186, 245, 243],
|
||||||
|
|
||||||
"scrollbar_background": [255, 255, 255, 255],
|
"scrollbar_background": [255, 255, 255, 255],
|
||||||
"scrollbar_handle": [24, 41, 77, 255],
|
"scrollbar_handle": [31, 36, 39, 255],
|
||||||
"scrollbar_handle_hover": [12, 159, 227, 255],
|
"scrollbar_handle_hover": [12, 159, 227, 255],
|
||||||
"scrollbar_handle_down": [12, 159, 227, 255],
|
"scrollbar_handle_down": [12, 159, 227, 255],
|
||||||
|
|
||||||
|
@ -143,11 +143,11 @@
|
||||||
"setting_category_hover": [245, 245, 245, 255],
|
"setting_category_hover": [245, 245, 245, 255],
|
||||||
"setting_category_active": [245, 245, 245, 255],
|
"setting_category_active": [245, 245, 245, 255],
|
||||||
"setting_category_active_hover": [245, 245, 245, 255],
|
"setting_category_active_hover": [245, 245, 245, 255],
|
||||||
"setting_category_text": [24, 41, 77, 255],
|
"setting_category_text": [31, 36, 39, 255],
|
||||||
"setting_category_disabled_text": [24, 41, 77, 101],
|
"setting_category_disabled_text": [24, 41, 77, 101],
|
||||||
"setting_category_hover_text": [24, 41, 77, 255],
|
"setting_category_hover_text": [31, 36, 39, 255],
|
||||||
"setting_category_active_text": [24, 41, 77, 255],
|
"setting_category_active_text": [31, 36, 39, 255],
|
||||||
"setting_category_active_hover_text": [24, 41, 77, 255],
|
"setting_category_active_hover_text": [31, 36, 39, 255],
|
||||||
"setting_category_border": [245, 245, 245, 255],
|
"setting_category_border": [245, 245, 245, 255],
|
||||||
"setting_category_disabled_border": [245, 245, 245, 255],
|
"setting_category_disabled_border": [245, 245, 245, 255],
|
||||||
"setting_category_hover_border": [12, 159, 227, 255],
|
"setting_category_hover_border": [12, 159, 227, 255],
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
"setting_category_active_hover_border": [12, 159, 227, 255],
|
"setting_category_active_hover_border": [12, 159, 227, 255],
|
||||||
|
|
||||||
"setting_control": [255, 255, 255, 255],
|
"setting_control": [255, 255, 255, 255],
|
||||||
"setting_control_selected": [24, 41, 77, 255],
|
"setting_control_selected": [31, 36, 39, 255],
|
||||||
"setting_control_highlight": [255, 255, 255, 255],
|
"setting_control_highlight": [255, 255, 255, 255],
|
||||||
"setting_control_border": [127, 127, 127, 255],
|
"setting_control_border": [127, 127, 127, 255],
|
||||||
"setting_control_border_highlight": [12, 169, 227, 255],
|
"setting_control_border_highlight": [12, 169, 227, 255],
|
||||||
|
@ -203,9 +203,9 @@
|
||||||
"mode_switch_hover": [255, 255, 255, 255],
|
"mode_switch_hover": [255, 255, 255, 255],
|
||||||
"mode_switch_border": [127, 127, 127, 255],
|
"mode_switch_border": [127, 127, 127, 255],
|
||||||
"mode_switch_border_hover": [12, 169, 227, 255],
|
"mode_switch_border_hover": [12, 169, 227, 255],
|
||||||
"mode_switch_handle": [24, 41, 77, 255],
|
"mode_switch_handle": [31, 36, 39, 255],
|
||||||
"mode_switch_text": [24, 41, 77, 255],
|
"mode_switch_text": [31, 36, 39, 255],
|
||||||
"mode_switch_text_hover": [24, 41, 77, 255],
|
"mode_switch_text_hover": [31, 36, 39, 255],
|
||||||
"mode_switch_text_checked": [12, 169, 227, 255],
|
"mode_switch_text_checked": [12, 169, 227, 255],
|
||||||
|
|
||||||
"tooltip": [68, 192, 255, 255],
|
"tooltip": [68, 192, 255, 255],
|
||||||
|
|
40
resources/variants/ultimaker3_aa0.25.inst.cfg
Normal file
40
resources/variants/ultimaker3_aa0.25.inst.cfg
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[general]
|
||||||
|
name = AA 0.25
|
||||||
|
version = 2
|
||||||
|
definition = ultimaker3
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = ultimaker
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
brim_width = 7
|
||||||
|
infill_line_width = 0.23
|
||||||
|
infill_overlap = 0
|
||||||
|
layer_height_0 = 0.17
|
||||||
|
line_width = 0.23
|
||||||
|
machine_nozzle_cool_down_speed = 0.85
|
||||||
|
machine_nozzle_heat_up_speed = 1.5
|
||||||
|
machine_nozzle_id = AA 0.25
|
||||||
|
machine_nozzle_size = 0.25
|
||||||
|
machine_nozzle_tip_outer_diameter = 0.65
|
||||||
|
material_final_print_temperature = =material_print_temperature - 10
|
||||||
|
material_initial_print_temperature = =material_print_temperature - 5
|
||||||
|
raft_interface_thickness = =layer_height * 1.5
|
||||||
|
retraction_count_max = 25
|
||||||
|
retraction_extrusion_window = 1
|
||||||
|
retraction_min_travel = 0.7
|
||||||
|
skin_overlap = 15
|
||||||
|
speed_layer_0 = 20
|
||||||
|
speed_print = 55
|
||||||
|
speed_topbottom = 20
|
||||||
|
speed_wall = =math.ceil(speed_print * 30 / 55)
|
||||||
|
support_angle = 60
|
||||||
|
support_bottom_distance = =support_z_distance / 2
|
||||||
|
support_top_distance = =support_z_distance
|
||||||
|
support_z_distance = =layer_height * 2
|
||||||
|
top_bottom_thickness = 1.2
|
||||||
|
wall_line_width_x = 0.23
|
||||||
|
wall_thickness = 1.3
|
||||||
|
|
40
resources/variants/ultimaker3_extended_aa0.25.inst.cfg
Normal file
40
resources/variants/ultimaker3_extended_aa0.25.inst.cfg
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[general]
|
||||||
|
name = AA 0.25
|
||||||
|
version = 2
|
||||||
|
definition = ultimaker3_extended
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = ultimaker
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
brim_width = 7
|
||||||
|
infill_line_width = 0.23
|
||||||
|
infill_overlap = 0
|
||||||
|
layer_height_0 = 0.17
|
||||||
|
line_width = 0.23
|
||||||
|
machine_nozzle_cool_down_speed = 0.85
|
||||||
|
machine_nozzle_heat_up_speed = 1.5
|
||||||
|
machine_nozzle_id = AA 0.25
|
||||||
|
machine_nozzle_size = 0.25
|
||||||
|
machine_nozzle_tip_outer_diameter = 0.65
|
||||||
|
material_final_print_temperature = =material_print_temperature - 10
|
||||||
|
material_initial_print_temperature = =material_print_temperature - 5
|
||||||
|
raft_interface_thickness = =layer_height * 1.5
|
||||||
|
retraction_count_max = 25
|
||||||
|
retraction_extrusion_window = 1
|
||||||
|
retraction_min_travel = 0.7
|
||||||
|
skin_overlap = 15
|
||||||
|
speed_layer_0 = 20
|
||||||
|
speed_print = 55
|
||||||
|
speed_topbottom = 20
|
||||||
|
speed_wall = =math.ceil(speed_print * 30 / 55)
|
||||||
|
support_angle = 60
|
||||||
|
support_bottom_distance = =support_z_distance / 2
|
||||||
|
support_top_distance = =support_z_distance
|
||||||
|
support_z_distance = =layer_height * 2
|
||||||
|
top_bottom_thickness = 1.2
|
||||||
|
wall_line_width_x = 0.23
|
||||||
|
wall_thickness = 1.3
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue