From d662770b225fa066815af644851644b87a8f198f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 23 Aug 2017 16:27:26 +0200 Subject: [PATCH 1/5] Fix setting new material for stacks CURA-4204 When a new material is created during project file loading, the material for each stack is set according to the parent material ID, but actually the child material should be used. This fix uses a hack to find the corresponding child material for a stack so when a user chooses to create a new material during project file loading, the material can be correctly set. --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 62 ++++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 8fdb120189..5747001a64 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -814,29 +814,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader): each_extruder_stack.definitionChanges = each_changes_container if self._resolve_strategies["material"] == "new": + # the actual material instance container can have an ID such as + # __ + # which cannot be determined immediately, so here we use a HACK to find the right new material + # instance ID: + # - get the old material IDs for all material + # - find the old material with the longest common prefix in ID, that's the old material + # - update the name by replacing the old prefix with the new + # - find the new material container and set it to the stack + old_to_new_material_dict = {} for each_material in material_containers: - old_material = global_stack.material + # find the material's old name + for old_id, new_id in self._id_mapping.items(): + if each_material.getId() == new_id: + old_to_new_material_dict[old_id] = each_material + break - # check if the old material container has been renamed to this material container ID - # if the container hasn't been renamed, we do nothing. - new_id = self._id_mapping.get(old_material.getId()) - if new_id is None or new_id != each_material.getId(): - continue - - if old_material.getId() in self._id_mapping: - global_stack.material = each_material - - for each_extruder_stack in extruder_stacks: - old_material = each_extruder_stack.material - - # check if the old material container has been renamed to this material container ID - # if the container hasn't been renamed, we do nothing. - new_id = self._id_mapping.get(old_material.getId()) - if new_id is None or new_id != each_material.getId(): - continue - - if old_material.getId() in self._id_mapping: - each_extruder_stack.material = each_material + # replace old material in global and extruder stacks with new + self._replaceStackMaterialWithNew(global_stack, old_to_new_material_dict) + for each_extruder_stack in extruder_stacks: + self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict) if extruder_stacks: for stack in extruder_stacks: @@ -861,6 +858,29 @@ class ThreeMFWorkspaceReader(WorkspaceReader): nodes = [] return nodes + def _replaceStackMaterialWithNew(self, stack, old_new_material_dict): + old_material_id_in_stack = stack.material.getId() + best_matching_old_material_id = None + best_matching_old_meterial_prefix_length = -1 + for old_parent_material_id in old_new_material_dict: + if len(old_parent_material_id) < best_matching_old_meterial_prefix_length: + continue + if len(old_parent_material_id) <= len(old_material_id_in_stack): + if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]: + best_matching_old_meterial_prefix_length = len(old_parent_material_id) + best_matching_old_material_id = old_parent_material_id + + if best_matching_old_material_id is None: + return + + new_material_id = old_new_material_dict[best_matching_old_material_id].getId() + old_material_id_in_stack[len(best_matching_old_material_id):] + new_material_containers = self._container_registry.findInstanceContainers(id = new_material_id, type = "material") + if not new_material_containers: + Logger.log("e", "Cannot find new material container [%s]", new_material_id) + return + + stack.material = new_material_containers[0] + def _stripFileToId(self, file): mime_type = MimeTypeDatabase.getMimeTypeForFile(file) file = mime_type.stripExtension(file) From c37782d5441e79b09ee69de40d0e6e505d7e337c Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 23 Aug 2017 17:19:42 +0200 Subject: [PATCH 2/5] Stop slicing when a new slice is needed CURA-4206 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 3710d33965..d94c3be94f 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -427,6 +427,7 @@ class CuraEngineBackend(QObject, Backend): ## Convenient function: set need_slicing, emit state and clear layer data def needsSlicing(self): + self.stopSlicing() self._need_slicing = True self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NotStarted) From 3805d2ff9e3310d982bd558f9e2714f74709f372 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 23 Aug 2017 17:37:58 +0200 Subject: [PATCH 3/5] Add comments for HACK in project loading CURA-4204 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 30 +++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 5747001a64..6c6451c4c4 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -858,7 +858,35 @@ class ThreeMFWorkspaceReader(WorkspaceReader): nodes = [] return nodes + ## HACK: Replaces the material container in the given stack with a newly created material container. + # This function is used when the user chooses to resolve material conflicts by creating new ones. def _replaceStackMaterialWithNew(self, stack, old_new_material_dict): + # The material containers in the project file are 'parent' material such as "generic_pla", + # but a material container used in a global/extruder stack is a 'child' material, + # such as "generic_pla_ultimaker3_AA_0.4", which can be formalised as the following: + # + # __ + # + # In the project loading, when a user chooses to resolve material conflicts by creating new ones, + # the old 'parent' material ID and the new 'parent' material ID are known, but not the child material IDs. + # In this case, the global stack and the extruder stacks need to use the newly created material, but the + # material containers they use are 'child' material. So, here, we need to find the right 'child' material for + # the stacks. + # + # This hack approach works as follows: + # - No matter there is a child material or not, the actual material we are looking for has the prefix + # "", which is the old material name. For the material in a stack, we know that the new + # material's ID will be "_blabla..", so we just need to replace the old material ID + # with the new one to get the new 'child' material. + # - Because the material containers have IDs such as "m #nn", if we use simple prefix matching, there can + # be a problem in the following scenario: + # - there are two materials in the project file, namely "m #1" and "m #11" + # - the child materials in use are for example: "m #1_um3_aa04", "m #11_um3_aa04" + # - if we only check for a simple prefix match, then "m #11_um3_aa04" will match with "m #1", but they + # are not the same material + # To avoid this, when doing the prefix matching, we use the result with the longest mactching prefix. + + # find the old material ID old_material_id_in_stack = stack.material.getId() best_matching_old_material_id = None best_matching_old_meterial_prefix_length = -1 @@ -873,12 +901,14 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if best_matching_old_material_id is None: return + # find the new material container new_material_id = old_new_material_dict[best_matching_old_material_id].getId() + old_material_id_in_stack[len(best_matching_old_material_id):] new_material_containers = self._container_registry.findInstanceContainers(id = new_material_id, type = "material") if not new_material_containers: Logger.log("e", "Cannot find new material container [%s]", new_material_id) return + # replace the material in the given stack stack.material = new_material_containers[0] def _stripFileToId(self, file): From 3d44d3c4caf1db536048382f4aa6a1cbe578d904 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 23 Aug 2017 17:42:39 +0200 Subject: [PATCH 4/5] Add logging and minor fix for project loading CURA-4204 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 6c6451c4c4..3eb224fb15 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -832,8 +832,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # replace old material in global and extruder stacks with new self._replaceStackMaterialWithNew(global_stack, old_to_new_material_dict) - for each_extruder_stack in extruder_stacks: - self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict) + if extruder_stacks: + for each_extruder_stack in extruder_stacks: + self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict) if extruder_stacks: for stack in extruder_stacks: @@ -899,6 +900,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader): best_matching_old_material_id = old_parent_material_id if best_matching_old_material_id is None: + Logger.log("w", "Cannot find any matching old material ID for stack [%s] material [%s]. Something can go wrong", + stack.getId(), old_material_id_in_stack) return # find the new material container From a1fdcd0e489aab45f2cb20949ffe0a75d665e4f1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 24 Aug 2017 15:32:41 +0200 Subject: [PATCH 5/5] Update prime tower settings for PVA This reduces the jerk considerably and makes use of the new prime tower purge settings. --- resources/definitions/fdmprinter.def.json | 2 +- resources/variants/ultimaker3_bb0.8.inst.cfg | 2 ++ resources/variants/ultimaker3_bb04.inst.cfg | 2 ++ resources/variants/ultimaker3_extended_bb0.8.inst.cfg | 2 ++ resources/variants/ultimaker3_extended_bb04.inst.cfg | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 0eff9e470f..36580f7785 100755 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -4616,7 +4616,7 @@ "unit": "mm³", "default_value": 0, "minimum_value": "0", - "maximum_value_warning": "0.5", + "maximum_value_warning": "1", "settable_per_mesh": false, "settable_per_extruder": true }, diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg index ddb1aa3c7e..8ed7c92511 100644 --- a/resources/variants/ultimaker3_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_bb0.8.inst.cfg @@ -24,6 +24,7 @@ infill_overlap = 0 infill_pattern = triangles infill_wipe_dist = 0 jerk_enabled = True +jerk_prime_tower = =math.ceil(jerk_print * 2 / 25) jerk_print = 25 jerk_support = =math.ceil(jerk_print * 15 / 25) jerk_support_interface = =math.ceil(jerk_support * 10 / 15) @@ -38,6 +39,7 @@ material_print_temperature = =default_material_print_temperature + 10 material_standby_temperature = 100 multiple_mesh_overlap = 0 prime_tower_enable = False +prime_tower_purge_volume = 1 prime_tower_wipe_enabled = True raft_acceleration = =acceleration_layer_0 raft_airgap = 0 diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg index b5698dea54..a5aa03f1fa 100644 --- a/resources/variants/ultimaker3_bb04.inst.cfg +++ b/resources/variants/ultimaker3_bb04.inst.cfg @@ -14,11 +14,13 @@ acceleration_support_interface = =math.ceil(acceleration_support * 1500 / 2000) acceleration_support_bottom = =math.ceil(acceleration_support_interface * 100 / 1500) cool_fan_speed_max = =cool_fan_speed gradual_support_infill_steps = 2 +jerk_prime_tower = =math.ceil(jerk_print * 2 / 25) jerk_support = =math.ceil(jerk_print * 15 / 25) jerk_support_interface = =math.ceil(jerk_support * 10 / 15) jerk_support_bottom = =math.ceil(jerk_support_interface * 1 / 10) machine_nozzle_heat_up_speed = 1.5 machine_nozzle_id = BB 0.4 +prime_tower_purge_volume = 1 raft_base_speed = 20 raft_interface_speed = 20 raft_speed = 25 diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg index 55ed280f36..886167f714 100644 --- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg @@ -24,6 +24,7 @@ infill_overlap = 0 infill_pattern = triangles infill_wipe_dist = 0 jerk_enabled = True +jerk_prime_tower = =math.ceil(jerk_print * 2 / 25) jerk_print = 25 jerk_support = =math.ceil(jerk_print * 15 / 25) jerk_support_interface = =math.ceil(jerk_support * 10 / 15) @@ -38,6 +39,7 @@ material_print_temperature = =default_material_print_temperature + 10 material_standby_temperature = 100 multiple_mesh_overlap = 0 prime_tower_enable = False +prime_tower_purge_volume = 1 prime_tower_wipe_enabled = True raft_acceleration = =acceleration_layer_0 raft_airgap = 0 diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg index 7393b0a24a..eb9eefed0c 100644 --- a/resources/variants/ultimaker3_extended_bb04.inst.cfg +++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg @@ -14,11 +14,13 @@ acceleration_support_interface = =math.ceil(acceleration_support * 1500 / 2000) acceleration_support_bottom = =math.ceil(acceleration_support_interface * 100 / 1500) cool_fan_speed_max = =cool_fan_speed gradual_support_infill_steps = 2 +jerk_prime_tower = =math.ceil(jerk_print * 2 / 25) jerk_support = =math.ceil(jerk_print * 15 / 25) jerk_support_interface = =math.ceil(jerk_support * 10 / 15) jerk_support_bottom = =math.ceil(jerk_support_interface * 1 / 10) machine_nozzle_heat_up_speed = 1.5 machine_nozzle_id = BB 0.4 +prime_tower_purge_volume = 1 raft_base_speed = 20 raft_interface_speed = 20 raft_speed = 25