diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b85c1a2f54..2a96cc9ab3 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -625,7 +625,9 @@ class CuraApplication(QtApplication): camera.lookAt(Vector(0, 0, 0)) 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.setCameraTool(self.getController().getTool("CameraTool")) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 10934c2d31..24a7ee1ec4 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -77,8 +77,9 @@ class ExtruderManager(QObject): @pyqtProperty("QVariantMap", notify=extrudersChanged) def extruderIds(self): map = {} - for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]: - map[position] = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position].getId() + global_stack_id = Application.getInstance().getGlobalContainerStack().getId() + for position in self._extruder_trains[global_stack_id]: + map[position] = self._extruder_trains[global_stack_id][position].getId() return map @pyqtSlot(str, result = str) @@ -462,6 +463,7 @@ class ExtruderManager(QObject): for extruder in self.getMachineExtruders(machine_id): ContainerRegistry.getInstance().removeContainer(extruder.userChanges.getId()) ContainerRegistry.getInstance().removeContainer(extruder.getId()) + del self._extruder_trains[machine_id] ## Returns extruders for a specific machine. # diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0eafd33e94..ae9e9d329b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -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. 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) for container in containers: ContainerRegistry.getInstance().removeContainer(container.getId()) 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) def hasMaterials(self) -> bool: if self._global_container_stack: diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index dcfe268665..c3a628f758 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -393,12 +393,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader): global_stack_id_original = self._stripFileToId(global_stack_file) global_stack_id_new = global_stack_id_original global_stack_need_rename = False + + extruder_stack_id_map = {} # new and old ExtruderStack IDs map if self._resolve_strategies["machine"] == "new": # We need a new id if the id already exists if self._container_registry.findContainerStacks(id = global_stack_id_original): global_stack_id_new = self.getNewId(global_stack_id_original) 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: 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. @@ -492,9 +503,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader): instance_container.setDirty(True) 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. - extruder_id = instance_container.getMetaDataEntry("extruder", None) - if extruder_id: - new_extruder_id = self.getNewId(extruder_id) + old_extruder_id = instance_container.getMetaDataEntry("extruder", None) + if old_extruder_id: + new_extruder_id = extruder_stack_id_map[old_extruder_id] new_id = new_extruder_id + "_current_settings" instance_container._id = new_id instance_container.setName(new_id) @@ -535,9 +546,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # AND REFACTOR!!! 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. - extruder_id = instance_container.getMetaDataEntry("extruder", None) - if extruder_id: - new_extruder_id = self.getNewId(extruder_id) + old_extruder_id = instance_container.getMetaDataEntry("extruder", None) + if old_extruder_id: + new_extruder_id = extruder_stack_id_map[old_extruder_id] instance_container.setMetaDataEntry("extruder", new_extruder_id) machine_id = instance_container.getMetaDataEntry("machine", None) @@ -641,9 +652,22 @@ class ThreeMFWorkspaceReader(WorkspaceReader): elif self._resolve_strategies["machine"] == "new": # 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.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 stack._id = new_id @@ -660,17 +684,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader): elif self._resolve_strategies["machine"] == "new": # container not found, create a new one 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) extruder_stacks_added.append(stack) containers_added.append(stack) else: 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) except: Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index 654030b013..23dc7f073f 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -341,7 +341,6 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: gantryHeightProvider 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 } @@ -385,7 +384,6 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: materialDiameterProvider property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: false } Label { @@ -399,7 +397,6 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: machineNozzleSizeProvider property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: false } } } @@ -550,7 +547,6 @@ Cura.MachineAction sourceComponent: numericTextFieldWithUnit property var propertyProvider: extruderNozzleSizeProvider property string unit: catalog.i18nc("@label", "mm") - property bool forceUpdateOnChange: false } Label @@ -564,6 +560,7 @@ Cura.MachineAction property var propertyProvider: extruderOffsetXProvider property string unit: catalog.i18nc("@label", "mm") property bool forceUpdateOnChange: true + property bool allowNegative: true } Label { @@ -576,6 +573,7 @@ Cura.MachineAction property var propertyProvider: extruderOffsetYProvider property string unit: catalog.i18nc("@label", "mm") property bool forceUpdateOnChange: true + property bool allowNegative: true } } @@ -655,17 +653,21 @@ Cura.MachineAction Item { height: textField.height width: textField.width + + property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative + property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange + TextField { id: textField 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: { if (propertyProvider && text != propertyProvider.properties.value) { propertyProvider.setPropertyValue("value", text); - if(forceUpdateOnChange) + if(_forceUpdateOnChange) { var extruderIndex = ExtruderManager.activeExtruderIndex; manager.forceUpdate(); diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json index 6567f61fb3..f14f6572e4 100644 --- a/resources/definitions/cartesio.def.json +++ b/resources/definitions/cartesio.def.json @@ -19,7 +19,7 @@ "variants_name": "Nozzle size", "preferred_variant": "*0.8*", "preferred_material": "*pla*", - "preferred_quality": "*high*", + "preferred_quality": "*normal*", "machine_extruder_trains": { @@ -29,7 +29,7 @@ "3": "cartesio_extruder_3" }, "platform": "cartesio_platform.stl", - "platform_offset": [ -120, -1.5, 130], + "platform_offset": [ -220, -5, 150], "first_start_actions": ["MachineSettingsAction"], "supported_actions": ["MachineSettingsAction"] }, diff --git a/resources/meshes/cartesio_platform.stl b/resources/meshes/cartesio_platform.stl index 65f0204881..d73581838b 100644 Binary files a/resources/meshes/cartesio_platform.stl and b/resources/meshes/cartesio_platform.stl differ