Browse Source

Merge branch 'master' of github.com:Ultimaker/Cura

Jaime van Kessel 8 years ago
parent
commit
e0ef1c3e9d

+ 8 - 4
cura/BuildVolume.py

@@ -240,9 +240,11 @@ class BuildVolume(SceneNode):
             self._active_container_stack.propertyChanged.connect(self._onSettingPropertyChanged)
 
             self._width = self._active_container_stack.getProperty("machine_width", "value")
+            machine_height = self._active_container_stack.getProperty("machine_height", "value")
             if self._active_container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
-                self._height = self._active_container_stack.getProperty("gantry_height", "value")
-                self._buildVolumeMessage()
+                self._height = min(self._active_container_stack.getProperty("gantry_height", "value"), machine_height)
+                if self._height < machine_height:
+                    self._buildVolumeMessage()
             else:
                 self._height = self._active_container_stack.getProperty("machine_height", "value")
             self._depth = self._active_container_stack.getProperty("machine_depth", "value")
@@ -258,9 +260,11 @@ class BuildVolume(SceneNode):
 
         rebuild_me = False
         if setting_key == "print_sequence":
+            machine_height = self._active_container_stack.getProperty("machine_height", "value")
             if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time":
-                self._height = self._active_container_stack.getProperty("gantry_height", "value")
-                self._buildVolumeMessage()
+                self._height = min(self._active_container_stack.getProperty("gantry_height", "value"), machine_height)
+                if self._height < machine_height:
+                    self._buildVolumeMessage()
             else:
                 self._height = self._active_container_stack.getProperty("machine_height", "value")
             rebuild_me = True

+ 93 - 0
plugins/MachineSettingsAction/MachineSettingsAction.py

@@ -0,0 +1,93 @@
+# Copyright (c) 2016 Ultimaker B.V.
+# Cura is released under the terms of the AGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtSlot
+
+from cura.MachineAction import MachineAction
+import cura.Settings.CuraContainerRegistry
+
+import UM.Application
+import UM.Settings.InstanceContainer
+import UM.Settings.DefinitionContainer
+import UM.Logger
+
+import UM.i18n
+catalog = UM.i18n.i18nCatalog("cura")
+
+class MachineSettingsAction(MachineAction):
+    def __init__(self, parent = None):
+        super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
+        self._qml_url = "MachineSettingsAction.qml"
+
+        cura.Settings.CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
+
+    def _reset(self):
+        global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
+        if global_container_stack:
+            variant = global_container_stack.findContainer({"type": "variant"})
+            if variant and variant.getId() == "empty_variant":
+                variant_index = global_container_stack.getContainerIndex(variant)
+                self._createVariant(global_container_stack, variant_index)
+
+    def _createVariant(self, global_container_stack, variant_index):
+        # Create and switch to a variant to store the settings in
+        new_variant = UM.Settings.InstanceContainer(global_container_stack.getName() + "_variant")
+        new_variant.addMetaDataEntry("type", "variant")
+        new_variant.setDefinition(global_container_stack.getBottom())
+        UM.Settings.ContainerRegistry.getInstance().addContainer(new_variant)
+        global_container_stack.replaceContainer(variant_index, new_variant)
+
+    def _onContainerAdded(self, container):
+        # Add this action as a supported action to all machine definitions
+        if isinstance(container, UM.Settings.DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
+            if container.getProperty("machine_extruder_count", "value") > 1:
+                # Multiextruder printers are not currently supported
+                UM.Logger.log("d", "Not attaching MachineSettingsAction to %s; Multi-extrusion printers are not supported", container.getId())
+                return
+            if container.getMetaDataEntry("has_variants", False):
+                # Machines that use variants are not currently supported
+                UM.Logger.log("d", "Not attaching MachineSettingsAction to %s; Machines that use variants are not supported", container.getId())
+                return
+
+            UM.Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
+
+    @pyqtSlot()
+    def forceUpdate(self):
+        # Force rebuilding the build volume by reloading the global container stack.
+        # This is a bit of a hack, but it seems quick enough.
+        UM.Application.getInstance().globalContainerStackChanged.emit()
+
+    @pyqtSlot()
+    def updateHasMaterialsMetadata(self):
+        # Updates the has_materials metadata flag after switching gcode flavor
+        global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
+        if global_container_stack:
+            definition = global_container_stack.getBottom()
+            if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False):
+                has_materials = global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
+
+                material_container = global_container_stack.findContainer({"type": "material"})
+                material_index = global_container_stack.getContainerIndex(material_container)
+
+                if has_materials:
+                    if "has_materials" in global_container_stack.getMetaData():
+                        global_container_stack.setMetaDataEntry("has_materials", True)
+                    else:
+                        global_container_stack.addMetaDataEntry("has_materials", True)
+
+                    # Set the material container to a sane default
+                    if material_container.getId() == "empty_material":
+                        search_criteria = { "type": "material", "definition": "fdmprinter", "id": "*pla*" }
+                        containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
+                        if containers:
+                            global_container_stack.replaceContainer(material_index, containers[0])
+                else:
+                    # The metadata entry is stored in an ini, and ini files are parsed as strings only.
+                    # Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
+                    if "has_materials" in global_container_stack.getMetaData():
+                        global_container_stack.removeMetaDataEntry("has_materials")
+
+                    empty_material = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0]
+                    global_container_stack.replaceContainer(material_index, empty_material)
+
+                UM.Application.getInstance().globalContainerStackChanged.emit()

