mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-07-16 03:01:52 +08:00
commit
21cf47b352
@ -433,7 +433,8 @@ class BuildVolume(SceneNode):
|
|||||||
self._global_container_stack.getProperty("raft_interface_thickness", "value") +
|
self._global_container_stack.getProperty("raft_interface_thickness", "value") +
|
||||||
self._global_container_stack.getProperty("raft_surface_layers", "value") *
|
self._global_container_stack.getProperty("raft_surface_layers", "value") *
|
||||||
self._global_container_stack.getProperty("raft_surface_thickness", "value") +
|
self._global_container_stack.getProperty("raft_surface_thickness", "value") +
|
||||||
self._global_container_stack.getProperty("raft_airgap", "value"))
|
self._global_container_stack.getProperty("raft_airgap", "value") -
|
||||||
|
self._global_container_stack.getProperty("layer_0_z_overlap", "value"))
|
||||||
|
|
||||||
# Rounding errors do not matter, we check if raft_thickness has changed at all
|
# Rounding errors do not matter, we check if raft_thickness has changed at all
|
||||||
if old_raft_thickness != self._raft_thickness:
|
if old_raft_thickness != self._raft_thickness:
|
||||||
@ -562,7 +563,7 @@ class BuildVolume(SceneNode):
|
|||||||
used_extruders = [self._global_container_stack]
|
used_extruders = [self._global_container_stack]
|
||||||
|
|
||||||
result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) #Normal machine disallowed areas can always be added.
|
result_areas = self._computeDisallowedAreasStatic(disallowed_border_size, used_extruders) #Normal machine disallowed areas can always be added.
|
||||||
prime_areas = self._computeDisallowedAreasPrime(disallowed_border_size, used_extruders)
|
prime_areas = self._computeDisallowedAreasPrimeBlob(disallowed_border_size, used_extruders)
|
||||||
prime_disallowed_areas = self._computeDisallowedAreasStatic(0, used_extruders) #Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
|
prime_disallowed_areas = self._computeDisallowedAreasStatic(0, used_extruders) #Where the priming is not allowed to happen. This is not added to the result, just for collision checking.
|
||||||
|
|
||||||
#Check if prime positions intersect with disallowed areas.
|
#Check if prime positions intersect with disallowed areas.
|
||||||
@ -658,7 +659,7 @@ class BuildVolume(SceneNode):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
## Computes the disallowed areas for the prime locations.
|
## Computes the disallowed areas for the prime blobs.
|
||||||
#
|
#
|
||||||
# These are special because they are not subject to things like brim or
|
# These are special because they are not subject to things like brim or
|
||||||
# travel avoidance. They do get a dilute with the border size though
|
# travel avoidance. They do get a dilute with the border size though
|
||||||
@ -669,17 +670,18 @@ class BuildVolume(SceneNode):
|
|||||||
# \param used_extruders The extruder stacks to generate disallowed areas
|
# \param used_extruders The extruder stacks to generate disallowed areas
|
||||||
# for.
|
# for.
|
||||||
# \return A dictionary with for each used extruder ID the prime areas.
|
# \return A dictionary with for each used extruder ID the prime areas.
|
||||||
def _computeDisallowedAreasPrime(self, border_size, used_extruders):
|
def _computeDisallowedAreasPrimeBlob(self, border_size, used_extruders):
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||||
for extruder in used_extruders:
|
for extruder in used_extruders:
|
||||||
|
prime_blob_enabled = extruder.getProperty("prime_blob_enable", "value")
|
||||||
prime_x = extruder.getProperty("extruder_prime_pos_x", "value")
|
prime_x = extruder.getProperty("extruder_prime_pos_x", "value")
|
||||||
prime_y = - extruder.getProperty("extruder_prime_pos_y", "value")
|
prime_y = - extruder.getProperty("extruder_prime_pos_y", "value")
|
||||||
|
|
||||||
#Ignore extruder prime position if it is not set
|
#Ignore extruder prime position if it is not set or if blob is disabled
|
||||||
if prime_x == 0 and prime_y == 0:
|
if (prime_x == 0 and prime_y == 0) or not prime_blob_enabled:
|
||||||
result[extruder.getId()] = []
|
result[extruder.getId()] = []
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -950,9 +952,9 @@ class BuildVolume(SceneNode):
|
|||||||
return max(min(value, max_value), min_value)
|
return max(min(value, max_value), min_value)
|
||||||
|
|
||||||
_skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist"]
|
_skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_brim_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist"]
|
||||||
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap"]
|
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
|
||||||
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
|
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
|
||||||
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z"]
|
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z", "prime_blob_enable"]
|
||||||
_tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"]
|
_tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"]
|
||||||
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
|
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
|
||||||
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts"]
|
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts"]
|
||||||
|
@ -328,8 +328,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||||||
return self.__isDescendant(root, node.getParent())
|
return self.__isDescendant(root, node.getParent())
|
||||||
|
|
||||||
_affected_settings = [
|
_affected_settings = [
|
||||||
"adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers",
|
"adhesion_type", "raft_margin", "print_sequence",
|
||||||
"raft_surface_thickness", "raft_airgap", "raft_margin", "print_sequence",
|
|
||||||
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"]
|
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"]
|
||||||
|
|
||||||
## Settings that change the convex hull.
|
## Settings that change the convex hull.
|
||||||
|
@ -99,6 +99,11 @@ if not MYPY:
|
|||||||
|
|
||||||
|
|
||||||
class CuraApplication(QtApplication):
|
class CuraApplication(QtApplication):
|
||||||
|
# SettingVersion represents the set of settings available in the machine/extruder definitions.
|
||||||
|
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
|
||||||
|
# changes of the settings.
|
||||||
|
SettingVersion = 1
|
||||||
|
|
||||||
class ResourceTypes:
|
class ResourceTypes:
|
||||||
QmlFiles = Resources.UserType + 1
|
QmlFiles = Resources.UserType + 1
|
||||||
Firmware = Resources.UserType + 2
|
Firmware = Resources.UserType + 2
|
||||||
@ -169,11 +174,11 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
|
||||||
{
|
{
|
||||||
("quality", InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
|
||||||
("machine_stack", ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
("machine_stack", ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"),
|
||||||
("extruder_train", ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
("extruder_train", ContainerStack.Version): (self.ResourceTypes.ExtruderStack, "application/x-uranium-extruderstack"),
|
||||||
("preferences", Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
("preferences", Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"),
|
||||||
("user", InstanceContainer.Version): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
|
("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -620,7 +625,9 @@ class CuraApplication(QtApplication):
|
|||||||
camera.lookAt(Vector(0, 0, 0))
|
camera.lookAt(Vector(0, 0, 0))
|
||||||
controller.getScene().setActiveCamera("3d")
|
controller.getScene().setActiveCamera("3d")
|
||||||
|
|
||||||
self.getController().getTool("CameraTool").setOrigin(Vector(0, 100, 0))
|
camera_tool = self.getController().getTool("CameraTool")
|
||||||
|
camera_tool.setOrigin(Vector(0, 100, 0))
|
||||||
|
camera_tool.setZoomRange(0.1, 200000)
|
||||||
|
|
||||||
self._camera_animation = CameraAnimation.CameraAnimation()
|
self._camera_animation = CameraAnimation.CameraAnimation()
|
||||||
self._camera_animation.setCameraTool(self.getController().getTool("CameraTool"))
|
self._camera_animation.setCameraTool(self.getController().getTool("CameraTool"))
|
||||||
|
@ -31,8 +31,8 @@ catalog = i18nCatalog("cura")
|
|||||||
# - This triggers a new slice with the current settings - this is the "current settings pass".
|
# - This triggers a new slice with the current settings - this is the "current settings pass".
|
||||||
# - When the slice is done, we update the current print time and material amount.
|
# - When the slice is done, we update the current print time and material amount.
|
||||||
# - If the source of the slice was not a Setting change, we start the second slice pass, the "low quality settings pass". Otherwise we stop here.
|
# - If the source of the slice was not a Setting change, we start the second slice pass, the "low quality settings pass". Otherwise we stop here.
|
||||||
# - When that is done, we update the minimum print time and start the final slice pass, the "high quality settings pass".
|
# - When that is done, we update the minimum print time and start the final slice pass, the "Extra Fine settings pass".
|
||||||
# - When the high quality pass is done, we update the maximum print time.
|
# - When the Extra Fine pass is done, we update the maximum print time.
|
||||||
#
|
#
|
||||||
# This class also mangles the current machine name and the filename of the first loaded mesh into a job name.
|
# This class also mangles the current machine name and the filename of the first loaded mesh into a job name.
|
||||||
# This job name is requested by the JobSpecs qml file.
|
# This job name is requested by the JobSpecs qml file.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# This collects a lot of quality and quality changes related code which was split between ContainerManager
|
# This collects a lot of quality and quality changes related code which was split between ContainerManager
|
||||||
# and the MachineManager and really needs to usable from both.
|
# and the MachineManager and really needs to usable from both.
|
||||||
from typing import List
|
from typing import List, Optional, Dict, TYPE_CHECKING
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
@ -11,6 +11,10 @@ from UM.Settings.DefinitionContainer import DefinitionContainer
|
|||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
from UM.Settings.DefinitionContainer import DefinitionContainerInterface
|
||||||
|
|
||||||
class QualityManager:
|
class QualityManager:
|
||||||
|
|
||||||
@ -27,12 +31,12 @@ class QualityManager:
|
|||||||
## Find a quality by name for a specific machine definition and materials.
|
## Find a quality by name for a specific machine definition and materials.
|
||||||
#
|
#
|
||||||
# \param quality_name
|
# \param quality_name
|
||||||
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
|
# \param machine_definition (Optional) \type{DefinitionContainerInterface} If nothing is
|
||||||
# specified then the currently selected machine definition is used.
|
# specified then the currently selected machine definition is used.
|
||||||
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
# \param material_containers (Optional) \type{List[InstanceContainer]} If nothing is specified then
|
||||||
# the current set of selected materials is used.
|
# the current set of selected materials is used.
|
||||||
# \return the matching quality container \type{ContainerInstance}
|
# \return the matching quality container \type{InstanceContainer}
|
||||||
def findQualityByName(self, quality_name, machine_definition=None, material_containers=None):
|
def findQualityByName(self, quality_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers: List[InstanceContainer] = None) -> Optional[InstanceContainer]:
|
||||||
criteria = {"type": "quality", "name": quality_name}
|
criteria = {"type": "quality", "name": quality_name}
|
||||||
result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
||||||
|
|
||||||
@ -46,12 +50,10 @@ class QualityManager:
|
|||||||
## Find a quality changes container by name.
|
## Find a quality changes container by name.
|
||||||
#
|
#
|
||||||
# \param quality_changes_name \type{str} the name of the quality changes container.
|
# \param quality_changes_name \type{str} the name of the quality changes container.
|
||||||
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
|
# \param machine_definition (Optional) \type{DefinitionContainer} If nothing is
|
||||||
# specified then the currently selected machine definition is used.
|
# specified then the currently selected machine definition is used..
|
||||||
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
# \return the matching quality changes containers \type{List[InstanceContainer]}
|
||||||
# the current set of selected materials is used.
|
def findQualityChangesByName(self, quality_changes_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None):
|
||||||
# \return the matching quality changes containers \type{List[ContainerInstance]}
|
|
||||||
def findQualityChangesByName(self, quality_changes_name, machine_definition=None):
|
|
||||||
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
||||||
result = self._getFilteredContainersForStack(machine_definition, [], **criteria)
|
result = self._getFilteredContainersForStack(machine_definition, [], **criteria)
|
||||||
|
|
||||||
@ -62,7 +64,7 @@ class QualityManager:
|
|||||||
# \param machine_definition \type{DefinitionContainer}
|
# \param machine_definition \type{DefinitionContainer}
|
||||||
# \param material_containers \type{List[InstanceContainer]}
|
# \param material_containers \type{List[InstanceContainer]}
|
||||||
# \return \type{List[str]}
|
# \return \type{List[str]}
|
||||||
def findAllQualityTypesForMachineAndMaterials(self, machine_definition, material_containers):
|
def findAllQualityTypesForMachineAndMaterials(self, machine_definition: "DefinitionContainerInterface", material_containers: List[InstanceContainer]) -> List[str]:
|
||||||
# Determine the common set of quality types which can be
|
# Determine the common set of quality types which can be
|
||||||
# applied to all of the materials for this machine.
|
# applied to all of the materials for this machine.
|
||||||
quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0])
|
quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0])
|
||||||
@ -76,9 +78,9 @@ class QualityManager:
|
|||||||
## Fetches a dict of quality types names to quality profiles for a combination of machine and material.
|
## Fetches a dict of quality types names to quality profiles for a combination of machine and material.
|
||||||
#
|
#
|
||||||
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
||||||
# \param material \type{ContainerInstance} the material.
|
# \param material \type{InstanceContainer} the material.
|
||||||
# \return \type{Dict[str, ContainerInstance]} the dict of suitable quality type names mapping to qualities.
|
# \return \type{Dict[str, InstanceContainer]} the dict of suitable quality type names mapping to qualities.
|
||||||
def __fetchQualityTypeDictForMaterial(self, machine_definition, material):
|
def __fetchQualityTypeDictForMaterial(self, machine_definition: "DefinitionContainerInterface", material: InstanceContainer) -> Dict[str, InstanceContainer]:
|
||||||
qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material)
|
qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material)
|
||||||
quality_type_dict = {}
|
quality_type_dict = {}
|
||||||
for quality in qualities:
|
for quality in qualities:
|
||||||
@ -88,12 +90,12 @@ class QualityManager:
|
|||||||
## Find a quality container by quality type.
|
## Find a quality container by quality type.
|
||||||
#
|
#
|
||||||
# \param quality_type \type{str} the name of the quality type to search for.
|
# \param quality_type \type{str} the name of the quality type to search for.
|
||||||
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
|
# \param machine_definition (Optional) \type{InstanceContainer} If nothing is
|
||||||
# specified then the currently selected machine definition is used.
|
# specified then the currently selected machine definition is used.
|
||||||
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
# \param material_containers (Optional) \type{List[InstanceContainer]} If nothing is specified then
|
||||||
# the current set of selected materials is used.
|
# the current set of selected materials is used.
|
||||||
# \return the matching quality container \type{ContainerInstance}
|
# \return the matching quality container \type{InstanceContainer}
|
||||||
def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None, **kwargs):
|
def findQualityByQualityType(self, quality_type: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers: List[InstanceContainer] = None, **kwargs) -> InstanceContainer:
|
||||||
criteria = kwargs
|
criteria = kwargs
|
||||||
criteria["type"] = "quality"
|
criteria["type"] = "quality"
|
||||||
if quality_type:
|
if quality_type:
|
||||||
@ -110,9 +112,9 @@ class QualityManager:
|
|||||||
## Find all suitable qualities for a combination of machine and material.
|
## Find all suitable qualities for a combination of machine and material.
|
||||||
#
|
#
|
||||||
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
||||||
# \param material_container \type{ContainerInstance} the material.
|
# \param material_container \type{InstanceContainer} the material.
|
||||||
# \return \type{List[ContainerInstance]} the list of suitable qualities.
|
# \return \type{List[InstanceContainer]} the list of suitable qualities.
|
||||||
def findAllQualitiesForMachineMaterial(self, machine_definition, material_container):
|
def findAllQualitiesForMachineMaterial(self, machine_definition: "DefinitionContainerInterface", material_container: InstanceContainer) -> List[InstanceContainer]:
|
||||||
criteria = {"type": "quality" }
|
criteria = {"type": "quality" }
|
||||||
result = self._getFilteredContainersForStack(machine_definition, [material_container], **criteria)
|
result = self._getFilteredContainersForStack(machine_definition, [material_container], **criteria)
|
||||||
if not result:
|
if not result:
|
||||||
@ -125,7 +127,7 @@ class QualityManager:
|
|||||||
#
|
#
|
||||||
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
# \param machine_definition \type{DefinitionContainer} the machine definition.
|
||||||
# \return \type{List[InstanceContainer]} the list of quality changes
|
# \return \type{List[InstanceContainer]} the list of quality changes
|
||||||
def findAllQualityChangesForMachine(self, machine_definition: DefinitionContainer) -> List[InstanceContainer]:
|
def findAllQualityChangesForMachine(self, machine_definition: "DefinitionContainerInterface") -> List[InstanceContainer]:
|
||||||
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
||||||
definition_id = machine_definition.getId()
|
definition_id = machine_definition.getId()
|
||||||
else:
|
else:
|
||||||
@ -141,19 +143,19 @@ class QualityManager:
|
|||||||
# Only one quality per quality type is returned. i.e. if there are 2 qualities with quality_type=normal
|
# Only one quality per quality type is returned. i.e. if there are 2 qualities with quality_type=normal
|
||||||
# then only one of then is returned (at random).
|
# then only one of then is returned (at random).
|
||||||
#
|
#
|
||||||
# \param global_container_stack \type{ContainerStack} the global machine definition
|
# \param global_container_stack \type{GlobalStack} the global machine definition
|
||||||
# \param extruder_stacks \type{List[ContainerStack]} the list of extruder stacks
|
# \param extruder_stacks \type{List[ExtruderStack]} the list of extruder stacks
|
||||||
# \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles
|
# \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles
|
||||||
# return come from the first extruder in the given list of extruders.
|
# return come from the first extruder in the given list of extruders.
|
||||||
def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack, extruder_stacks):
|
def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack: "GlobalStack", extruder_stacks: List["ExtruderStack"]) -> List[InstanceContainer]:
|
||||||
global_machine_definition = global_container_stack.getBottom()
|
global_machine_definition = global_container_stack.getBottom()
|
||||||
|
|
||||||
if extruder_stacks:
|
if extruder_stacks:
|
||||||
# Multi-extruder machine detected.
|
# Multi-extruder machine detected.
|
||||||
materials = [stack.findContainer(type="material") for stack in extruder_stacks]
|
materials = [stack.material for stack in extruder_stacks]
|
||||||
else:
|
else:
|
||||||
# Machine with one extruder.
|
# Machine with one extruder.
|
||||||
materials = [global_container_stack.findContainer(type="material")]
|
materials = [global_container_stack.material]
|
||||||
|
|
||||||
quality_types = self.findAllQualityTypesForMachineAndMaterials(global_machine_definition, materials)
|
quality_types = self.findAllQualityTypesForMachineAndMaterials(global_machine_definition, materials)
|
||||||
|
|
||||||
@ -170,7 +172,7 @@ class QualityManager:
|
|||||||
# This tries to find a generic or basic version of the given material.
|
# This tries to find a generic or basic version of the given material.
|
||||||
# \param material_container \type{InstanceContainer} the material
|
# \param material_container \type{InstanceContainer} the material
|
||||||
# \return \type{List[InstanceContainer]} a list of the basic materials or an empty list if one could not be found.
|
# \return \type{List[InstanceContainer]} a list of the basic materials or an empty list if one could not be found.
|
||||||
def _getBasicMaterials(self, material_container):
|
def _getBasicMaterials(self, material_container: InstanceContainer):
|
||||||
base_material = material_container.getMetaDataEntry("material")
|
base_material = material_container.getMetaDataEntry("material")
|
||||||
material_container_definition = material_container.getDefinition()
|
material_container_definition = material_container.getDefinition()
|
||||||
if material_container_definition and material_container_definition.getMetaDataEntry("has_machine_quality"):
|
if material_container_definition and material_container_definition.getMetaDataEntry("has_machine_quality"):
|
||||||
@ -192,7 +194,7 @@ class QualityManager:
|
|||||||
def _getFilteredContainers(self, **kwargs):
|
def _getFilteredContainers(self, **kwargs):
|
||||||
return self._getFilteredContainersForStack(None, None, **kwargs)
|
return self._getFilteredContainersForStack(None, None, **kwargs)
|
||||||
|
|
||||||
def _getFilteredContainersForStack(self, machine_definition=None, material_containers=None, **kwargs):
|
def _getFilteredContainersForStack(self, machine_definition: "DefinitionContainerInterface" = None, material_containers: List[InstanceContainer] = None, **kwargs):
|
||||||
# Fill in any default values.
|
# Fill in any default values.
|
||||||
if machine_definition is None:
|
if machine_definition is None:
|
||||||
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
|
||||||
@ -202,7 +204,8 @@ class QualityManager:
|
|||||||
|
|
||||||
if material_containers is None:
|
if material_containers is None:
|
||||||
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||||
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
|
if active_stacks:
|
||||||
|
material_containers = [stack.material for stack in active_stacks]
|
||||||
|
|
||||||
criteria = kwargs
|
criteria = kwargs
|
||||||
filter_by_material = False
|
filter_by_material = False
|
||||||
@ -216,12 +219,11 @@ class QualityManager:
|
|||||||
filter_by_material = whole_machine_definition.getMetaDataEntry("has_materials")
|
filter_by_material = whole_machine_definition.getMetaDataEntry("has_materials")
|
||||||
else:
|
else:
|
||||||
criteria["definition"] = "fdmprinter"
|
criteria["definition"] = "fdmprinter"
|
||||||
|
material_ids = set()
|
||||||
# Stick the material IDs in a set
|
# Stick the material IDs in a set
|
||||||
if material_containers is None or len(material_containers) == 0:
|
if material_containers is None or len(material_containers) == 0:
|
||||||
filter_by_material = False
|
filter_by_material = False
|
||||||
else:
|
else:
|
||||||
material_ids = set()
|
|
||||||
for material_instance in material_containers:
|
for material_instance in material_containers:
|
||||||
if material_instance is not None:
|
if material_instance is not None:
|
||||||
# Add the parent material too.
|
# Add the parent material too.
|
||||||
@ -245,7 +247,7 @@ class QualityManager:
|
|||||||
# an extruder definition.
|
# an extruder definition.
|
||||||
# \return \type{DefinitionContainer} the parent machine definition. If the given machine
|
# \return \type{DefinitionContainer} the parent machine definition. If the given machine
|
||||||
# definition doesn't have a parent then it is simply returned.
|
# definition doesn't have a parent then it is simply returned.
|
||||||
def getParentMachineDefinition(self, machine_definition: DefinitionContainer) -> DefinitionContainer:
|
def getParentMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface":
|
||||||
container_registry = ContainerRegistry.getInstance()
|
container_registry = ContainerRegistry.getInstance()
|
||||||
|
|
||||||
machine_entry = machine_definition.getMetaDataEntry("machine")
|
machine_entry = machine_definition.getMetaDataEntry("machine")
|
||||||
@ -274,8 +276,8 @@ class QualityManager:
|
|||||||
#
|
#
|
||||||
# \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
|
# \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
|
||||||
# an extruder definition.
|
# an extruder definition.
|
||||||
# \return \type{DefinitionContainer}
|
# \return \type{DefinitionContainerInterface}
|
||||||
def getWholeMachineDefinition(self, machine_definition):
|
def getWholeMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface":
|
||||||
machine_entry = machine_definition.getMetaDataEntry("machine")
|
machine_entry = machine_definition.getMetaDataEntry("machine")
|
||||||
if machine_entry is None:
|
if machine_entry is None:
|
||||||
# This already is a 'global' machine definition.
|
# This already is a 'global' machine definition.
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import urllib
|
import urllib
|
||||||
|
import uuid
|
||||||
from typing import Dict, Union
|
from typing import Dict, Union
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QUrl, QVariant
|
from PyQt5.QtCore import QObject, QUrl, QVariant
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
from UM.Util import parseBool
|
||||||
|
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.SaveFile import SaveFile
|
from UM.SaveFile import SaveFile
|
||||||
@ -671,6 +673,9 @@ class ContainerManager(QObject):
|
|||||||
|
|
||||||
return new_change_instances
|
return new_change_instances
|
||||||
|
|
||||||
|
## Create a duplicate of a material, which has the same GUID and base_file metadata
|
||||||
|
#
|
||||||
|
# \return \type{str} the id of the newly created container.
|
||||||
@pyqtSlot(str, result = str)
|
@pyqtSlot(str, result = str)
|
||||||
def duplicateMaterial(self, material_id: str) -> str:
|
def duplicateMaterial(self, material_id: str) -> str:
|
||||||
containers = self._container_registry.findInstanceContainers(id=material_id)
|
containers = self._container_registry.findInstanceContainers(id=material_id)
|
||||||
@ -693,6 +698,115 @@ class ContainerManager(QObject):
|
|||||||
duplicated_container.deserialize(f.read())
|
duplicated_container.deserialize(f.read())
|
||||||
duplicated_container.setDirty(True)
|
duplicated_container.setDirty(True)
|
||||||
self._container_registry.addContainer(duplicated_container)
|
self._container_registry.addContainer(duplicated_container)
|
||||||
|
return self._getMaterialContainerIdForActiveMachine(new_id)
|
||||||
|
|
||||||
|
## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue
|
||||||
|
#
|
||||||
|
# \return \type{str} the id of the newly created container.
|
||||||
|
@pyqtSlot(result = str)
|
||||||
|
def createMaterial(self) -> str:
|
||||||
|
# Ensure all settings are saved.
|
||||||
|
Application.getInstance().saveSettings()
|
||||||
|
|
||||||
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
if not global_stack:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
approximate_diameter = round(global_stack.getProperty("material_diameter", "value"))
|
||||||
|
containers = self._container_registry.findInstanceContainers(id = "generic_pla*", approximate_diameter = approximate_diameter)
|
||||||
|
if not containers:
|
||||||
|
Logger.log("d", "Unable to create a new material by cloning Generic PLA, because it cannot be found for the material diameter for this machine.")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
base_file = containers[0].getMetaDataEntry("base_file")
|
||||||
|
containers = self._container_registry.findInstanceContainers(id = base_file)
|
||||||
|
if not containers:
|
||||||
|
Logger.log("d", "Unable to create a new material by cloning Generic PLA, because the base file for Generic PLA for this machine can not be found.")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# Create a new ID & container to hold the data.
|
||||||
|
new_id = self._container_registry.uniqueName("custom_material")
|
||||||
|
container_type = type(containers[0]) # Always XMLMaterialProfile, since we specifically clone the base_file
|
||||||
|
duplicated_container = container_type(new_id)
|
||||||
|
|
||||||
|
# Instead of duplicating we load the data from the basefile again.
|
||||||
|
# This ensures that the inheritance goes well and all "cut up" subclasses of the xmlMaterial profile
|
||||||
|
# are also correctly created.
|
||||||
|
with open(containers[0].getPath(), encoding="utf-8") as f:
|
||||||
|
duplicated_container.deserialize(f.read())
|
||||||
|
|
||||||
|
duplicated_container.setMetaDataEntry("GUID", str(uuid.uuid4()))
|
||||||
|
duplicated_container.setMetaDataEntry("brand", catalog.i18nc("@label", "Custom"))
|
||||||
|
duplicated_container.setMetaDataEntry("material", catalog.i18nc("@label", "Custom"))
|
||||||
|
duplicated_container.setName(catalog.i18nc("@label", "Custom Material"))
|
||||||
|
|
||||||
|
self._container_registry.addContainer(duplicated_container)
|
||||||
|
return self._getMaterialContainerIdForActiveMachine(new_id)
|
||||||
|
|
||||||
|
## Find the id of a material container based on the new material
|
||||||
|
# Utilty function that is shared between duplicateMaterial and createMaterial
|
||||||
|
#
|
||||||
|
# \param base_file \type{str} the id of the created container.
|
||||||
|
def _getMaterialContainerIdForActiveMachine(self, base_file):
|
||||||
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
if not global_stack:
|
||||||
|
return base_file
|
||||||
|
|
||||||
|
has_machine_materials = parseBool(global_stack.getMetaDataEntry("has_machine_materials", default = False))
|
||||||
|
has_variant_materials = parseBool(global_stack.getMetaDataEntry("has_variant_materials", default = False))
|
||||||
|
has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", default = False))
|
||||||
|
if has_machine_materials or has_variant_materials:
|
||||||
|
if has_variants:
|
||||||
|
materials = self._container_registry.findInstanceContainers(type = "material", base_file = base_file, definition = global_stack.getBottom().getId(), variant = self._machine_manager.activeVariantId)
|
||||||
|
else:
|
||||||
|
materials = self._container_registry.findInstanceContainers(type = "material", base_file = base_file, definition = global_stack.getBottom().getId())
|
||||||
|
|
||||||
|
if materials:
|
||||||
|
return materials[0].getId()
|
||||||
|
|
||||||
|
Logger.log("w", "Unable to find a suitable container based on %s for the current machine .", base_file)
|
||||||
|
return "" # do not activate a new material if a container can not be found
|
||||||
|
|
||||||
|
return base_file
|
||||||
|
|
||||||
|
## Get a list of materials that have the same GUID as the reference material
|
||||||
|
#
|
||||||
|
# \param material_id \type{str} the id of the material for which to get the linked materials.
|
||||||
|
# \return \type{list} a list of names of materials with the same GUID
|
||||||
|
@pyqtSlot(str, result = "QStringList")
|
||||||
|
def getLinkedMaterials(self, material_id: str):
|
||||||
|
containers = self._container_registry.findInstanceContainers(id=material_id)
|
||||||
|
if not containers:
|
||||||
|
Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't exist.", material_id)
|
||||||
|
return []
|
||||||
|
|
||||||
|
material_container = containers[0]
|
||||||
|
material_base_file = material_container.getMetaDataEntry("base_file", "")
|
||||||
|
material_guid = material_container.getMetaDataEntry("GUID", "")
|
||||||
|
if not material_guid:
|
||||||
|
Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't have a GUID.", material_id)
|
||||||
|
return []
|
||||||
|
|
||||||
|
containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_guid)
|
||||||
|
linked_material_names = []
|
||||||
|
for container in containers:
|
||||||
|
if container.getId() in [material_id, material_base_file] or container.getMetaDataEntry("base_file") != container.getId():
|
||||||
|
continue
|
||||||
|
|
||||||
|
linked_material_names.append(container.getName())
|
||||||
|
return linked_material_names
|
||||||
|
|
||||||
|
## Unlink a material from all other materials by creating a new GUID
|
||||||
|
# \param material_id \type{str} the id of the material to create a new GUID for.
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def unlinkMaterial(self, material_id: str):
|
||||||
|
containers = self._container_registry.findInstanceContainers(id=material_id)
|
||||||
|
if not containers:
|
||||||
|
Logger.log("d", "Unable to make the material with id %s unique, because it doesn't exist.", material_id)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
containers[0].setMetaDataEntry("GUID", str(uuid.uuid4()))
|
||||||
|
|
||||||
|
|
||||||
## Get the singleton instance for this class.
|
## Get the singleton instance for this class.
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -815,6 +929,8 @@ class ContainerManager(QObject):
|
|||||||
quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0])
|
quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0])
|
||||||
else:
|
else:
|
||||||
quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition))
|
quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition))
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
return quality_changes
|
return quality_changes
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ from . import GlobalStack
|
|||||||
from .ContainerManager import ContainerManager
|
from .ContainerManager import ContainerManager
|
||||||
from .ExtruderManager import ExtruderManager
|
from .ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
|
|
||||||
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 = int(container.getDefinition().getMetaDataEntry("setting_version"))
|
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:
|
||||||
Logger.log("w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}.".format(container_id = container.getId(), actual_setting_version = actual_setting_version, required_setting_version = required_setting_version))
|
Logger.log("w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}.".format(container_id = container.getId(), actual_setting_version = actual_setting_version, required_setting_version = required_setting_version))
|
||||||
|
@ -9,7 +9,6 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
|
|||||||
|
|
||||||
from .GlobalStack import GlobalStack
|
from .GlobalStack import GlobalStack
|
||||||
from .ExtruderStack import ExtruderStack
|
from .ExtruderStack import ExtruderStack
|
||||||
from .CuraContainerStack import CuraContainerStack
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
@ -76,6 +75,8 @@ class CuraStackBuilder:
|
|||||||
user_container = InstanceContainer(new_stack_id + "_user")
|
user_container = InstanceContainer(new_stack_id + "_user")
|
||||||
user_container.addMetaDataEntry("type", "user")
|
user_container.addMetaDataEntry("type", "user")
|
||||||
user_container.addMetaDataEntry("extruder", new_stack_id)
|
user_container.addMetaDataEntry("extruder", new_stack_id)
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
user_container.setDefinition(machine_definition)
|
user_container.setDefinition(machine_definition)
|
||||||
|
|
||||||
stack.setUserChanges(user_container)
|
stack.setUserChanges(user_container)
|
||||||
@ -124,6 +125,8 @@ class CuraStackBuilder:
|
|||||||
user_container = InstanceContainer(new_stack_id + "_user")
|
user_container = InstanceContainer(new_stack_id + "_user")
|
||||||
user_container.addMetaDataEntry("type", "user")
|
user_container.addMetaDataEntry("type", "user")
|
||||||
user_container.addMetaDataEntry("machine", new_stack_id)
|
user_container.addMetaDataEntry("machine", new_stack_id)
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
user_container.setDefinition(definition)
|
user_container.setDefinition(definition)
|
||||||
|
|
||||||
stack.setUserChanges(user_container)
|
stack.setUserChanges(user_container)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 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.
|
||||||
@ -20,6 +20,7 @@ from typing import Optional, List, TYPE_CHECKING, Union
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from cura.Settings.ExtruderStack import ExtruderStack
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
|
||||||
## Manages all existing extruder stacks.
|
## Manages all existing extruder stacks.
|
||||||
@ -76,8 +77,9 @@ class ExtruderManager(QObject):
|
|||||||
@pyqtProperty("QVariantMap", notify=extrudersChanged)
|
@pyqtProperty("QVariantMap", notify=extrudersChanged)
|
||||||
def extruderIds(self):
|
def extruderIds(self):
|
||||||
map = {}
|
map = {}
|
||||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
global_stack_id = Application.getInstance().getGlobalContainerStack().getId()
|
||||||
map[position] = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position].getId()
|
for position in self._extruder_trains[global_stack_id]:
|
||||||
|
map[position] = self._extruder_trains[global_stack_id][position].getId()
|
||||||
return map
|
return map
|
||||||
|
|
||||||
@pyqtSlot(str, result = str)
|
@pyqtSlot(str, result = str)
|
||||||
@ -85,7 +87,7 @@ class ExtruderManager(QObject):
|
|||||||
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() == id:
|
||||||
return extruder.findContainer(type = "quality_changes").getId()
|
return extruder.qualityChanges.getId()
|
||||||
|
|
||||||
## The instance of the singleton pattern.
|
## The instance of the singleton pattern.
|
||||||
#
|
#
|
||||||
@ -235,6 +237,13 @@ class ExtruderManager(QObject):
|
|||||||
if machine_id not in self._extruder_trains:
|
if machine_id not in self._extruder_trains:
|
||||||
self._extruder_trains[machine_id] = {}
|
self._extruder_trains[machine_id] = {}
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
# do not register if an extruder has already been registered at the position on this machine
|
||||||
|
if any(item.getId() == extruder_train.getId() for item in self._extruder_trains[machine_id].values()):
|
||||||
|
Logger.log("w", "Extruder [%s] has already been registered on machine [%s], not doing anything",
|
||||||
|
extruder_train.getId(), machine_id)
|
||||||
|
return
|
||||||
|
|
||||||
if extruder_train:
|
if extruder_train:
|
||||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train
|
||||||
changed = True
|
changed = True
|
||||||
@ -362,6 +371,8 @@ class ExtruderManager(QObject):
|
|||||||
user_profile = InstanceContainer(extruder_stack_id + "_current_settings") # Add an empty user profile.
|
user_profile = InstanceContainer(extruder_stack_id + "_current_settings") # Add an empty user profile.
|
||||||
user_profile.addMetaDataEntry("type", "user")
|
user_profile.addMetaDataEntry("type", "user")
|
||||||
user_profile.addMetaDataEntry("extruder", extruder_stack_id)
|
user_profile.addMetaDataEntry("extruder", extruder_stack_id)
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
user_profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
user_profile.setDefinition(machine_definition)
|
user_profile.setDefinition(machine_definition)
|
||||||
container_registry.addContainer(user_profile)
|
container_registry.addContainer(user_profile)
|
||||||
container_stack.addContainer(user_profile)
|
container_stack.addContainer(user_profile)
|
||||||
@ -457,10 +468,9 @@ class ExtruderManager(QObject):
|
|||||||
# \param machine_id The machine to remove the extruders for.
|
# \param machine_id The machine to remove the extruders for.
|
||||||
def removeMachineExtruders(self, machine_id: str):
|
def removeMachineExtruders(self, machine_id: str):
|
||||||
for extruder in self.getMachineExtruders(machine_id):
|
for extruder in self.getMachineExtruders(machine_id):
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", extruder = extruder.getId())
|
ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId())
|
||||||
for container in containers:
|
|
||||||
ContainerRegistry.getInstance().removeContainer(container.getId())
|
|
||||||
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
ContainerRegistry.getInstance().removeContainer(extruder.getId())
|
||||||
|
del self._extruder_trains[machine_id]
|
||||||
|
|
||||||
## Returns extruders for a specific machine.
|
## Returns extruders for a specific machine.
|
||||||
#
|
#
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot
|
|
||||||
|
|
||||||
from UM.Decorators import override
|
from UM.Decorators import override
|
||||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||||
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
|
||||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
|
||||||
from UM.Settings.Interfaces import ContainerInterface
|
from UM.Settings.Interfaces import ContainerInterface
|
||||||
|
|
||||||
from . import Exceptions
|
from . import Exceptions
|
||||||
from .CuraContainerStack import CuraContainerStack
|
from .CuraContainerStack import CuraContainerStack
|
||||||
from .ExtruderManager import ExtruderManager
|
from .ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
## Represents an Extruder and its related containers.
|
## Represents an Extruder and its related containers.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@ -38,6 +37,10 @@ class ExtruderStack(CuraContainerStack):
|
|||||||
# For backward compatibility: Register the extruder with the Extruder Manager
|
# For backward compatibility: Register the extruder with the Extruder Manager
|
||||||
ExtruderManager.getInstance().registerExtruder(self, stack.id)
|
ExtruderManager.getInstance().registerExtruder(self, stack.id)
|
||||||
|
|
||||||
|
@override(ContainerStack)
|
||||||
|
def getNextStack(self) -> Optional["GlobalStack"]:
|
||||||
|
return super().getNextStack()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getLoadingPriority(cls) -> int:
|
def getLoadingPriority(cls) -> int:
|
||||||
return 3
|
return 3
|
||||||
@ -59,6 +62,12 @@ class ExtruderStack(CuraContainerStack):
|
|||||||
if not super().getProperty(key, "settable_per_extruder"):
|
if not super().getProperty(key, "settable_per_extruder"):
|
||||||
return self.getNextStack().getProperty(key, property_name)
|
return self.getNextStack().getProperty(key, property_name)
|
||||||
|
|
||||||
|
limit_to_extruder = super().getProperty(key, "limit_to_extruder")
|
||||||
|
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
|
||||||
|
result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name)
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
|
||||||
return super().getProperty(key, property_name)
|
return super().getProperty(key, property_name)
|
||||||
|
|
||||||
@override(CuraContainerStack)
|
@override(CuraContainerStack)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any, Dict
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty
|
from PyQt5.QtCore import pyqtProperty
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ class GlobalStack(CuraContainerStack):
|
|||||||
|
|
||||||
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
||||||
|
|
||||||
self._extruders = []
|
self._extruders = {}
|
||||||
|
|
||||||
# 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
|
||||||
@ -34,8 +34,8 @@ class GlobalStack(CuraContainerStack):
|
|||||||
## Get the list of extruders of this stack.
|
## Get the list of extruders of this stack.
|
||||||
#
|
#
|
||||||
# \return The extruders registered with this stack.
|
# \return The extruders registered with this stack.
|
||||||
@pyqtProperty("QVariantList")
|
@pyqtProperty("QVariantMap")
|
||||||
def extruders(self) -> list:
|
def extruders(self) -> Dict[str, "ExtruderStack"]:
|
||||||
return self._extruders
|
return self._extruders
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -52,8 +52,17 @@ class GlobalStack(CuraContainerStack):
|
|||||||
extruder_count = self.getProperty("machine_extruder_count", "value")
|
extruder_count = self.getProperty("machine_extruder_count", "value")
|
||||||
if extruder_count and len(self._extruders) + 1 > extruder_count:
|
if extruder_count and len(self._extruders) + 1 > extruder_count:
|
||||||
Logger.log("w", "Adding extruder {meta} to {id} but its extruder count is {count}".format(id = self.id, count = extruder_count, meta = str(extruder.getMetaData())))
|
Logger.log("w", "Adding extruder {meta} to {id} but its extruder count is {count}".format(id = self.id, count = extruder_count, meta = str(extruder.getMetaData())))
|
||||||
|
return
|
||||||
|
|
||||||
self._extruders.append(extruder)
|
position = extruder.getMetaDataEntry("position")
|
||||||
|
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)
|
||||||
|
return
|
||||||
|
|
||||||
|
if any(item.getId() == extruder.id for item in self._extruders.values()):
|
||||||
|
Logger.log("w", "Extruder [%s] has already been added to this stack [%s]", extruder.id, self._id)
|
||||||
|
return
|
||||||
|
self._extruders[position] = extruder
|
||||||
|
|
||||||
## Overridden from ContainerStack
|
## Overridden from ContainerStack
|
||||||
#
|
#
|
||||||
@ -71,6 +80,7 @@ class GlobalStack(CuraContainerStack):
|
|||||||
if not self.definition.findDefinitions(key = key):
|
if not self.definition.findDefinitions(key = key):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# Handle the "resolve" property.
|
||||||
if self._shouldResolve(key, property_name):
|
if self._shouldResolve(key, property_name):
|
||||||
self._resolving_settings.add(key)
|
self._resolving_settings.add(key)
|
||||||
resolve = super().getProperty(key, "resolve")
|
resolve = super().getProperty(key, "resolve")
|
||||||
@ -78,6 +88,16 @@ class GlobalStack(CuraContainerStack):
|
|||||||
if resolve is not None:
|
if resolve is not None:
|
||||||
return resolve
|
return resolve
|
||||||
|
|
||||||
|
# Handle the "limit_to_extruder" property.
|
||||||
|
limit_to_extruder = super().getProperty(key, "limit_to_extruder")
|
||||||
|
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders:
|
||||||
|
if super().getProperty(key, "settable_per_extruder"):
|
||||||
|
result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name)
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key)
|
||||||
|
|
||||||
return super().getProperty(key, property_name)
|
return super().getProperty(key, property_name)
|
||||||
|
|
||||||
## Overridden from ContainerStack
|
## Overridden from ContainerStack
|
||||||
|
@ -1061,19 +1061,19 @@ class MachineManager(QObject):
|
|||||||
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
|
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
|
||||||
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
|
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
|
||||||
|
|
||||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
# activate a new machine before removing a machine because this is safer
|
||||||
|
if activate_new_machine:
|
||||||
|
machine_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||||
|
other_machine_stacks = [s for s in machine_stacks if s.getId() != machine_id]
|
||||||
|
if other_machine_stacks:
|
||||||
|
Application.getInstance().setGlobalContainerStack(other_machine_stacks[0])
|
||||||
|
|
||||||
|
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)
|
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)
|
||||||
for container in containers:
|
for container in containers:
|
||||||
ContainerRegistry.getInstance().removeContainer(container.getId())
|
ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||||
ContainerRegistry.getInstance().removeContainer(machine_id)
|
ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||||
|
|
||||||
if activate_new_machine:
|
|
||||||
stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
|
||||||
if stacks:
|
|
||||||
Application.getInstance().setGlobalContainerStack(stacks[0])
|
|
||||||
|
|
||||||
|
|
||||||
@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:
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
|
||||||
@ -43,6 +46,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
self._extruder_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(ExtruderStack).preferredSuffix
|
self._extruder_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(ExtruderStack).preferredSuffix
|
||||||
self._global_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(GlobalStack).preferredSuffix
|
self._global_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(GlobalStack).preferredSuffix
|
||||||
|
|
||||||
|
# Certain instance container types are ignored because we make the assumption that only we make those types
|
||||||
|
# of containers. They are:
|
||||||
|
# - quality
|
||||||
|
# - variant
|
||||||
|
self._ignored_instance_container_types = {"quality", "variant"}
|
||||||
|
|
||||||
self._resolve_strategies = {}
|
self._resolve_strategies = {}
|
||||||
|
|
||||||
self._id_mapping = {}
|
self._id_mapping = {}
|
||||||
@ -180,6 +189,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
num_user_settings = 0
|
num_user_settings = 0
|
||||||
quality_changes_conflict = False
|
quality_changes_conflict = False
|
||||||
definition_changes_conflict = False
|
definition_changes_conflict = False
|
||||||
|
|
||||||
for each_instance_container_file in instance_container_files:
|
for each_instance_container_file in instance_container_files:
|
||||||
container_id = self._stripFileToId(each_instance_container_file)
|
container_id = self._stripFileToId(each_instance_container_file)
|
||||||
instance_container = InstanceContainer(container_id)
|
instance_container = InstanceContainer(container_id)
|
||||||
@ -205,14 +215,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
if definition_changes:
|
if definition_changes:
|
||||||
if definition_changes[0] != instance_container:
|
if definition_changes[0] != instance_container:
|
||||||
definition_changes_conflict = True
|
definition_changes_conflict = True
|
||||||
elif container_type == "quality":
|
|
||||||
# If the quality name is not set (either by quality or changes, set it now)
|
|
||||||
# Quality changes should always override this (as they are "on top")
|
|
||||||
if quality_name == "":
|
|
||||||
quality_name = instance_container.getName()
|
|
||||||
quality_type = instance_container.getName()
|
|
||||||
elif container_type == "user":
|
elif container_type == "user":
|
||||||
num_user_settings += len(instance_container._instances)
|
num_user_settings += len(instance_container._instances)
|
||||||
|
elif container_type in self._ignored_instance_container_types:
|
||||||
|
# Ignore certain instance container types
|
||||||
|
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
|
||||||
|
continue
|
||||||
|
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
@ -303,6 +311,19 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
|
|
||||||
return WorkspaceReader.PreReadResult.accepted
|
return WorkspaceReader.PreReadResult.accepted
|
||||||
|
|
||||||
|
## Overrides an ExtruderStack in the given GlobalStack and returns the new ExtruderStack.
|
||||||
|
def _overrideExtruderStack(self, global_stack, extruder_index, extruder_file_content):
|
||||||
|
extruder_index_str = str(extruder_index)
|
||||||
|
|
||||||
|
extruder_stack = global_stack.extruders[extruder_index_str]
|
||||||
|
old_extruder_stack_id = extruder_stack.getId()
|
||||||
|
|
||||||
|
# override the given extruder stack
|
||||||
|
extruder_stack.deserialize(extruder_file_content)
|
||||||
|
|
||||||
|
# return the new ExtruderStack
|
||||||
|
return extruder_stack
|
||||||
|
|
||||||
## Read the project file
|
## Read the project file
|
||||||
# Add all the definitions / materials / quality changes that do not exist yet. Then it loads
|
# Add all the definitions / materials / quality changes that do not exist yet. Then it loads
|
||||||
# all the stacks into the container registry. In some cases it will reuse the container for the global stack.
|
# all the stacks into the container registry. In some cases it will reuse the container for the global stack.
|
||||||
@ -355,12 +376,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
global_stack_id_original = self._stripFileToId(global_stack_file)
|
global_stack_id_original = self._stripFileToId(global_stack_file)
|
||||||
global_stack_id_new = global_stack_id_original
|
global_stack_id_new = global_stack_id_original
|
||||||
global_stack_need_rename = False
|
global_stack_need_rename = False
|
||||||
|
|
||||||
|
extruder_stack_id_map = {} # new and old ExtruderStack IDs map
|
||||||
if self._resolve_strategies["machine"] == "new":
|
if self._resolve_strategies["machine"] == "new":
|
||||||
# We need a new id if the id already exists
|
# We need a new id if the id already exists
|
||||||
if self._container_registry.findContainerStacks(id = global_stack_id_original):
|
if self._container_registry.findContainerStacks(id = global_stack_id_original):
|
||||||
global_stack_id_new = self.getNewId(global_stack_id_original)
|
global_stack_id_new = self.getNewId(global_stack_id_original)
|
||||||
global_stack_need_rename = True
|
global_stack_need_rename = True
|
||||||
|
|
||||||
|
for each_extruder_stack_file in extruder_stack_files:
|
||||||
|
old_container_id = self._stripFileToId(each_extruder_stack_file)
|
||||||
|
new_container_id = old_container_id
|
||||||
|
if self._container_registry.findContainerStacks(id = old_container_id):
|
||||||
|
# get a new name for this extruder
|
||||||
|
new_container_id = self.getNewId(old_container_id)
|
||||||
|
|
||||||
|
extruder_stack_id_map[old_container_id] = new_container_id
|
||||||
|
|
||||||
# TODO: For the moment we use pretty naive existence checking. If the ID is the same, we assume in quite a few
|
# TODO: For the moment we use pretty naive existence checking. If the ID is the same, we assume in quite a few
|
||||||
# TODO: cases that the container loaded is the same (most notable in materials & definitions).
|
# TODO: cases that the container loaded is the same (most notable in materials & definitions).
|
||||||
# TODO: It might be possible that we need to add smarter checking in the future.
|
# TODO: It might be possible that we need to add smarter checking in the future.
|
||||||
@ -414,13 +446,35 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
quality_and_definition_changes_instance_containers = []
|
quality_and_definition_changes_instance_containers = []
|
||||||
for instance_container_file in instance_container_files:
|
for instance_container_file in instance_container_files:
|
||||||
container_id = self._stripFileToId(instance_container_file)
|
container_id = self._stripFileToId(instance_container_file)
|
||||||
|
serialized = archive.open(instance_container_file).read().decode("utf-8")
|
||||||
|
|
||||||
|
# HACK! we ignore the "metadata/type = quality" instance containers!
|
||||||
|
parser = configparser.ConfigParser()
|
||||||
|
parser.read_string(serialized)
|
||||||
|
if not parser.has_option("metadata", "type"):
|
||||||
|
Logger.log("w", "Cannot find metadata/type in %s, ignoring it", instance_container_file)
|
||||||
|
continue
|
||||||
|
if parser.get("metadata", "type") == "quality":
|
||||||
|
continue
|
||||||
|
|
||||||
instance_container = InstanceContainer(container_id)
|
instance_container = InstanceContainer(container_id)
|
||||||
|
|
||||||
# Deserialize InstanceContainer by converting read data from bytes to string
|
# Deserialize InstanceContainer by converting read data from bytes to string
|
||||||
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
|
instance_container.deserialize(serialized)
|
||||||
container_type = instance_container.getMetaDataEntry("type")
|
container_type = instance_container.getMetaDataEntry("type")
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
if container_type == "user":
|
|
||||||
|
#
|
||||||
|
# IMPORTANT:
|
||||||
|
# If an instance container (or maybe other type of container) exists, and user chooses "Create New",
|
||||||
|
# we need to rename this container and all references to it, and changing those references are VERY
|
||||||
|
# HARD.
|
||||||
|
#
|
||||||
|
if container_type in self._ignored_instance_container_types:
|
||||||
|
# Ignore certain instance container types
|
||||||
|
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
|
||||||
|
continue
|
||||||
|
elif container_type == "user":
|
||||||
# Check if quality changes already exists.
|
# Check if quality changes already exists.
|
||||||
user_containers = self._container_registry.findInstanceContainers(id = container_id)
|
user_containers = self._container_registry.findInstanceContainers(id = container_id)
|
||||||
if not user_containers:
|
if not user_containers:
|
||||||
@ -432,9 +486,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
instance_container.setDirty(True)
|
instance_container.setDirty(True)
|
||||||
elif self._resolve_strategies["machine"] == "new":
|
elif self._resolve_strategies["machine"] == "new":
|
||||||
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
||||||
extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||||
if extruder_id:
|
if old_extruder_id:
|
||||||
new_extruder_id = self.getNewId(extruder_id)
|
new_extruder_id = extruder_stack_id_map[old_extruder_id]
|
||||||
new_id = new_extruder_id + "_current_settings"
|
new_id = new_extruder_id + "_current_settings"
|
||||||
instance_container._id = new_id
|
instance_container._id = new_id
|
||||||
instance_container.setName(new_id)
|
instance_container.setName(new_id)
|
||||||
@ -454,26 +508,30 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# Check if quality changes already exists.
|
# Check if quality changes already exists.
|
||||||
changes_containers = self._container_registry.findInstanceContainers(id = container_id)
|
changes_containers = self._container_registry.findInstanceContainers(id = container_id)
|
||||||
if not changes_containers:
|
if not changes_containers:
|
||||||
|
# no existing containers with the same ID, so we can safely add the new one
|
||||||
containers_to_add.append(instance_container)
|
containers_to_add.append(instance_container)
|
||||||
else:
|
else:
|
||||||
|
# we have found existing container with the same ID, so we need to resolve according to the
|
||||||
|
# selected strategy.
|
||||||
if self._resolve_strategies[container_type] == "override":
|
if self._resolve_strategies[container_type] == "override":
|
||||||
instance_container = changes_containers[0]
|
instance_container = changes_containers[0]
|
||||||
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
|
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
|
||||||
instance_container.setDirty(True)
|
instance_container.setDirty(True)
|
||||||
|
|
||||||
elif self._resolve_strategies[container_type] == "new":
|
elif self._resolve_strategies[container_type] == "new":
|
||||||
# TODO: how should we handle the case "new" for quality_changes and definition_changes?
|
# TODO: how should we handle the case "new" for quality_changes and definition_changes?
|
||||||
|
|
||||||
|
instance_container.setName(self._container_registry.uniqueName(instance_container.getName()))
|
||||||
new_changes_container_id = self.getNewId(instance_container.getId())
|
new_changes_container_id = self.getNewId(instance_container.getId())
|
||||||
instance_container._id = new_changes_container_id
|
instance_container._id = new_changes_container_id
|
||||||
instance_container.setName(new_changes_container_id)
|
|
||||||
|
|
||||||
# TODO: we don't know the following is correct or not, need to verify
|
# TODO: we don't know the following is correct or not, need to verify
|
||||||
# AND REFACTOR!!!
|
# AND REFACTOR!!!
|
||||||
if self._resolve_strategies["machine"] == "new":
|
if self._resolve_strategies["machine"] == "new":
|
||||||
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
||||||
extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||||
if extruder_id:
|
if old_extruder_id:
|
||||||
new_extruder_id = self.getNewId(extruder_id)
|
new_extruder_id = extruder_stack_id_map[old_extruder_id]
|
||||||
instance_container.setMetaDataEntry("extruder", new_extruder_id)
|
instance_container.setMetaDataEntry("extruder", new_extruder_id)
|
||||||
|
|
||||||
machine_id = instance_container.getMetaDataEntry("machine", None)
|
machine_id = instance_container.getMetaDataEntry("machine", None)
|
||||||
@ -563,18 +621,36 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
try:
|
try:
|
||||||
for index, extruder_stack_file in enumerate(extruder_stack_files):
|
for index, extruder_stack_file in enumerate(extruder_stack_files):
|
||||||
container_id = self._stripFileToId(extruder_stack_file)
|
container_id = self._stripFileToId(extruder_stack_file)
|
||||||
|
extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8")
|
||||||
|
|
||||||
container_stacks = self._container_registry.findContainerStacks(id = container_id)
|
container_stacks = self._container_registry.findContainerStacks(id = container_id)
|
||||||
if container_stacks:
|
if container_stacks:
|
||||||
# this container stack already exists, try to resolve
|
# this container stack already exists, try to resolve
|
||||||
stack = container_stacks[0]
|
stack = container_stacks[0]
|
||||||
|
|
||||||
if self._resolve_strategies["machine"] == "override":
|
if self._resolve_strategies["machine"] == "override":
|
||||||
pass # do nothing
|
# NOTE: This is the same code as those in the lower part
|
||||||
|
# deserialize new extruder stack over the current ones
|
||||||
|
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
|
||||||
|
|
||||||
elif self._resolve_strategies["machine"] == "new":
|
elif self._resolve_strategies["machine"] == "new":
|
||||||
# create a new extruder stack from this one
|
# create a new extruder stack from this one
|
||||||
new_id = self.getNewId(container_id)
|
new_id = extruder_stack_id_map[container_id]
|
||||||
stack = ExtruderStack(new_id)
|
stack = ExtruderStack(new_id)
|
||||||
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
|
|
||||||
|
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||||
|
# references to the new name instead of the old one. Normally, this can be done after
|
||||||
|
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||||
|
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||||
|
# to the right machine BEFORE deserialization.
|
||||||
|
extruder_config = configparser.ConfigParser()
|
||||||
|
extruder_config.read_string(extruder_file_content)
|
||||||
|
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||||
|
tmp_string_io = io.StringIO()
|
||||||
|
extruder_config.write(tmp_string_io)
|
||||||
|
extruder_file_content = tmp_string_io.getvalue()
|
||||||
|
|
||||||
|
stack.deserialize(extruder_file_content)
|
||||||
|
|
||||||
# Ensure a unique ID and name
|
# Ensure a unique ID and name
|
||||||
stack._id = new_id
|
stack._id = new_id
|
||||||
@ -583,37 +659,34 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
extruder_stacks_added.append(stack)
|
extruder_stacks_added.append(stack)
|
||||||
containers_added.append(stack)
|
containers_added.append(stack)
|
||||||
else:
|
else:
|
||||||
|
# No extruder stack with the same ID can be found
|
||||||
if self._resolve_strategies["machine"] == "override":
|
if self._resolve_strategies["machine"] == "override":
|
||||||
global_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
|
|
||||||
# deserialize new extruder stack over the current ones
|
# deserialize new extruder stack over the current ones
|
||||||
if global_stacks:
|
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
|
||||||
old_extruder_stack_id = global_stacks[0].extruders[index].getId()
|
|
||||||
# HACK delete file
|
|
||||||
self._container_registry._deleteFiles(global_stacks[0].extruders[index])
|
|
||||||
global_stacks[0].extruders[index].deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
|
|
||||||
# HACK
|
|
||||||
global_stacks[0]._extruders = global_stacks[0]._extruders[:2]
|
|
||||||
# HACK update cache
|
|
||||||
del self._container_registry._id_container_cache[old_extruder_stack_id]
|
|
||||||
new_extruder_stack_id = global_stacks[0].extruders[index].getId()
|
|
||||||
self._container_registry._id_container_cache[new_extruder_stack_id] = global_stacks[0].extruders[index]
|
|
||||||
|
|
||||||
stack = global_stacks[0].extruders[index]
|
|
||||||
else:
|
|
||||||
Logger.log("w", "Could not find global stack, while I expected it: %s" % global_stack_id_original)
|
|
||||||
elif self._resolve_strategies["machine"] == "new":
|
elif self._resolve_strategies["machine"] == "new":
|
||||||
# container not found, create a new one
|
# container not found, create a new one
|
||||||
stack = ExtruderStack(container_id)
|
stack = ExtruderStack(container_id)
|
||||||
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
|
|
||||||
|
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||||
|
# references to the new name instead of the old one. Normally, this can be done after
|
||||||
|
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||||
|
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||||
|
# to the right machine BEFORE deserialization.
|
||||||
|
extruder_config = configparser.ConfigParser()
|
||||||
|
extruder_config.read_string(extruder_file_content)
|
||||||
|
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||||
|
tmp_string_io = io.StringIO()
|
||||||
|
extruder_config.write(tmp_string_io)
|
||||||
|
extruder_file_content = tmp_string_io.getvalue()
|
||||||
|
|
||||||
|
stack.deserialize(extruder_file_content)
|
||||||
self._container_registry.addContainer(stack)
|
self._container_registry.addContainer(stack)
|
||||||
extruder_stacks_added.append(stack)
|
extruder_stacks_added.append(stack)
|
||||||
containers_added.append(stack)
|
containers_added.append(stack)
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "Unknown resolve strategy: %s" % str(self._resolve_strategies["machine"]))
|
Logger.log("w", "Unknown resolve strategy: %s" % str(self._resolve_strategies["machine"]))
|
||||||
|
|
||||||
if global_stack_need_rename:
|
|
||||||
if stack.getMetaDataEntry("machine"):
|
|
||||||
stack.setMetaDataEntry("machine", global_stack_id_new)
|
|
||||||
extruder_stacks.append(stack)
|
extruder_stacks.append(stack)
|
||||||
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.")
|
||||||
@ -649,13 +722,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
if self._resolve_strategies[changes_container_type] == "new":
|
if self._resolve_strategies[changes_container_type] == "new":
|
||||||
# Quality changes needs to get a new ID, added to registry and to the right stacks
|
# Quality changes needs to get a new ID, added to registry and to the right stacks
|
||||||
for each_changes_container in quality_and_definition_changes_instance_containers:
|
for each_changes_container in quality_and_definition_changes_instance_containers:
|
||||||
old_id = each_changes_container.getId()
|
# NOTE: The renaming and giving new IDs are possibly redundant because they are done in the
|
||||||
each_changes_container.setName(self._container_registry.uniqueName(each_changes_container.getName()))
|
# instance container loading part.
|
||||||
# We're not really supposed to change the ID in normal cases, but this is an exception.
|
new_id = each_changes_container.getId()
|
||||||
each_changes_container._id = self.getNewId(each_changes_container.getId())
|
|
||||||
|
|
||||||
# The container was not added yet, as it didn't have an unique ID. It does now, so add it.
|
|
||||||
self._container_registry.addContainer(each_changes_container)
|
|
||||||
|
|
||||||
# Find the old (current) changes container in the global stack
|
# Find the old (current) changes container in the global stack
|
||||||
if changes_container_type == "quality_changes":
|
if changes_container_type == "quality_changes":
|
||||||
@ -672,7 +741,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# Replace the quality/definition changes container if it's in the GlobalStack
|
# Replace the quality/definition changes container if it's in the GlobalStack
|
||||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||||
# so this comparison is fine.
|
# so this comparison is fine.
|
||||||
if old_container.getId() == old_id:
|
if self._id_mapping.get(old_container.getId()) == new_id:
|
||||||
if changes_container_type == "quality_changes":
|
if changes_container_type == "quality_changes":
|
||||||
global_stack.qualityChanges = each_changes_container
|
global_stack.qualityChanges = each_changes_container
|
||||||
elif changes_container_type == "definition_changes":
|
elif changes_container_type == "definition_changes":
|
||||||
@ -695,7 +764,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
|
|
||||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||||
# so this comparison is fine.
|
# so this comparison is fine.
|
||||||
if changes_container.getId() == old_id:
|
if self._id_mapping.get(changes_container.getId()) == new_id:
|
||||||
if changes_container_type == "quality_changes":
|
if changes_container_type == "quality_changes":
|
||||||
each_extruder_stack.qualityChanges = each_changes_container
|
each_extruder_stack.qualityChanges = each_changes_container
|
||||||
elif changes_container_type == "definition_changes":
|
elif changes_container_type == "definition_changes":
|
||||||
|
@ -7,6 +7,7 @@ from cura.Settings.ExtruderManager import ExtruderManager
|
|||||||
import zipfile
|
import zipfile
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import copy
|
import copy
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
|
||||||
class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
||||||
@ -48,6 +49,16 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||||||
Preferences.getInstance().writeToFile(preferences_string)
|
Preferences.getInstance().writeToFile(preferences_string)
|
||||||
archive.writestr(preferences_file, preferences_string.getvalue())
|
archive.writestr(preferences_file, preferences_string.getvalue())
|
||||||
|
|
||||||
|
# Save Cura version
|
||||||
|
version_file = zipfile.ZipInfo("Cura/version.ini")
|
||||||
|
version_config_parser = configparser.ConfigParser()
|
||||||
|
version_config_parser.add_section("versions")
|
||||||
|
version_config_parser.set("versions", "cura_version", Application.getStaticVersion())
|
||||||
|
|
||||||
|
version_file_string = StringIO()
|
||||||
|
version_config_parser.write(version_file_string)
|
||||||
|
archive.writestr(version_file, version_file_string.getvalue())
|
||||||
|
|
||||||
# Close the archive & reset states.
|
# Close the archive & reset states.
|
||||||
archive.close()
|
archive.close()
|
||||||
mesh_writer.setStoreArchive(False)
|
mesh_writer.setStoreArchive(False)
|
||||||
|
@ -79,7 +79,7 @@ The initial and final printing temperatures reduce the amount of oozing during P
|
|||||||
Initial and final printing temperature settings have been tuned for higher quality results. For all materials the initial print temperature is 5 degrees above the default value.
|
Initial and final printing temperature settings have been tuned for higher quality results. For all materials the initial print temperature is 5 degrees above the default value.
|
||||||
|
|
||||||
*Printing temperature of the materials
|
*Printing temperature of the materials
|
||||||
The printing temperature of the materials in the material profiles is now the same as the printing temperature for the Normal Quality profile.
|
The printing temperature of the materials in the material profiles is now the same as the printing temperature for the Fine profile.
|
||||||
|
|
||||||
*Improved PLA-PVA layer adhesion
|
*Improved PLA-PVA layer adhesion
|
||||||
The PVA jerk and acceleration have been optimized to improve the layer adhesion between PVA and PLA.
|
The PVA jerk and acceleration have been optimized to improve the layer adhesion between PVA and PLA.
|
||||||
|
@ -14,7 +14,7 @@ from UM.Settings.DefinitionContainer import DefinitionContainer
|
|||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
|
||||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
from cura.CuraApplication import CuraApplication
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
import UM.i18n
|
import UM.i18n
|
||||||
@ -99,6 +99,7 @@ class MachineSettingsAction(MachineAction):
|
|||||||
definition = container_stack.getBottom()
|
definition = container_stack.getBottom()
|
||||||
definition_changes_container.setDefinition(definition)
|
definition_changes_container.setDefinition(definition)
|
||||||
definition_changes_container.addMetaDataEntry("type", "definition_changes")
|
definition_changes_container.addMetaDataEntry("type", "definition_changes")
|
||||||
|
definition_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
|
|
||||||
self._container_registry.addContainer(definition_changes_container)
|
self._container_registry.addContainer(definition_changes_container)
|
||||||
container_stack.definitionChanges = definition_changes_container
|
container_stack.definitionChanges = definition_changes_container
|
||||||
|
@ -341,7 +341,6 @@ Cura.MachineAction
|
|||||||
sourceComponent: numericTextFieldWithUnit
|
sourceComponent: numericTextFieldWithUnit
|
||||||
property var propertyProvider: gantryHeightProvider
|
property var propertyProvider: gantryHeightProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
|
||||||
@ -385,7 +384,6 @@ Cura.MachineAction
|
|||||||
sourceComponent: numericTextFieldWithUnit
|
sourceComponent: numericTextFieldWithUnit
|
||||||
property var propertyProvider: materialDiameterProvider
|
property var propertyProvider: materialDiameterProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: false
|
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
@ -399,7 +397,6 @@ Cura.MachineAction
|
|||||||
sourceComponent: numericTextFieldWithUnit
|
sourceComponent: numericTextFieldWithUnit
|
||||||
property var propertyProvider: machineNozzleSizeProvider
|
property var propertyProvider: machineNozzleSizeProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,7 +547,6 @@ Cura.MachineAction
|
|||||||
sourceComponent: numericTextFieldWithUnit
|
sourceComponent: numericTextFieldWithUnit
|
||||||
property var propertyProvider: extruderNozzleSizeProvider
|
property var propertyProvider: extruderNozzleSizeProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
@ -564,6 +560,7 @@ Cura.MachineAction
|
|||||||
property var propertyProvider: extruderOffsetXProvider
|
property var propertyProvider: extruderOffsetXProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: true
|
property bool forceUpdateOnChange: true
|
||||||
|
property bool allowNegative: true
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
@ -576,6 +573,7 @@ Cura.MachineAction
|
|||||||
property var propertyProvider: extruderOffsetYProvider
|
property var propertyProvider: extruderOffsetYProvider
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property bool forceUpdateOnChange: true
|
property bool forceUpdateOnChange: true
|
||||||
|
property bool allowNegative: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,17 +653,21 @@ Cura.MachineAction
|
|||||||
Item {
|
Item {
|
||||||
height: textField.height
|
height: textField.height
|
||||||
width: textField.width
|
width: textField.width
|
||||||
|
|
||||||
|
property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative
|
||||||
|
property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange
|
||||||
|
|
||||||
TextField
|
TextField
|
||||||
{
|
{
|
||||||
id: textField
|
id: textField
|
||||||
text: (propertyProvider.properties.value) ? propertyProvider.properties.value : ""
|
text: (propertyProvider.properties.value) ? propertyProvider.properties.value : ""
|
||||||
validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
|
validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.]{0,6}/ : /[0-9\.]{0,6}/ }
|
||||||
onEditingFinished:
|
onEditingFinished:
|
||||||
{
|
{
|
||||||
if (propertyProvider && text != propertyProvider.properties.value)
|
if (propertyProvider && text != propertyProvider.properties.value)
|
||||||
{
|
{
|
||||||
propertyProvider.setPropertyValue("value", text);
|
propertyProvider.setPropertyValue("value", text);
|
||||||
if(forceUpdateOnChange)
|
if(_forceUpdateOnChange)
|
||||||
{
|
{
|
||||||
var extruderIndex = ExtruderManager.activeExtruderIndex;
|
var extruderIndex = ExtruderManager.activeExtruderIndex;
|
||||||
manager.forceUpdate();
|
manager.forceUpdate();
|
||||||
|
@ -11,7 +11,7 @@ from UM.Application import Application
|
|||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
import UM.Settings.InstanceContainer
|
import UM.Settings.InstanceContainer
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
## The Ultimaker Original can have a few revisions & upgrades. This action helps with selecting them, so they are added
|
## The Ultimaker Original can have a few revisions & upgrades. This action helps with selecting them, so they are added
|
||||||
# as a variant.
|
# as a variant.
|
||||||
@ -49,6 +49,7 @@ class UMOUpgradeSelection(MachineAction):
|
|||||||
definition = global_container_stack.getBottom()
|
definition = global_container_stack.getBottom()
|
||||||
definition_changes_container.setDefinition(definition)
|
definition_changes_container.setDefinition(definition)
|
||||||
definition_changes_container.addMetaDataEntry("type", "definition_changes")
|
definition_changes_container.addMetaDataEntry("type", "definition_changes")
|
||||||
|
definition_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
|
|
||||||
UM.Settings.ContainerRegistry.ContainerRegistry.getInstance().addContainer(definition_changes_container)
|
UM.Settings.ContainerRegistry.ContainerRegistry.getInstance().addContainer(definition_changes_container)
|
||||||
# Insert definition_changes between the definition and the variant
|
# Insert definition_changes between the definition and the variant
|
||||||
|
@ -142,6 +142,16 @@ class VersionUpgrade22to24(VersionUpgrade):
|
|||||||
config.write(output)
|
config.write(output)
|
||||||
return [filename], [output.getvalue()]
|
return [filename], [output.getvalue()]
|
||||||
|
|
||||||
|
def upgradeQuality(self, serialised, filename):
|
||||||
|
config = configparser.ConfigParser(interpolation = None)
|
||||||
|
config.read_string(serialised) # Read the input string as config file.
|
||||||
|
config.set("metadata", "type", "quality_changes") # Update metadata/type to quality_changes
|
||||||
|
config.set("general", "version", "2") # Just bump the version number. That is all we need for now.
|
||||||
|
|
||||||
|
output = io.StringIO()
|
||||||
|
config.write(output)
|
||||||
|
return [filename], [output.getvalue()]
|
||||||
|
|
||||||
def getCfgVersion(self, serialised):
|
def getCfgVersion(self, serialised):
|
||||||
parser = configparser.ConfigParser(interpolation = None)
|
parser = configparser.ConfigParser(interpolation = None)
|
||||||
parser.read_string(serialised)
|
parser.read_string(serialised)
|
||||||
|
@ -21,9 +21,9 @@ def getMetaData():
|
|||||||
# From To Upgrade function
|
# From To Upgrade function
|
||||||
("machine_instance", 2000000): ("machine_stack", 3000000, upgrade.upgradeMachineInstance),
|
("machine_instance", 2000000): ("machine_stack", 3000000, upgrade.upgradeMachineInstance),
|
||||||
("extruder_train", 2000000): ("extruder_train", 3000000, upgrade.upgradeExtruderTrain),
|
("extruder_train", 2000000): ("extruder_train", 3000000, upgrade.upgradeExtruderTrain),
|
||||||
("preferences", 3000000): ("preferences", 4000000, upgrade.upgradePreferences)
|
("preferences", 3000000): ("preferences", 4000000, upgrade.upgradePreferences),
|
||||||
|
("quality", 2000000): ("quality_changes", 2000000, upgrade.upgradeQuality),
|
||||||
},
|
},
|
||||||
"sources": {
|
"sources": {
|
||||||
"machine_stack": {
|
"machine_stack": {
|
||||||
"get_version": upgrade.getCfgVersion,
|
"get_version": upgrade.getCfgVersion,
|
||||||
|
@ -5,6 +5,7 @@ import configparser #To parse the files we need to upgrade and write the new fil
|
|||||||
import io #To serialise configparser output to a string.
|
import io #To serialise configparser output to a string.
|
||||||
|
|
||||||
from UM.VersionUpgrade import VersionUpgrade
|
from UM.VersionUpgrade import VersionUpgrade
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
_removed_settings = { #Settings that were removed in 2.5.
|
_removed_settings = { #Settings that were removed in 2.5.
|
||||||
"start_layers_at_same_position",
|
"start_layers_at_same_position",
|
||||||
@ -86,11 +87,17 @@ class VersionUpgrade25to26(VersionUpgrade):
|
|||||||
parser["values"][replacement] = parser["values"][replaced_setting] #Copy to replacement before removing the original!
|
parser["values"][replacement] = parser["values"][replaced_setting] #Copy to replacement before removing the original!
|
||||||
del replaced_setting
|
del replaced_setting
|
||||||
|
|
||||||
#Change the version number in the file.
|
for each_section in ("general", "metadata"):
|
||||||
if parser.has_section("general"):
|
if not parser.has_section(each_section):
|
||||||
parser["general"]["setting_version"] = "1"
|
parser.add_section(each_section)
|
||||||
|
|
||||||
|
# Change the version number in the file.
|
||||||
|
parser["metadata"]["setting_version"] = str(CuraApplication.SettingVersion)
|
||||||
|
|
||||||
|
# Update version
|
||||||
|
parser["general"]["version"] = "2"
|
||||||
|
|
||||||
#Re-serialise the file.
|
#Re-serialise the file.
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
parser.write(output)
|
parser.write(output)
|
||||||
return [filename], [output.getvalue()]
|
return [filename], [output.getvalue()]
|
||||||
|
@ -18,14 +18,16 @@ def getMetaData():
|
|||||||
"api": 3
|
"api": 3
|
||||||
},
|
},
|
||||||
"version_upgrade": {
|
"version_upgrade": {
|
||||||
# From To Upgrade function
|
# From To Upgrade function
|
||||||
("preferences", 4000000): ("preferences", 4000001, upgrade.upgradePreferences),
|
("preferences", 4000000): ("preferences", 4000001, upgrade.upgradePreferences),
|
||||||
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
|
# NOTE: All the instance containers share the same general/version, so we have to update all of them
|
||||||
("variant", 2000000): ("variant", 2000001, upgrade.upgradeInstanceContainer), #We can re-use upgradeContainerStack since there is nothing specific to quality, variant or user profiles being changed.
|
# if any is updated.
|
||||||
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer)
|
("quality_changes", 2000000): ("quality_changes", 2000001, upgrade.upgradeInstanceContainer),
|
||||||
|
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer),
|
||||||
|
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
|
||||||
},
|
},
|
||||||
"sources": {
|
"sources": {
|
||||||
"quality": {
|
"quality_changes": {
|
||||||
"get_version": upgrade.getCfgVersion,
|
"get_version": upgrade.getCfgVersion,
|
||||||
"location": {"./quality"}
|
"location": {"./quality"}
|
||||||
},
|
},
|
||||||
@ -36,7 +38,7 @@ def getMetaData():
|
|||||||
"user": {
|
"user": {
|
||||||
"get_version": upgrade.getCfgVersion,
|
"get_version": upgrade.getCfgVersion,
|
||||||
"location": {"./user"}
|
"location": {"./user"}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,10 +159,10 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
|
|
||||||
for key, value in metadata.items():
|
for key, value in metadata.items():
|
||||||
builder.start(key)
|
builder.start(key)
|
||||||
# Normally value is a string.
|
if value is not None: #Nones get handled well by the builder.
|
||||||
# Nones get handled well.
|
#Otherwise the builder always expects a string.
|
||||||
if isinstance(value, bool):
|
#Deserialize expects the stringified version.
|
||||||
value = str(value) # parseBool in deserialize expects 'True'.
|
value = str(value)
|
||||||
builder.data(value)
|
builder.data(value)
|
||||||
builder.end(key)
|
builder.end(key)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"variants_name": "Nozzle size",
|
"variants_name": "Nozzle size",
|
||||||
"preferred_variant": "*0.8*",
|
"preferred_variant": "*0.8*",
|
||||||
"preferred_material": "*pla*",
|
"preferred_material": "*pla*",
|
||||||
"preferred_quality": "*high*",
|
"preferred_quality": "*normal*",
|
||||||
|
|
||||||
"machine_extruder_trains":
|
"machine_extruder_trains":
|
||||||
{
|
{
|
||||||
|
@ -1323,7 +1323,7 @@
|
|||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value_warning": "4",
|
"maximum_value_warning": "5",
|
||||||
"maximum_value": "0 if spaghetti_infill_enabled else (999999 if infill_line_distance == 0 else (20 - math.log(infill_line_distance) / math.log(2)))",
|
"maximum_value": "0 if spaghetti_infill_enabled else (999999 if infill_line_distance == 0 else (20 - math.log(infill_line_distance) / math.log(2)))",
|
||||||
"enabled": "infill_sparse_density > 0 and infill_pattern != 'cubicsubdiv' and not spaghetti_infill_enabled",
|
"enabled": "infill_sparse_density > 0 and infill_pattern != 'cubicsubdiv' and not spaghetti_infill_enabled",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
@ -1953,7 +1953,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||||
"maximum_value_warning": "150",
|
"maximum_value_warning": "150",
|
||||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "support_interface_enable and support_enable",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"value": "speed_support / 1.5",
|
"value": "speed_support / 1.5",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -1970,7 +1970,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||||
"maximum_value_warning": "150",
|
"maximum_value_warning": "150",
|
||||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "support_roof_enable and support_enable",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"value": "speed_support_interface",
|
"value": "speed_support_interface",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -1986,7 +1986,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
|
||||||
"maximum_value_warning": "150",
|
"maximum_value_warning": "150",
|
||||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "support_bottom_enable and support_enable",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"value": "speed_support_interface",
|
"value": "speed_support_interface",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -2275,7 +2275,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"minimum_value_warning": "100",
|
"minimum_value_warning": "100",
|
||||||
"maximum_value_warning": "10000",
|
"maximum_value_warning": "10000",
|
||||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "resolveOrValue('acceleration_enabled') and support_interface_enable and support_enable",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -2292,7 +2292,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"minimum_value_warning": "100",
|
"minimum_value_warning": "100",
|
||||||
"maximum_value_warning": "10000",
|
"maximum_value_warning": "10000",
|
||||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "resolveOrValue('acceleration_enabled') and support_roof_enable and support_enable",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
@ -2308,7 +2308,7 @@
|
|||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"minimum_value_warning": "100",
|
"minimum_value_warning": "100",
|
||||||
"maximum_value_warning": "10000",
|
"maximum_value_warning": "10000",
|
||||||
"enabled": "resolveOrValue('acceleration_enabled') and extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "resolveOrValue('acceleration_enabled') and support_bottom_enable and support_enable",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
@ -2540,7 +2540,7 @@
|
|||||||
"value": "jerk_support",
|
"value": "jerk_support",
|
||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"maximum_value_warning": "50",
|
"maximum_value_warning": "50",
|
||||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -2555,9 +2555,8 @@
|
|||||||
"default_value": 20,
|
"default_value": 20,
|
||||||
"value": "jerk_support_interface",
|
"value": "jerk_support_interface",
|
||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"minimum_value_warning": "5",
|
|
||||||
"maximum_value_warning": "50",
|
"maximum_value_warning": "50",
|
||||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
@ -2571,9 +2570,8 @@
|
|||||||
"default_value": 20,
|
"default_value": 20,
|
||||||
"value": "jerk_support_interface",
|
"value": "jerk_support_interface",
|
||||||
"minimum_value": "0.1",
|
"minimum_value": "0.1",
|
||||||
"minimum_value_warning": "5",
|
|
||||||
"maximum_value_warning": "50",
|
"maximum_value_warning": "50",
|
||||||
"enabled": "resolveOrValue('jerk_enabled') and extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
@ -3158,7 +3156,7 @@
|
|||||||
"default_value": 0.1,
|
"default_value": 0.1,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"enabled": "support_enable",
|
"enabled": "support_enable",
|
||||||
"value": "extruderValue(support_extruder_nr, 'support_z_distance')",
|
"value": "support_z_distance",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
@ -3170,7 +3168,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value_warning": "machine_nozzle_size",
|
"maximum_value_warning": "machine_nozzle_size",
|
||||||
"default_value": 0.1,
|
"default_value": 0.1,
|
||||||
"value": "extruderValue(support_extruder_nr, 'support_z_distance') if resolveOrValue('support_type') == 'everywhere' else 0",
|
"value": "support_z_distance if support_type == 'everywhere' else 0",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"enabled": "support_enable and resolveOrValue('support_type') == 'everywhere'",
|
"enabled": "support_enable and resolveOrValue('support_type') == 'everywhere'",
|
||||||
@ -3213,11 +3211,11 @@
|
|||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value_warning": "extruderValue(support_infill_extruder_nr, 'support_xy_distance')",
|
"maximum_value_warning": "support_xy_distance",
|
||||||
"default_value": 0.2,
|
"default_value": 0.2,
|
||||||
"value": "machine_nozzle_size / 2",
|
"value": "machine_nozzle_size / 2",
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_xy_overrides_z') == 'z_overrides_xy'",
|
"enabled": "support_enable and support_xy_overrides_z == 'z_overrides_xy'",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_bottom_stair_step_height":
|
"support_bottom_stair_step_height":
|
||||||
@ -3315,10 +3313,10 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "0.2 + resolveOrValue('layer_height')",
|
"minimum_value_warning": "0.2 + layer_height",
|
||||||
"maximum_value_warning": "10",
|
"maximum_value_warning": "10",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "support_interface_enable and support_enable",
|
||||||
"settable_per_mesh": true,
|
"settable_per_mesh": true,
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
@ -3330,11 +3328,11 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "0.2 + resolveOrValue('layer_height')",
|
"minimum_value_warning": "0.2 + layer_height",
|
||||||
"maximum_value_warning": "10",
|
"maximum_value_warning": "10",
|
||||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_height')",
|
"value": "support_interface_height",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "support_roof_enable and support_enable",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_bottom_height":
|
"support_bottom_height":
|
||||||
@ -3344,12 +3342,12 @@
|
|||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_height')",
|
"value": "support_interface_height",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "min(0.2 + resolveOrValue('layer_height'), extruderValue(support_bottom_extruder_nr, 'support_bottom_stair_step_height'))",
|
"minimum_value_warning": "min(0.2 + layer_height, support_bottom_stair_step_height)",
|
||||||
"maximum_value_warning": "10",
|
"maximum_value_warning": "10",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "support_bottom_enable and support_enable",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3363,7 +3361,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value_warning": "support_interface_height",
|
"maximum_value_warning": "support_interface_height",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "support_interface_enable and support_enable",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_interface_density":
|
"support_interface_density":
|
||||||
@ -3376,7 +3374,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value_warning": "100",
|
"maximum_value_warning": "100",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "support_interface_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"children":
|
"children":
|
||||||
@ -3391,7 +3389,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "100",
|
"maximum_value": "100",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "support_roof_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"children":
|
"children":
|
||||||
@ -3407,7 +3405,7 @@
|
|||||||
"minimum_value_warning": "support_roof_line_width - 0.0001",
|
"minimum_value_warning": "support_roof_line_width - 0.0001",
|
||||||
"value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == 'grid' else (3 if support_roof_pattern == 'triangles' else 1))",
|
"value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == 'grid' else (3 if support_roof_pattern == 'triangles' else 1))",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "support_roof_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
}
|
}
|
||||||
@ -3423,7 +3421,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "100",
|
"maximum_value": "100",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "support_bottom_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"children":
|
"children":
|
||||||
@ -3439,7 +3437,7 @@
|
|||||||
"minimum_value_warning": "support_bottom_line_width - 0.0001",
|
"minimum_value_warning": "support_bottom_line_width - 0.0001",
|
||||||
"value": "0 if support_bottom_density == 0 else (support_bottom_line_width * 100) / support_bottom_density * (2 if support_bottom_pattern == 'grid' else (3 if support_bottom_pattern == 'triangles' else 1))",
|
"value": "0 if support_bottom_density == 0 else (support_bottom_line_width * 100) / support_bottom_density * (2 if support_bottom_pattern == 'grid' else (3 if support_bottom_pattern == 'triangles' else 1))",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "support_bottom_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
}
|
}
|
||||||
@ -3463,7 +3461,7 @@
|
|||||||
},
|
},
|
||||||
"default_value": "concentric",
|
"default_value": "concentric",
|
||||||
"limit_to_extruder": "support_interface_extruder_nr",
|
"limit_to_extruder": "support_interface_extruder_nr",
|
||||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
"enabled": "support_interface_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
"children":
|
"children":
|
||||||
@ -3485,7 +3483,7 @@
|
|||||||
"default_value": "concentric",
|
"default_value": "concentric",
|
||||||
"value": "support_interface_pattern",
|
"value": "support_interface_pattern",
|
||||||
"limit_to_extruder": "support_roof_extruder_nr",
|
"limit_to_extruder": "support_roof_extruder_nr",
|
||||||
"enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
|
"enabled": "support_roof_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
},
|
},
|
||||||
@ -3506,7 +3504,7 @@
|
|||||||
"default_value": "concentric",
|
"default_value": "concentric",
|
||||||
"value": "support_interface_pattern",
|
"value": "support_interface_pattern",
|
||||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||||
"enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
|
"enabled": "support_bottom_enable and support_enable",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
}
|
}
|
||||||
@ -3533,7 +3531,7 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "2 * machine_nozzle_size",
|
"minimum_value_warning": "2 * machine_nozzle_size",
|
||||||
"maximum_value_warning": "20",
|
"maximum_value_warning": "20",
|
||||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
"enabled": "support_enable and support_use_towers",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_minimal_diameter":
|
"support_minimal_diameter":
|
||||||
@ -3547,8 +3545,8 @@
|
|||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "2 * machine_nozzle_size",
|
"minimum_value_warning": "2 * machine_nozzle_size",
|
||||||
"maximum_value_warning": "20",
|
"maximum_value_warning": "20",
|
||||||
"maximum_value": "extruderValue(support_infill_extruder_nr, 'support_tower_diameter')",
|
"maximum_value": "support_tower_diameter",
|
||||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
"enabled": "support_enable and support_use_towers",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_tower_roof_angle":
|
"support_tower_roof_angle":
|
||||||
@ -3561,7 +3559,7 @@
|
|||||||
"maximum_value": "90",
|
"maximum_value": "90",
|
||||||
"default_value": 65,
|
"default_value": 65,
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"enabled": "support_enable and extruderValue(support_infill_extruder_nr, 'support_use_towers')",
|
"enabled": "support_enable and support_use_towers",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3624,7 +3622,7 @@
|
|||||||
"none": "None"
|
"none": "None"
|
||||||
},
|
},
|
||||||
"default_value": "brim",
|
"default_value": "brim",
|
||||||
"limit_to_extruder": "adhesion_extruder_nr",
|
"resolve": "extruderValue(adhesion_extruder_nr, 'adhesion_type')",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": false
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
@ -3787,7 +3785,7 @@
|
|||||||
"value": "resolveOrValue('layer_height')",
|
"value": "resolveOrValue('layer_height')",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "0.04",
|
"minimum_value_warning": "0.04",
|
||||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')",
|
"maximum_value_warning": "0.75 * machine_nozzle_size",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3802,8 +3800,8 @@
|
|||||||
"default_value": 0.4,
|
"default_value": 0.4,
|
||||||
"value": "line_width",
|
"value": "line_width",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.1",
|
"minimum_value_warning": "machine_nozzle_size * 0.1",
|
||||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 2",
|
"maximum_value_warning": "machine_nozzle_size * 2",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3817,8 +3815,8 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0.4,
|
"default_value": 0.4,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_surface_line_width')",
|
"minimum_value_warning": "raft_surface_line_width",
|
||||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_surface_line_width') * 3",
|
"maximum_value_warning": "raft_surface_line_width * 3",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"value": "raft_surface_line_width",
|
"value": "raft_surface_line_width",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -3835,7 +3833,7 @@
|
|||||||
"value": "resolveOrValue('layer_height') * 1.5",
|
"value": "resolveOrValue('layer_height') * 1.5",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "0.04",
|
"minimum_value_warning": "0.04",
|
||||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')",
|
"maximum_value_warning": "0.75 * machine_nozzle_size",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3850,8 +3848,8 @@
|
|||||||
"default_value": 0.7,
|
"default_value": 0.7,
|
||||||
"value": "line_width * 2",
|
"value": "line_width * 2",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.5",
|
"minimum_value_warning": "machine_nozzle_size * 0.5",
|
||||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 3",
|
"maximum_value_warning": "machine_nozzle_size * 3",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3866,7 +3864,7 @@
|
|||||||
"default_value": 0.9,
|
"default_value": 0.9,
|
||||||
"value": "raft_interface_line_width + 0.2",
|
"value": "raft_interface_line_width + 0.2",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_interface_line_width')",
|
"minimum_value_warning": "raft_interface_line_width",
|
||||||
"maximum_value_warning": "15.0",
|
"maximum_value_warning": "15.0",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -3883,7 +3881,7 @@
|
|||||||
"value": "resolveOrValue('layer_height_0') * 1.2",
|
"value": "resolveOrValue('layer_height_0') * 1.2",
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"minimum_value_warning": "0.04",
|
"minimum_value_warning": "0.04",
|
||||||
"maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'raft_base_line_width')",
|
"maximum_value_warning": "0.75 * raft_base_line_width",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3897,9 +3895,9 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0.8,
|
"default_value": 0.8,
|
||||||
"minimum_value": "0.001",
|
"minimum_value": "0.001",
|
||||||
"value": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 2",
|
"value": "machine_nozzle_size * 2",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 0.5",
|
"minimum_value_warning": "machine_nozzle_size * 0.5",
|
||||||
"maximum_value_warning": "extruderValue(adhesion_extruder_nr, 'machine_nozzle_size') * 3",
|
"maximum_value_warning": "machine_nozzle_size * 3",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true,
|
"settable_per_extruder": true,
|
||||||
@ -3914,7 +3912,7 @@
|
|||||||
"default_value": 1.6,
|
"default_value": 1.6,
|
||||||
"value": "raft_base_line_width * 2",
|
"value": "raft_base_line_width * 2",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "extruderValue(adhesion_extruder_nr, 'raft_base_line_width')",
|
"minimum_value_warning": "raft_base_line_width",
|
||||||
"maximum_value_warning": "100",
|
"maximum_value_warning": "100",
|
||||||
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
"enabled": "resolveOrValue('adhesion_type') == 'raft'",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
@ -4571,7 +4569,7 @@
|
|||||||
"magic_spiralize":
|
"magic_spiralize":
|
||||||
{
|
{
|
||||||
"label": "Spiralize Outer Contour",
|
"label": "Spiralize Outer Contour",
|
||||||
"description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid model into a single walled print with a solid bottom. This feature used to be called Joris in older versions.",
|
"description": "Spiralize smooths out the Z move of the outer edge. This will create a steady Z increase over the whole print. This feature turns a solid model into a single walled print with a solid bottom. This feature should only be enabled when each layer only contains a single part.",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"default_value": false,
|
"default_value": false,
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
|
4009
resources/i18n/jp/fdmprinter.def.json.po
Normal file
4009
resources/i18n/jp/fdmprinter.def.json.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -152,6 +152,7 @@ UM.PreferencesPage
|
|||||||
append({ text: "Suomi", code: "fi" })
|
append({ text: "Suomi", code: "fi" })
|
||||||
append({ text: "Français", code: "fr" })
|
append({ text: "Français", code: "fr" })
|
||||||
append({ text: "Italiano", code: "it" })
|
append({ text: "Italiano", code: "it" })
|
||||||
|
append({ text: "日本語", code: "jp" })
|
||||||
append({ text: "Nederlands", code: "nl" })
|
append({ text: "Nederlands", code: "nl" })
|
||||||
append({ text: "Português do Brasil", code: "ptbr" })
|
append({ text: "Português do Brasil", code: "ptbr" })
|
||||||
append({ text: "Русский", code: "ru" })
|
append({ text: "Русский", code: "ru" })
|
||||||
|
@ -24,66 +24,89 @@ TabView
|
|||||||
property double spoolLength: calculateSpoolLength()
|
property double spoolLength: calculateSpoolLength()
|
||||||
property real costPerMeter: calculateCostPerMeter()
|
property real costPerMeter: calculateCostPerMeter()
|
||||||
|
|
||||||
|
property bool reevaluateLinkedMaterials: false
|
||||||
|
property string linkedMaterialNames:
|
||||||
|
{
|
||||||
|
if (reevaluateLinkedMaterials)
|
||||||
|
{
|
||||||
|
reevaluateLinkedMaterials = false;
|
||||||
|
}
|
||||||
|
if(!base.containerId || !base.editingEnabled)
|
||||||
|
{
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId);
|
||||||
|
return linkedMaterials.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
Tab
|
Tab
|
||||||
{
|
{
|
||||||
title: catalog.i18nc("@title","Information")
|
title: catalog.i18nc("@title","Information")
|
||||||
|
|
||||||
anchors
|
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||||
{
|
|
||||||
leftMargin: UM.Theme.getSize("default_margin").width
|
|
||||||
topMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
bottomMargin: UM.Theme.getSize("default_margin").height
|
|
||||||
rightMargin: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollView
|
ScrollView
|
||||||
{
|
{
|
||||||
|
id: scrollView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
||||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||||
|
frameVisible: true
|
||||||
|
|
||||||
|
property real columnWidth: Math.floor(viewport.width * 0.5) - UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
Flow
|
Flow
|
||||||
{
|
{
|
||||||
id: containerGrid
|
id: containerGrid
|
||||||
|
|
||||||
width: base.width;
|
x: UM.Theme.getSize("default_margin").width
|
||||||
|
y: UM.Theme.getSize("default_lining").height
|
||||||
|
|
||||||
property real rowHeight: textField.height;
|
width: base.width
|
||||||
|
property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
|
||||||
ReadOnlyTextField
|
ReadOnlyTextField
|
||||||
{
|
{
|
||||||
id: displayNameTextField;
|
id: displayNameTextField;
|
||||||
width: base.secondColumnWidth;
|
width: scrollView.columnWidth;
|
||||||
text: properties.name;
|
text: properties.name;
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled;
|
||||||
onEditingFinished: base.setName(properties.name, text)
|
onEditingFinished: base.setName(properties.name, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
|
||||||
ReadOnlyTextField
|
ReadOnlyTextField
|
||||||
{
|
{
|
||||||
id: textField;
|
id: textField;
|
||||||
width: base.secondColumnWidth;
|
width: scrollView.columnWidth;
|
||||||
text: properties.supplier;
|
text: properties.supplier;
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled;
|
||||||
onEditingFinished: base.setMetaDataEntry("brand", properties.supplier, text)
|
onEditingFinished:
|
||||||
|
{
|
||||||
|
base.setMetaDataEntry("brand", properties.supplier, text);
|
||||||
|
pane.objectList.currentIndex = pane.getIndexById(base.containerId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
|
||||||
ReadOnlyTextField
|
ReadOnlyTextField
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
width: scrollView.columnWidth;
|
||||||
text: properties.material_type;
|
text: properties.material_type;
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled;
|
||||||
onEditingFinished: base.setMetaDataEntry("material", properties.material_type, text)
|
onEditingFinished:
|
||||||
|
{
|
||||||
|
base.setMetaDataEntry("material", properties.material_type, text);
|
||||||
|
pane.objectList.currentIndex = pane.getIndexById(base.containerId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
|
||||||
|
|
||||||
Row
|
Row
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
width: scrollView.columnWidth;
|
||||||
height: parent.rowHeight;
|
height: parent.rowHeight;
|
||||||
spacing: UM.Theme.getSize("default_margin").width/2
|
spacing: UM.Theme.getSize("default_margin").width/2
|
||||||
|
|
||||||
@ -115,11 +138,11 @@ TabView
|
|||||||
|
|
||||||
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
|
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
|
||||||
ReadOnlySpinBox
|
ReadOnlySpinBox
|
||||||
{
|
{
|
||||||
id: densitySpinBox
|
id: densitySpinBox
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
value: properties.density
|
value: properties.density
|
||||||
decimals: 2
|
decimals: 2
|
||||||
suffix: " g/cm³"
|
suffix: " g/cm³"
|
||||||
@ -130,11 +153,11 @@ TabView
|
|||||||
onValueChanged: updateCostPerMeter()
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
|
||||||
ReadOnlySpinBox
|
ReadOnlySpinBox
|
||||||
{
|
{
|
||||||
id: diameterSpinBox
|
id: diameterSpinBox
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
value: properties.diameter
|
value: properties.diameter
|
||||||
decimals: 2
|
decimals: 2
|
||||||
suffix: " mm"
|
suffix: " mm"
|
||||||
@ -145,11 +168,11 @@ TabView
|
|||||||
onValueChanged: updateCostPerMeter()
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
|
||||||
SpinBox
|
SpinBox
|
||||||
{
|
{
|
||||||
id: spoolCostSpinBox
|
id: spoolCostSpinBox
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
|
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
|
||||||
prefix: base.currency + " "
|
prefix: base.currency + " "
|
||||||
decimals: 2
|
decimals: 2
|
||||||
@ -161,11 +184,11 @@ TabView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
|
||||||
SpinBox
|
SpinBox
|
||||||
{
|
{
|
||||||
id: spoolWeightSpinBox
|
id: spoolWeightSpinBox
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
|
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
|
||||||
suffix: " g"
|
suffix: " g"
|
||||||
stepSize: 100
|
stepSize: 100
|
||||||
@ -178,24 +201,45 @@ TabView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
text: "~ %1 m".arg(Math.round(base.spoolLength))
|
text: "~ %1 m".arg(Math.round(base.spoolLength))
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
height: parent.rowHeight
|
height: parent.rowHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
|
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth
|
width: scrollView.columnWidth
|
||||||
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
|
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
|
||||||
verticalAlignment: Qt.AlignVCenter
|
verticalAlignment: Qt.AlignVCenter
|
||||||
height: parent.rowHeight
|
height: parent.rowHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
width: 2 * scrollView.columnWidth
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
|
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
visible: unlinkMaterialButton.visible
|
||||||
|
}
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: unlinkMaterialButton
|
||||||
|
text: catalog.i18nc("@label", "Unlink Material")
|
||||||
|
visible: base.linkedMaterialNames != ""
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
Cura.ContainerManager.unlinkMaterial(base.containerId)
|
||||||
|
base.reevaluateLinkedMaterials = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||||
|
|
||||||
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
|
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
|
||||||
@ -203,7 +247,7 @@ TabView
|
|||||||
ReadOnlyTextArea
|
ReadOnlyTextArea
|
||||||
{
|
{
|
||||||
text: properties.description;
|
text: properties.description;
|
||||||
width: base.firstColumnWidth + base.secondColumnWidth
|
width: 2 * scrollView.columnWidth
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled;
|
||||||
@ -216,13 +260,15 @@ TabView
|
|||||||
ReadOnlyTextArea
|
ReadOnlyTextArea
|
||||||
{
|
{
|
||||||
text: properties.adhesion_info;
|
text: properties.adhesion_info;
|
||||||
width: base.firstColumnWidth + base.secondColumnWidth
|
width: 2 * scrollView.columnWidth
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled;
|
||||||
|
|
||||||
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
|
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCostPerMeter()
|
function updateCostPerMeter()
|
||||||
@ -266,8 +312,10 @@ TabView
|
|||||||
{
|
{
|
||||||
id: label
|
id: label
|
||||||
width: base.firstColumnWidth;
|
width: base.firstColumnWidth;
|
||||||
height: spinBox.height
|
height: spinBox.height + UM.Theme.getSize("default_lining").height
|
||||||
text: model.label
|
text: model.label
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Qt.AlignVCenter
|
||||||
}
|
}
|
||||||
ReadOnlySpinBox
|
ReadOnlySpinBox
|
||||||
{
|
{
|
||||||
@ -380,6 +428,7 @@ TabView
|
|||||||
Cura.ContainerManager.setContainerName(base.containerId, new_value);
|
Cura.ContainerManager.setContainerName(base.containerId, new_value);
|
||||||
// update material name label. not so pretty, but it works
|
// update material name label. not so pretty, but it works
|
||||||
materialProperties.name = new_value;
|
materialProperties.name = new_value;
|
||||||
|
pane.objectList.currentIndex = pane.getIndexById(base.containerId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,12 @@ UM.ManagementPage
|
|||||||
|
|
||||||
title: catalog.i18nc("@title:tab", "Materials");
|
title: catalog.i18nc("@title:tab", "Materials");
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
// Workaround to make sure all of the items are visible
|
||||||
|
objectList.positionViewAtBeginning();
|
||||||
|
}
|
||||||
|
|
||||||
model: UM.InstanceContainersModel
|
model: UM.InstanceContainersModel
|
||||||
{
|
{
|
||||||
filter:
|
filter:
|
||||||
@ -81,6 +87,7 @@ UM.ManagementPage
|
|||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
|
forceActiveFocus();
|
||||||
if(!parent.ListView.isCurrentItem)
|
if(!parent.ListView.isCurrentItem)
|
||||||
{
|
{
|
||||||
parent.ListView.view.currentIndex = index;
|
parent.ListView.view.currentIndex = index;
|
||||||
@ -91,9 +98,11 @@ UM.ManagementPage
|
|||||||
}
|
}
|
||||||
|
|
||||||
activeId: Cura.MachineManager.activeMaterialId
|
activeId: Cura.MachineManager.activeMaterialId
|
||||||
activeIndex: {
|
activeIndex: getIndexById(activeId)
|
||||||
|
function getIndexById(material_id)
|
||||||
|
{
|
||||||
for(var i = 0; i < model.rowCount(); i++) {
|
for(var i = 0; i < model.rowCount(); i++) {
|
||||||
if (model.getItem(i).id == Cura.MachineManager.activeMaterialId) {
|
if (model.getItem(i).id == material_id) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,6 +144,24 @@ UM.ManagementPage
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Button
|
Button
|
||||||
|
{
|
||||||
|
text: catalog.i18nc("@action:button", "Create")
|
||||||
|
iconName: "list-add"
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
var material_id = Cura.ContainerManager.createMaterial()
|
||||||
|
if(material_id == "")
|
||||||
|
{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(Cura.MachineManager.hasMaterials)
|
||||||
|
{
|
||||||
|
Cura.MachineManager.setActiveMaterial(material_id)
|
||||||
|
}
|
||||||
|
base.objectList.currentIndex = base.getIndexById(material_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Button
|
||||||
{
|
{
|
||||||
text: catalog.i18nc("@action:button", "Duplicate");
|
text: catalog.i18nc("@action:button", "Duplicate");
|
||||||
iconName: "list-add";
|
iconName: "list-add";
|
||||||
@ -152,6 +179,7 @@ UM.ManagementPage
|
|||||||
{
|
{
|
||||||
Cura.MachineManager.setActiveMaterial(material_id)
|
Cura.MachineManager.setActiveMaterial(material_id)
|
||||||
}
|
}
|
||||||
|
base.objectList.currentIndex = base.getIndexById(material_id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Button
|
Button
|
||||||
@ -206,6 +234,8 @@ UM.ManagementPage
|
|||||||
|
|
||||||
properties: materialProperties
|
properties: materialProperties
|
||||||
containerId: base.currentItem != null ? base.currentItem.id : ""
|
containerId: base.currentItem != null ? base.currentItem.id : ""
|
||||||
|
|
||||||
|
property alias pane: base
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject
|
QtObject
|
||||||
@ -251,6 +281,10 @@ UM.ManagementPage
|
|||||||
{
|
{
|
||||||
Cura.ContainerManager.removeContainer(containers[i])
|
Cura.ContainerManager.removeContainer(containers[i])
|
||||||
}
|
}
|
||||||
|
if(base.objectList.currentIndex > 0)
|
||||||
|
{
|
||||||
|
base.objectList.currentIndex--;
|
||||||
|
}
|
||||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,17 +45,4 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
visible: base.readOnly
|
|
||||||
text: textArea.text
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: textArea.__style ? textArea.__style.textMargin : 4
|
|
||||||
|
|
||||||
color: palette.buttonText
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemPalette { id: palette }
|
|
||||||
}
|
}
|
||||||
|
@ -15,22 +15,19 @@ SettingItem
|
|||||||
contents: ComboBox
|
contents: ComboBox
|
||||||
{
|
{
|
||||||
id: control
|
id: control
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
model: Cura.ExtrudersModel
|
model: Cura.ExtrudersModel { onModelChanged: control.color = getItem(control.currentIndex).color }
|
||||||
{
|
|
||||||
id: extruders_model
|
|
||||||
onModelChanged: control.color = extruders_model.getItem(control.currentIndex).color
|
|
||||||
}
|
|
||||||
property string color:
|
|
||||||
{
|
|
||||||
var model_color = extruders_model.getItem(control.currentIndex).color;
|
|
||||||
return (model_color) ? model_color : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
textRole: "name"
|
textRole: "name"
|
||||||
|
|
||||||
anchors.fill: parent
|
onActivated:
|
||||||
onCurrentIndexChanged: updateCurrentColor();
|
{
|
||||||
|
forceActiveFocus();
|
||||||
|
propertyProvider.setPropertyValue("value", model.getItem(index).index);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex: propertyProvider.properties.value
|
||||||
|
|
||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
@ -39,6 +36,17 @@ SettingItem
|
|||||||
onWheel: wheel.accepted = true;
|
onWheel: wheel.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property string color: "#fff"
|
||||||
|
|
||||||
|
Binding
|
||||||
|
{
|
||||||
|
// We override the color property's value when the ExtruderModel changes. So we need to use an
|
||||||
|
// explicit binding here otherwise we do not handle value changes after the model changes.
|
||||||
|
target: control
|
||||||
|
property: "color"
|
||||||
|
value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : ""
|
||||||
|
}
|
||||||
|
|
||||||
style: ComboBoxStyle
|
style: ComboBoxStyle
|
||||||
{
|
{
|
||||||
background: Rectangle
|
background: Rectangle
|
||||||
@ -59,7 +67,19 @@ SettingItem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
border.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : control.hovered ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
|
border.color:
|
||||||
|
{
|
||||||
|
if(!enabled)
|
||||||
|
{
|
||||||
|
return UM.Theme.getColor("setting_control_disabled_border");
|
||||||
|
}
|
||||||
|
if(control.hovered || base.activeFocus)
|
||||||
|
{
|
||||||
|
UM.Theme.getColor("setting_control_border_highlight")
|
||||||
|
}
|
||||||
|
|
||||||
|
return UM.Theme.getColor("setting_control_border")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
label: Item
|
label: Item
|
||||||
{
|
{
|
||||||
@ -68,35 +88,36 @@ SettingItem
|
|||||||
id: swatch
|
id: swatch
|
||||||
height: UM.Theme.getSize("setting_control").height / 2
|
height: UM.Theme.getSize("setting_control").height / 2
|
||||||
width: height
|
width: height
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
color: control.color
|
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
border.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : UM.Theme.getColor("setting_control_border")
|
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
|
||||||
|
|
||||||
|
color: control.color
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
anchors.left: swatch.right
|
anchors
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width
|
{
|
||||||
anchors.right: downArrow.left
|
left: swatch.right;
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_lining").width
|
right: arrow.left;
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
verticalCenter: parent.verticalCenter
|
||||||
|
margins: UM.Theme.getSize("default_lining").width
|
||||||
|
}
|
||||||
|
width: parent.width - swatch.width;
|
||||||
|
|
||||||
text: control.currentText
|
text: control.currentText
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
|
color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
|
||||||
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
UM.RecolorImage
|
UM.RecolorImage
|
||||||
{
|
{
|
||||||
id: downArrow
|
id: arrow
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
source: UM.Theme.getIcon("arrow_bottom")
|
source: UM.Theme.getIcon("arrow_bottom")
|
||||||
@ -109,57 +130,5 @@ SettingItem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onActivated:
|
|
||||||
{
|
|
||||||
forceActiveFocus();
|
|
||||||
propertyProvider.setPropertyValue("value", extruders_model.getItem(index).index);
|
|
||||||
control.color = extruders_model.getItem(index).color;
|
|
||||||
}
|
|
||||||
|
|
||||||
onModelChanged: updateCurrentIndex();
|
|
||||||
|
|
||||||
Binding
|
|
||||||
{
|
|
||||||
target: control
|
|
||||||
property: "currentIndex"
|
|
||||||
value:
|
|
||||||
{
|
|
||||||
for(var i = 0; i < extruders_model.rowCount(); ++i)
|
|
||||||
{
|
|
||||||
if(extruders_model.getItem(i).index == propertyProvider.properties.value)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In some cases we want to update the current color without updating the currentIndex, so it's a seperate function.
|
|
||||||
function updateCurrentColor()
|
|
||||||
{
|
|
||||||
for(var i = 0; i < extruders_model.rowCount(); ++i)
|
|
||||||
{
|
|
||||||
if(extruders_model.getItem(i).index == currentIndex)
|
|
||||||
{
|
|
||||||
control.color = extruders_model.getItem(i).color;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCurrentIndex()
|
|
||||||
{
|
|
||||||
for(var i = 0; i < extruders_model.rowCount(); ++i)
|
|
||||||
{
|
|
||||||
if(extruders_model.getItem(i).index == propertyProvider.properties.value)
|
|
||||||
{
|
|
||||||
control.currentIndex = i;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentIndex = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_pri3
|
definition = abax_pri3
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = abax_pri3
|
definition = abax_pri3
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_pri3
|
definition = abax_pri3
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_pri5
|
definition = abax_pri5
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = abax_pri5
|
definition = abax_pri5
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_pri5
|
definition = abax_pri5
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_titan
|
definition = abax_titan
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = abax_titan
|
definition = abax_titan
|
||||||
[metadata]
|
[metadata]
|
||||||
type = quality
|
type = quality
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = abax_titan
|
definition = abax_titan
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = fdmprinter
|
definition = fdmprinter
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = fdmprinter
|
definition = fdmprinter
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = peopoly_moai
|
definition = peopoly_moai
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = peopoly_moai
|
definition = peopoly_moai
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Fast Print
|
name = Normal
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Fast Print
|
name = Normal
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Fast Print
|
name = Normal
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = High Quality
|
name = Extra Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Normal Quality
|
name = Fine
|
||||||
definition = ultimaker2_plus
|
definition = ultimaker2_plus
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user