From ade1c039ea3d0658158bcc273d20f4712e816da2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 20 Sep 2017 11:03:20 +0200 Subject: [PATCH 01/13] Print information not being set won't cause crash anymore --- plugins/CuraEngineBackend/CuraEngineBackend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index dd5b182607..cb7d333cde 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -195,8 +195,8 @@ class CuraEngineBackend(QObject, Backend): self.backendStateChange.emit(BackendState.Done) Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.") return - - Application.getInstance().getPrintInformation().setToZeroPrintInformation() + if Application.getInstance().getPrintInformation(): + Application.getInstance().getPrintInformation().setToZeroPrintInformation() self._stored_layer_data = [] self._stored_optimized_layer_data = [] From b434fdb875127bc999523b3ab5c8eee02b230b1e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 20 Sep 2017 13:35:13 +0200 Subject: [PATCH 02/13] Layerview scrollbar now has fixed size. Instead of using the size of the other items. This worked when the bar was still part of the larger view, but since it's now below the item it broke it. CURA-4342 --- plugins/LayerView/LayerView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LayerView/LayerView.qml b/plugins/LayerView/LayerView.qml index 274b5c695c..21032be6ea 100755 --- a/plugins/LayerView/LayerView.qml +++ b/plugins/LayerView/LayerView.qml @@ -342,7 +342,7 @@ Item { id: slider width: handleSize - height: parent.height - 2*UM.Theme.getSize("slider_layerview_margin").height + height: UM.Theme.getSize("layerview_menu_size").height anchors.top: parent.bottom anchors.topMargin: UM.Theme.getSize("slider_layerview_margin").height anchors.right: layerViewMenu.right From 4d99fb067f3f9a9187121cc67dd41a8b8a29ba7b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 20 Sep 2017 17:19:44 +0200 Subject: [PATCH 03/13] After disconnect a signal, now is reconnected the correct one - CURA-4327 --- cura/Settings/MachineManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 4fb700e5ea..e807e49200 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -965,7 +965,7 @@ class MachineManager(QObject): if container_type == "quality": stack.quality.nameChanged.disconnect(self._onQualityNameChanged) stack.setQuality(container, postpone_emit = postpone_emit) - stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged) + stack.quality.nameChanged.connect(self._onQualityNameChanged) elif container_type == "quality_changes" or container_type is None: # If the container is an empty container, we need to change the quality_changes. # Quality can never be set to empty. From cdc1b9ba66c17301b57a2918fb09956d383b5392 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 21 Sep 2017 14:28:22 +0200 Subject: [PATCH 04/13] CURA-4303 infill slider icon color, border, alignment --- resources/qml/SidebarSimple.qml | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 9bd5c7590a..f3202d0e63 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -509,21 +509,23 @@ Item } } - Item + Rectangle { id: infillIcon - width: (infillCellRight.width / 5) - (UM.Theme.getSize("sidebar_margin").width) + width: (parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width) height: width - anchors.right: infillCellRight.right - anchors.top: infillSlider.top + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 // we loop over all density icons and only show the one that has the current density and steps Repeater { id: infillIconList model: infillModel + anchors.fill: parent property int activeIndex: { for (var i = 0; i < infillModel.count; i++) { @@ -541,20 +543,21 @@ Item return -1 } - Item { + Rectangle + { anchors.fill: parent + visible: infillIconList.activeIndex == index - Rectangle { + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("quality_slider_available") + + UM.RecolorImage { anchors.fill: parent - visible: infillIconList.activeIndex == index - - UM.RecolorImage { - anchors.fill: parent - sourceSize.width: width - sourceSize.height: width - source: UM.Theme.getIcon(model.icon) - color: UM.Theme.getColor("quality_slider_available") - } + anchors.margins: 2 + sourceSize.width: width + sourceSize.height: width + source: UM.Theme.getIcon(model.icon) + color: UM.Theme.getColor("quality_slider_unavailable") } } } From ddfb5f0b48446fff8d5bb037bbb6f9b9b7892928 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 21 Sep 2017 15:09:04 +0200 Subject: [PATCH 05/13] fix conflict after revert --- plugins/3MFReader/ThreeMFReader.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index a19005057c..93a8dc1c65 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -12,7 +12,6 @@ from UM.Mesh.MeshBuilder import MeshBuilder from UM.Mesh.MeshReader import MeshReader from UM.Scene.GroupDecorator import GroupDecorator from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator -from cura.ZOffsetDecorator import ZOffsetDecorator from UM.Application import Application from cura.Settings.ExtruderManager import ExtruderManager from cura.QualityManager import QualityManager @@ -47,7 +46,7 @@ class ThreeMFReader(MeshReader): def _createMatrixFromTransformationString(self, transformation): if transformation == "": return Matrix() - + splitted_transformation = transformation.split() ## Transformation is saved as: ## M00 M01 M02 0.0 @@ -105,8 +104,8 @@ class ThreeMFReader(MeshReader): # Add the setting override decorator, so we can add settings to this node. if settings: um_node.addDecorator(SettingOverrideDecorator()) - global_container_stack = Application.getInstance().getGlobalContainerStack() + global_container_stack = Application.getInstance().getGlobalContainerStack() # Ensure the correct next container for the SettingOverride decorator is set. if global_container_stack: multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 @@ -144,15 +143,12 @@ class ThreeMFReader(MeshReader): if len(um_node.getChildren()) > 0: group_decorator = GroupDecorator() um_node.addDecorator(group_decorator) - um_node.setSelectable(True) - if um_node.getMeshData(): # Assuming that all nodes with mesh data are printable objects # affects (auto) slicing sliceable_decorator = SliceableObjectDecorator() um_node.addDecorator(sliceable_decorator) - return um_node def read(self, file_name): @@ -172,18 +168,10 @@ class ThreeMFReader(MeshReader): transform_matrix = Matrix() mesh_data = um_node.getMeshData() - if mesh_data is not None: extents = mesh_data.getExtents() center_vector = Vector(extents.center.x, extents.center.y, extents.center.z) - - # If the object in a saved project is below the bed, keep it that way - if extents.minimum.z < 0.0: - um_node.addDecorator(ZOffsetDecorator()) - um_node.callDecoration("setZOffset", extents.minimum.z) - transform_matrix.setByTranslation(center_vector) - transform_matrix.multiply(um_node.getLocalTransformation()) um_node.setTransformation(transform_matrix) @@ -207,7 +195,7 @@ class ThreeMFReader(MeshReader): translation_matrix.setByTranslation(translation_vector) transformation_matrix.multiply(translation_matrix) - # Third step: 3MF also defines a unit, whereas Cura always assumes mm. + # Third step: 3MF also defines a unit, wheras Cura always assumes mm. scale_matrix = Matrix() scale_matrix.setByScaleVector(self._getScaleFromUnit(self._unit)) transformation_matrix.multiply(scale_matrix) From 78987ba666c332920d7fea098a5388e342b099b6 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 21 Sep 2017 15:19:00 +0200 Subject: [PATCH 06/13] When tool icon can not be found in theme, try to find it in the plugin folder CURA-4345 --- resources/qml/Toolbar.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml index 0903c0555b..bc7905c527 100644 --- a/resources/qml/Toolbar.qml +++ b/resources/qml/Toolbar.qml @@ -34,7 +34,15 @@ Item Button { text: model.name - iconSource: UM.Theme.getIcon(model.icon); + iconSource: + { + var result = UM.Theme.getIcon(model.icon) + if(result == "") + { + return model.location + "/" + model.icon + } + return result + } checkable: true; checked: model.active; From e73e218c4e68e9b8554125c300099af77b25e14b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Thu, 21 Sep 2017 16:28:50 +0200 Subject: [PATCH 07/13] Detecting whether the profile is created for multiple extrusion printers or not - CURA-4327 --- cura/QualityManager.py | 4 +--- cura/Settings/QualityAndUserProfilesModel.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 813d23ea13..c0b5afb71e 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -61,8 +61,6 @@ class QualityManager: machine_definition = global_stack.definition result = self.findAllQualityChangesForMachine(machine_definition) - for extruder in self.findAllExtruderDefinitionsForMachine(machine_definition): - result.extend(self.findAllQualityChangesForExtruder(extruder)) result = [quality_change for quality_change in result if quality_change.getName() == quality_changes_name] return result @@ -151,7 +149,7 @@ class QualityManager: else: definition_id = "fdmprinter" - filter_dict = { "type": "quality_changes", "extruder": None, "definition": definition_id } + filter_dict = { "type": "quality_changes", "definition": definition_id } quality_changes_list = ContainerRegistry.getInstance().findInstanceContainers(**filter_dict) return quality_changes_list diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index b6ac3fb6d0..1fa45a5902 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -25,21 +25,30 @@ class QualityAndUserProfilesModel(ProfilesModel): machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom()) quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) + # Detecting if the machine has multiple extrusion + multiple_extrusion = False # Get the list of extruders and place the selected extruder at the front of the list. extruder_manager = ExtruderManager.getInstance() active_extruder = extruder_manager.getActiveExtruderStack() extruder_stacks = extruder_manager.getActiveExtruderStacks() if active_extruder in extruder_stacks: + multiple_extrusion = True extruder_stacks.remove(active_extruder) extruder_stacks = [active_extruder] + extruder_stacks # Fetch the list of useable qualities across all extruders. # The actual list of quality profiles come from the first extruder in the extruder list. - quality_list = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, + quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks) # Filter the quality_change by the list of available quality_types quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list]) - filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") is None] + + if multiple_extrusion: + # If the printer has multiple extruders then quality changes related to the current extruder are kept + filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set and qc.getMetaDataEntry("extruder") == active_extruder.definition.getId()] + else: + # If not, the quality changes of the global stack are selected + filtered_quality_changes = [qc for qc in quality_changes_list if qc.getMetaDataEntry("quality_type") in quality_type_set] return quality_list + filtered_quality_changes From ecafa248884cf27399f0bd82720def2c4bd633c6 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 21 Sep 2017 17:35:12 +0200 Subject: [PATCH 08/13] code cleanup --- cura/Settings/ProfilesModel.py | 1 + resources/qml/SidebarSimple.qml | 21 +++++++++------------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 4df362cdef..e39ed949b0 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -75,6 +75,7 @@ class ProfilesModel(InstanceContainersModel): # The actual list of quality profiles come from the first extruder in the extruder list. result = QualityManager.getInstance().findAllQualitiesForMachineAndMaterials(global_stack_definition, materials) + for quality in QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders( global_container_stack, extruder_stacks): if quality not in result: diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 76bfe6a8c2..ff2339371c 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -179,10 +179,8 @@ Item anchors.top: parent.top anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 color: UM.Theme.getColor("text") - text: - { - return Cura.ProfilesModel.getItem(index).layer_height_without_unit - } + text: Cura.ProfilesModel.getItem(index).layer_height_without_unit + width: 1 x: { @@ -213,7 +211,7 @@ Item height: 2 color: UM.Theme.getColor("quality_slider_unavailable") //radius: parent.radius - y: 9 + y: 8.5 x: 0 } @@ -248,14 +246,10 @@ Item value: qualityRow.qualitySliderSelectedValue - width:{ - return qualityRow.qualitySliderStep * (qualityRow.availableTotalTicks) - } + width: qualityRow.qualitySliderStep * (qualityRow.availableTotalTicks) anchors.right: parent.right - anchors.rightMargin:{ - return qualityRow.sliderMarginRight - } + anchors.rightMargin: qualityRow.sliderMarginRight style: SliderStyle { @@ -265,6 +259,7 @@ Item color: UM.Theme.getColor("quality_slider_available") radius: 1 } + handle: Item { Rectangle { id: qualityhandleButton @@ -334,7 +329,7 @@ Item id: infillCellLeft anchors.top: qualityRow.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2 anchors.left: parent.left width: UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width @@ -386,6 +381,8 @@ Item anchors.top: selectedInfillRateText.bottom anchors.left: parent.left + anchors.right: infillIcon.left + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width height: UM.Theme.getSize("sidebar_margin").height width: infillCellRight.width - UM.Theme.getSize("sidebar_margin").width - style.handleWidth From 7c462f57038447269505363848acc986bd5a8855 Mon Sep 17 00:00:00 2001 From: alekseisasin Date: Thu, 21 Sep 2017 17:36:12 +0200 Subject: [PATCH 09/13] After loading a model from a project Y position is ignored CURA-4269 --- plugins/3MFReader/ThreeMFReader.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 93a8dc1c65..c264c381f8 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -17,6 +17,7 @@ from cura.Settings.ExtruderManager import ExtruderManager from cura.QualityManager import QualityManager from UM.Scene.SceneNode import SceneNode from cura.SliceableObjectDecorator import SliceableObjectDecorator +from cura.ZOffsetDecorator import ZOffsetDecorator MYPY = False @@ -195,7 +196,7 @@ class ThreeMFReader(MeshReader): translation_matrix.setByTranslation(translation_vector) transformation_matrix.multiply(translation_matrix) - # Third step: 3MF also defines a unit, wheras Cura always assumes mm. + # Third step: 3MF also defines a unit, whereas Cura always assumes mm. scale_matrix = Matrix() scale_matrix.setByScaleVector(self._getScaleFromUnit(self._unit)) transformation_matrix.multiply(scale_matrix) @@ -203,6 +204,11 @@ class ThreeMFReader(MeshReader): # Pre multiply the transformation with the loaded transformation, so the data is handled correctly. um_node.setTransformation(um_node.getLocalTransformation().preMultiply(transformation_matrix)) + # If the object in a saved project is below the bed, keep it that way + if um_node.getMeshData() != None and um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y < 0: + um_node.addDecorator(ZOffsetDecorator()) + um_node.callDecoration("setZOffset",um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y) + result.append(um_node) except Exception: From 879b3df816a88373f64d85cd9b01fba64f0cac7b Mon Sep 17 00:00:00 2001 From: Aleksei Sasin Date: Thu, 21 Sep 2017 21:20:54 +0200 Subject: [PATCH 10/13] On Windows platform the qualitys slider is properly aligned CURA-4182 --- resources/qml/SidebarSimple.qml | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index ff2339371c..c91c1fcb93 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -53,7 +53,7 @@ Item Component.onCompleted: { - qualityRow.updateAvailableTotalTicks() + qualityRow.updateQualitySliderProperties() } Connections @@ -61,17 +61,10 @@ Item target: Cura.MachineManager onActiveQualityChanged: { - qualityRow.updateAvailableTotalTicks() + qualityRow.updateQualitySliderProperties() } } - /* - Component.onCompleted: - { - updateCurrentQualityIndex(); - updateBar(); - } - */ id: qualityRow @@ -84,7 +77,7 @@ Item property var sliderAvailableMax : 0 property var sliderMarginRight : 0 - function updateAvailableTotalTicks() + function updateQualitySliderProperties() { qualityRow.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0 @@ -142,12 +135,6 @@ Item qualityRow.sliderAvailableMin = availableMin qualityRow.sliderAvailableMax = availableMax - - //console.log("==>>FIND.availableMin: " + availableMin) - //console.log("==>>FIND.availableMax: " + availableMax) - //console.log("==>>FIND.qualitySliderSelectedValue: " + qualitySliderSelectedValue) - //console.log("==>>FIND.sliderMarginRightVALUE: "+ sliderMarginRight) - } height: UM.Theme.getSize("sidebar_margin").height @@ -211,7 +198,7 @@ Item height: 2 color: UM.Theme.getColor("quality_slider_unavailable") //radius: parent.radius - y: 8.5 + anchors.verticalCenter: qualityRowSlider.verticalCenter x: 0 } @@ -256,13 +243,14 @@ Item //Draw Available line groove: Rectangle { implicitHeight: 2 + anchors.verticalCenter: qualityRowSlider.verticalCenter color: UM.Theme.getColor("quality_slider_available") radius: 1 } - handle: Item { Rectangle { id: qualityhandleButton + anchors.verticalCenter: qualityRowSlider.verticalCenter anchors.centerIn: parent color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable") implicitWidth: 10 From d2de039371f3b1ebc0e45637972fcdb5397c13e9 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 21 Sep 2017 16:08:46 +0200 Subject: [PATCH 11/13] dont disappear when click on splashscreen CURA-4343 --- cura/CuraSplashScreen.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/CuraSplashScreen.py b/cura/CuraSplashScreen.py index 4fc81e815f..eedf1e3d53 100644 --- a/cura/CuraSplashScreen.py +++ b/cura/CuraSplashScreen.py @@ -41,6 +41,10 @@ class CuraSplashScreen(QSplashScreen): self._loading_image_rotation_angle -= 10 self.repaint() + # Override the mousePressEvent so the splashscreen doesn't disappear when clicked + def mousePressEvent(self, mouse_event): + pass + def drawContents(self, painter): if self._to_stop: return From e7e24caf97851f999c807fc88e9588fbd42108b2 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 09:31:11 +0200 Subject: [PATCH 12/13] CURA-4269 small code improvement for z-offset in project loading --- plugins/3MFReader/ThreeMFReader.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index c264c381f8..283a685498 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -204,10 +204,11 @@ class ThreeMFReader(MeshReader): # Pre multiply the transformation with the loaded transformation, so the data is handled correctly. um_node.setTransformation(um_node.getLocalTransformation().preMultiply(transformation_matrix)) - # If the object in a saved project is below the bed, keep it that way - if um_node.getMeshData() != None and um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y < 0: + # Check if the model is positioned below the build plate and honor that when loading project files. + if um_node.getMeshData() is not None: + z_offset_value = um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y um_node.addDecorator(ZOffsetDecorator()) - um_node.callDecoration("setZOffset",um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y) + um_node.callDecoration("setZOffset", z_offset_value) result.append(um_node) From 21ea99d9f2c77242c17ee35317f403b23597343c Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Fri, 22 Sep 2017 09:34:24 +0200 Subject: [PATCH 13/13] CURA-4269 small code improvement for z-offset in project loading --- plugins/3MFReader/ThreeMFReader.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 283a685498..57b3b9e0fd 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -206,9 +206,10 @@ class ThreeMFReader(MeshReader): # Check if the model is positioned below the build plate and honor that when loading project files. if um_node.getMeshData() is not None: - z_offset_value = um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y - um_node.addDecorator(ZOffsetDecorator()) - um_node.callDecoration("setZOffset", z_offset_value) + minimum_z_value = um_node.getMeshData().getExtents(um_node.getWorldTransformation()).minimum.y # y is z in transformation coordinates + if minimum_z_value < 0: + um_node.addDecorator(ZOffsetDecorator()) + um_node.callDecoration("setZOffset", minimum_z_value) result.append(um_node)