+ 476 - 0
plugins/MachineSettingsAction/MachineSettingsAction.qml

@@ -0,0 +1,476 @@
+// Copyright (c) 2016 Ultimaker B.V.
+// Cura is released under the terms of the AGPLv3 or higher.
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.1
+import QtQuick.Window 2.1
+
+import UM 1.2 as UM
+import Cura 1.0 as Cura
+
+
+Cura.MachineAction
+{
+    anchors.fill: parent;
+    Item
+    {
+        id: bedLevelMachineAction
+        anchors.fill: parent;
+
+        UM.I18nCatalog { id: catalog; name: "cura"; }
+
+        Label
+        {
+            id: pageTitle
+            width: parent.width
+            text: catalog.i18nc("@title", "Machine Settings")
+            wrapMode: Text.WordWrap
+            font.pointSize: 18;
+        }
+        Label
+        {
+            id: pageDescription
+            anchors.top: pageTitle.bottom
+            anchors.topMargin: UM.Theme.getSize("default_margin").height
+            width: parent.width
+            wrapMode: Text.WordWrap
+            text: catalog.i18nc("@label", "Please enter the correct settings for your printer below:")
+        }
+
+        Column
+        {
+            height: parent.height - y
+            width: parent.width - UM.Theme.getSize("default_margin").width
+            spacing: UM.Theme.getSize("default_margin").height
+
+            anchors.left: parent.left
+            anchors.top: pageDescription.bottom
+            anchors.topMargin: UM.Theme.getSize("default_margin").height
+
+            Row
+            {
+                width: parent.width
+                spacing: UM.Theme.getSize("default_margin").height
+
+                Column
+                {
+                    width: parent.width / 2
+                    spacing: UM.Theme.getSize("default_margin").height
+
+                    Label
+                    {
+                        text: catalog.i18nc("@label", "Printer Settings")
+                        font.bold: true
+                    }
+
+                    Grid
+                    {
+                        columns: 3
+                        columnSpacing: UM.Theme.getSize("default_margin").width
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "X (Width)")
+                        }
+                        TextField
+                        {
+                            id: buildAreaWidthField
+                            text: machineWidthProvider.properties.value
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: { machineWidthProvider.setPropertyValue("value", text); manager.forceUpdate() }
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Y (Depth)")
+                        }
+                        TextField
+                        {
+                            id: buildAreaDepthField
+                            text: machineDepthProvider.properties.value
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: { machineDepthProvider.setPropertyValue("value", text); manager.forceUpdate() }
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Z (Height)")
+                        }
+                        TextField
+                        {
+                            id: buildAreaHeightField
+                            text: machineHeightProvider.properties.value
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: { machineHeightProvider.setPropertyValue("value", text); manager.forceUpdate() }
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+                    }
+
+                    Column
+                    {
+                        CheckBox
+                        {
+                            id: heatedBedCheckBox
+                            text: catalog.i18nc("@option:check", "Heated Bed")
+                            checked: String(machineHeatedBedProvider.properties.value).toLowerCase() != 'false'
+                            onClicked: machineHeatedBedProvider.setPropertyValue("value", checked)
+                        }
+                        CheckBox
+                        {
+                            id: centerIsZeroCheckBox
+                            text: catalog.i18nc("@option:check", "Machine Center is Zero")
+                            checked: String(machineCenterIsZeroProvider.properties.value).toLowerCase() != 'false'
+                            onClicked: machineCenterIsZeroProvider.setPropertyValue("value", checked)
+                        }
+                    }
+
+                    Row
+                    {
+                        spacing: UM.Theme.getSize("default_margin").width
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "GCode Flavor")
+                        }
+
+                        ComboBox
+                        {
+                            model: ["RepRap (Marlin/Sprinter)", "UltiGCode"]
+                            currentIndex: machineGCodeFlavorProvider.properties.value != model[1] ? 0 : 1
+                            onActivated:
+                            {
+                                machineGCodeFlavorProvider.setPropertyValue("value", model[index]);
+                                manager.updateHasMaterialsMetadata();
+                            }
+                        }
+                    }
+                }
+
+                Column
+                {
+                    width: parent.width / 2
+                    spacing: UM.Theme.getSize("default_margin").height
+
+                    Label
+                    {
+                        text: catalog.i18nc("@label", "Printhead Settings")
+                        font.bold: true
+                    }
+
+                    Grid
+                    {
+                        columns: 3
+                        columnSpacing: UM.Theme.getSize("default_margin").width
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "X min")
+                        }
+                        TextField
+                        {
+                            id: printheadXMinField
+                            text: getHeadPolygonCoord("x", "min")
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: setHeadPolygon()
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Y min")
+                        }
+                        TextField
+                        {
+                            id: printheadYMinField
+                            text: getHeadPolygonCoord("y", "min")
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: setHeadPolygon()
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "X max")
+                        }
+                        TextField
+                        {
+                            id: printheadXMaxField
+                            text: getHeadPolygonCoord("x", "max")
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: setHeadPolygon()
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Y max")
+                        }
+                        TextField
+                        {
+                            id: printheadYMaxField
+                            text: getHeadPolygonCoord("y", "max")
+                            validator: RegExpValidator { regExp: /[0-9]{0,6}/ }
+                            onEditingFinished: setHeadPolygon()
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        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 }
+                        Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Gantry height")
+                        }
+                        TextField
+                        {
+                            id: gantryHeightField
+                            text: gantryHeightProvider.properties.value
+                            validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
+                            onEditingFinished: { gantryHeightProvider.setPropertyValue("value", text) }
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+
+                        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 }
+                        Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
+
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "Nozzle size")
+                        }
+                        TextField
+                        {
+                            id: nozzleSizeField
+                            text: machineNozzleSizeProvider.properties.value
+                            validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
+                            onEditingFinished: { machineNozzleSizeProvider.setPropertyValue("value", text) }
+                        }
+                        Label
+                        {
+                            text: catalog.i18nc("@label", "mm")
+                        }
+                    }
+                }
+            }
+
+            Row
+            {
+                spacing: UM.Theme.getSize("default_margin").width
+                anchors.left: parent.left
+                anchors.right: parent.right
+                height: parent.height - y
+                Column
+                {
+                    height: parent.height
+                    width: parent.width / 2
+                    Label
+                    {
+                        text: catalog.i18nc("@label", "Start Gcode")
+                    }
+                    TextArea
+                    {
+                        id: machineStartGcodeField
+                        width: parent.width
+                        height: parent.height - y
+                        text: machineStartGcodeProvider.properties.value
+                        onActiveFocusChanged:
+                        {
+                            if(!activeFocus)
+                            {
+                                machineStartGcodeProvider.setPropertyValue("value", machineStartGcodeField.text)
+                            }
+                        }
+                    }
+                }
+                Column {
+                    height: parent.height
+                    width: parent.width / 2
+                    Label
+                    {
+                        text: catalog.i18nc("@label", "End Gcode")
+                    }
+                    TextArea
+                    {
+                        id: machineEndGcodeField
+                        width: parent.width
+                        height: parent.height - y
+                        text: machineEndGcodeProvider.properties.value
+                        onActiveFocusChanged:
+                        {
+                            if(!activeFocus)
+                            {
+                                machineEndGcodeProvider.setPropertyValue("value", machineEndGcodeField.text)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    function getHeadPolygonCoord(axis, minMax)
+    {
+        var polygon = JSON.parse(machineHeadPolygonProvider.properties.value);
+        var item = (axis == "x") ? 0 : 1
+        var result = polygon[0][item];
+        for(var i = 1; i < polygon.length; i++) {
+            if (minMax == "min") {
+                result = Math.min(result, polygon[i][item]);
+            } else {
+                result = Math.max(result, polygon[i][item]);
+            }
+        }
+        return Math.abs(result);
+    }
+
+    function setHeadPolygon()
+    {
+        var polygon = [];
+        polygon.push([-parseFloat(printheadXMinField.text), parseFloat(printheadYMaxField.text)]);
+        polygon.push([-parseFloat(printheadXMinField.text),-parseFloat(printheadYMinField.text)]);
+        polygon.push([ parseFloat(printheadXMaxField.text), parseFloat(printheadYMaxField.text)]);
+        polygon.push([ parseFloat(printheadXMaxField.text),-parseFloat(printheadYMinField.text)]);
+        machineHeadPolygonProvider.setPropertyValue("value", JSON.stringify(polygon));
+        manager.forceUpdate();
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineWidthProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_width"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineDepthProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_depth"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineHeightProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_height"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineHeatedBedProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_heated_bed"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineCenterIsZeroProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_center_is_zero"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineGCodeFlavorProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_gcode_flavor"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineNozzleSizeProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_nozzle_size"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: gantryHeightProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "gantry_height"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineHeadPolygonProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_head_with_fans_polygon"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+
+    UM.SettingPropertyProvider
+    {
+        id: machineStartGcodeProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_start_gcode"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+    UM.SettingPropertyProvider
+    {
+        id: machineEndGcodeProvider
+
+        containerStackId: Cura.MachineManager.activeMachineId
+        key: "machine_end_gcode"
+        watchedProperties: [ "value" ]
+        storeIndex: 3
+    }
+
+}

+ 21 - 0
plugins/MachineSettingsAction/__init__.py

@@ -0,0 +1,21 @@
+# Copyright (c) 2016 Ultimaker B.V.
+# Cura is released under the terms of the AGPLv3 or higher.
+
+from . import MachineSettingsAction
+
+from UM.i18n import i18nCatalog
+catalog = i18nCatalog("cura")
+
+def getMetaData():
+    return {
+        "plugin": {
+            "name": catalog.i18nc("@label", "Machine Settings action"),
+            "author": "fieldOfView",
+            "version": "1.0",
+            "description": catalog.i18nc("@info:whatsthis", "Provides a way to change machine settings (such as build volume, nozzle size, etc)"),
+            "api": 3
+        }
+    }
+
+def register(app):
+    return { "machine_action": MachineSettingsAction.MachineSettingsAction() }

+ 16 - 0
resources/definitions/custom.def.json

@@ -0,0 +1,16 @@
+{
+    "id": "custom",
+    "version": 2,
+    "name": "Custom FDM printer",
+    "inherits": "fdmprinter",
+    "metadata": {
+        "visible": true,
+        "author": "Ultimaker",
+        "manufacturer": "Custom",
+        "category": "Custom",
+        "file_formats": "text/x-gcode",
+        "has_materials": true,
+        "preferred_material": "*pla*",
+        "first_start_actions": ["MachineSettingsAction"]
+    }
+}