diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 98dbf206bd..9f956edbea 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -255,8 +255,7 @@ class BuildVolume(SceneNode): skirt_line_count = profile.getSettingValue("skirt_line_count") skirt_size = skirt_distance + (skirt_line_count * profile.getSettingValue("skirt_line_width")) elif adhesion_type == "brim": - brim_line_count = profile.getSettingValue("brim_line_count") - skirt_size = brim_line_count * profile.getSettingValue("skirt_line_width") + skirt_size = profile.getSettingValue("brim_width") elif adhesion_type == "raft": skirt_size = profile.getSettingValue("raft_margin") @@ -270,4 +269,4 @@ class BuildVolume(SceneNode): def _clamp(self, value, min_value, max_value): return max(min(value, max_value), min_value) - _skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_line_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"] + _skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_line_width", "brim_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"] diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsDialog.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsDialog.qml new file mode 100644 index 0000000000..0215b7ba04 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsDialog.qml @@ -0,0 +1,157 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Uranium is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Window 2.2 + +import UM 1.1 as UM + +UM.Dialog { + id: settingPickDialog + title: catalog.i18nc("@title:window", "Pick a Setting to Customize") + property var settingCategoriesModel + + TextField { + id: filter; + + anchors { + top: parent.top; + left: parent.left; + right: parent.right; + } + + placeholderText: catalog.i18nc("@label:textbox", "Filter..."); + + onTextChanged: settingCategoriesModel.filter(text); + } + + ScrollView { + id: view; + anchors { + top: filter.bottom; + left: parent.left; + right: parent.right; + bottom: parent.bottom; + } + + Column { + width: view.width - UM.Theme.sizes.default_margin.width * 2; + height: childrenRect.height; + + Repeater { + id: settingList; + + model: settingPickDialog.settingCategoriesModel + + delegate: Item { + id: delegateItem; + + width: parent.width; + height: childrenRect.height; + + ToolButton { + id: categoryHeader; + text: model.name; + checkable: true; + width: parent.width; + onCheckedChanged: settingsColumn.state != "" ? settingsColumn.state = "" : settingsColumn.state = "collapsed"; + + style: ButtonStyle { + background: Rectangle + { + width: control.width; + height: control.height; + color: control.hovered ? palette.highlight : "transparent"; + } + label: Row + { + spacing: UM.Theme.sizes.default_margin.width; + Image + { + anchors.verticalCenter: parent.verticalCenter; + source: control.checked ? UM.Theme.icons.arrow_right : UM.Theme.icons.arrow_bottom; + } + Label + { + text: control.text; + font.bold: true; + color: control.hovered ? palette.highlightedText : palette.text; + } + } + } + } + + property variant settingsModel: model.settings; + + visible: model.visible; + + Column { + id: settingsColumn; + + anchors.top: categoryHeader.bottom; + + property real childrenHeight: + { + var h = 0.0; + for(var i in children) + { + var item = children[i]; + h += children[i].height; + if(item.settingVisible) + { + if(i > 0) + { + h += spacing; + } + } + } + return h; + } + + width: childrenRect.width; + height: childrenHeight; + Repeater { + model: delegateItem.settingsModel; + + delegate: ToolButton { + id: button; + x: model.depth * UM.Theme.sizes.default_margin.width; + text: model.name + tooltip: model.description; + + onClicked: { + var object_id = UM.ActiveTool.properties.Model.getItem(base.currentIndex).id; + UM.ActiveTool.properties.Model.addSettingOverride(object_id, model.key); + settingPickDialog.visible = false; + } + + states: State { + name: "filtered" + when: model.filtered || !model.visible || !model.enabled || model.global_only + PropertyChanges { target: button; height: 0; opacity: 0; } + } + } + } + + states: State { + name: "collapsed"; + + PropertyChanges { target: settingsColumn; opacity: 0; height: 0; } + } + } + } + } + } + } + + rightButtons: [ + Button { + text: catalog.i18nc("@action:button", "Cancel"); + onClicked: { + settingPickDialog.visible = false; + } + } + ] +} \ No newline at end of file diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 781b7b0f1c..ef28ccfde3 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -15,12 +15,21 @@ Item { height: 0; property variant position: mapToItem(null, 0, 0) + property var settingOverrideModel: UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings property real viewportWidth: UM.Application.mainWindow.width * UM.Application.mainWindow.viewportRect.width; property real viewportHeight: UM.Application.mainWindow.height * UM.Application.mainWindow.viewportRect.height; property int currentIndex; + onSettingOverrideModelChanged:{ + console.log(UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings) +// UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings.refresh() +// if (UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings == undefined){ +// +// } + } + Rectangle { id: settingsPanel; @@ -40,7 +49,6 @@ Item { DropArea { anchors.fill: parent; } - Button { id: closeButton; width: UM.Theme.sizes.message_close.width; @@ -101,25 +109,26 @@ Item { Repeater { id: settings; - model: UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings + model: base.settingOverrideModel UM.SettingItem { width: UM.Theme.sizes.setting.width; height: UM.Theme.sizes.setting.height; x: UM.Theme.sizes.per_object_settings_panel_border.width + 1 - name: model.label; + visible: !model.global_only; type: model.type; value: model.value; description: model.description; unit: model.unit; valid: model.valid; - options: model.options + options: model.options; style: UM.Theme.styles.setting_item; onItemValueChanged: { settings.model.setSettingValue(model.key, value) + base.settingOverrideModel = UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings } Button @@ -184,7 +193,10 @@ Item { } } - onClicked: settingPickDialog.visible = true; + onClicked: { + settingPickDialog.settingCategoriesModel.reload() + settingPickDialog.visible = true; + } Connections { @@ -249,153 +261,17 @@ Item { } } - UM.Dialog { + PerObjectSettingsDialog{ id: settingPickDialog + settingCategoriesModel: UM.SettingCategoriesModel { id: settingCategoriesModel; } - title: catalog.i18nc("@title:window", "Pick a Setting to Customize") - - TextField { - id: filter; - - anchors { - top: parent.top; - left: parent.left; - right: parent.right; - } - - placeholderText: catalog.i18nc("@label:textbox", "Filter..."); - - onTextChanged: settingCategoriesModel.filter(text); - } - - ScrollView { - id: view; - anchors { - top: filter.bottom; - left: parent.left; - right: parent.right; - bottom: parent.bottom; - } - - Column { - width: view.width - UM.Theme.sizes.default_margin.width * 2; - height: childrenRect.height; - - Repeater { - id: settingList; - - model: UM.SettingCategoriesModel { id: settingCategoriesModel; } - - delegate: Item { - id: delegateItem; - - width: parent.width; - height: childrenRect.height; - - ToolButton { - id: categoryHeader; - text: model.name; - checkable: true; - width: parent.width; - onCheckedChanged: settingsColumn.state != "" ? settingsColumn.state = "" : settingsColumn.state = "collapsed"; - - style: ButtonStyle { - background: Rectangle - { - width: control.width; - height: control.height; - color: control.hovered ? palette.highlight : "transparent"; - } - label: Row - { - spacing: UM.Theme.sizes.default_margin.width; - Image - { - anchors.verticalCenter: parent.verticalCenter; - source: control.checked ? UM.Theme.icons.arrow_right : UM.Theme.icons.arrow_bottom; - } - Label - { - text: control.text; - font.bold: true; - color: control.hovered ? palette.highlightedText : palette.text; - } - } - } - } - - property variant settingsModel: model.settings; - - visible: model.visible; - - Column { - id: settingsColumn; - - anchors.top: categoryHeader.bottom; - - property real childrenHeight: - { - var h = 0.0; - for(var i in children) - { - var item = children[i]; - h += children[i].height; - if(item.settingVisible) - { - if(i > 0) - { - h += spacing; - } - } - } - return h; - } - - width: childrenRect.width; - height: childrenHeight; - Repeater { - model: delegateItem.settingsModel; - - delegate: ToolButton { - id: button; - x: model.depth * UM.Theme.sizes.default_margin.width; - text: model.name; - tooltip: model.description; - - onClicked: { - var object_id = UM.ActiveTool.properties.Model.getItem(base.currentIndex).id; - UM.ActiveTool.properties.Model.addSettingOverride(object_id, model.key); - settingPickDialog.visible = false; - } - - states: State { - name: "filtered" - when: model.filtered || !model.visible || !model.enabled - PropertyChanges { target: button; height: 0; opacity: 0; } - } - } - } - - states: State { - name: "collapsed"; - - PropertyChanges { target: settingsColumn; opacity: 0; height: 0; } - } - } - } - } + onVisibilityChanged:{ + if (settingPickDialog.visibility == false){ + base.settingOverrideModel = UM.ActiveTool.properties.Model.getItem(base.currentIndex).settings } } - - rightButtons: [ - Button { - text: catalog.i18nc("@action:button", "Cancel"); - onClicked: { - settingPickDialog.visible = false; - } - } - ] } + SystemPalette { id: palette; } } diff --git a/plugins/PerObjectSettingsTool/SettingOverrideModel.py b/plugins/PerObjectSettingsTool/SettingOverrideModel.py index 74696f0ee6..f7411524b1 100644 --- a/plugins/PerObjectSettingsTool/SettingOverrideModel.py +++ b/plugins/PerObjectSettingsTool/SettingOverrideModel.py @@ -1,7 +1,7 @@ # Copyright (c) 2015 Ultimaker B.V. # Uranium is released under the terms of the AGPLv3 or higher. -from PyQt5.QtCore import Qt, pyqtSlot, QUrl +from PyQt5.QtCore import Qt, pyqtSlot, QUrl, pyqtSignal from UM.Application import Application from UM.Qt.ListModel import ListModel @@ -18,6 +18,7 @@ class SettingOverrideModel(ListModel): OptionsRole = Qt.UserRole + 8 WarningDescriptionRole = Qt.UserRole + 9 ErrorDescriptionRole = Qt.UserRole + 10 + GlobalOnlyRole = Qt.UserRole + 11 def __init__(self, node, parent = None): super().__init__(parent) @@ -38,6 +39,7 @@ class SettingOverrideModel(ListModel): self.addRoleName(self.OptionsRole, "options") self.addRoleName(self.WarningDescriptionRole, "warning_description") self.addRoleName(self.ErrorDescriptionRole, "error_description") + self.addRoleName(self.GlobalOnlyRole, "global_only") @pyqtSlot(str, "QVariant") def setSettingValue(self, key, value): @@ -50,7 +52,6 @@ class SettingOverrideModel(ListModel): if not self._node.getDecorator(SettingOverrideDecorator): self.clear() return - self._decorator = self._node.getDecorator(SettingOverrideDecorator) self._decorator.settingAdded.connect(self._onSettingsChanged) self._decorator.settingRemoved.connect(self._onSettingsChanged) @@ -68,6 +69,20 @@ class SettingOverrideModel(ListModel): model.appendItem({"value": str(value), "name": str(name)}) return model + @pyqtSlot() + def reload(self): + self.clear() + #if self._machine_instance: + #for category in self._machine_instance.getMachineDefinition().getAllCategories(): + #self.appendItem({ + #"id": category.getKey(), + #"name": category.getLabel(), + #"icon": category.getIcon(), + #"visible": category.isVisible(), + #"settings": SettingsFromCategoryModel.SettingsFromCategoryModel(category), + #"hiddenValuesCount": category.getHiddenValuesCount() + #}) + def _onSettingsChanged(self): self.clear() @@ -84,9 +99,9 @@ class SettingOverrideModel(ListModel): "valid": setting.validate(value), "options": self._createOptionsModel(setting.getOptions()), "warning_description": setting.getWarningDescription(), - "error_description": setting.getErrorDescription() + "error_description": setting.getErrorDescription(), + "global_only": setting.getGlobalOnly() }) - items.sort(key = lambda i: i["key"]) for item in items: diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index 4ce9b6fd94..9fe5ab33be 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -63,8 +63,10 @@ class RemovableDriveOutputDevice(OutputDevice): self._writing = True job.start() except PermissionError as e: + Logger.log("e", "Permission denied when trying to write to %s: %s", file_name, str(e)) raise OutputDeviceError.PermissionDeniedError() from e except OSError as e: + Logger.log("e", "Operating system would not let us write to %s: %s", file_name, str(e)) raise OutputDeviceError.WriteRequestFailedError() from e def _onProgress(self, job, progress): diff --git a/resources/machines/RigidBot.json b/resources/machines/RigidBot.json index ccdd6475f8..8e3793bec6 100644 --- a/resources/machines/RigidBot.json +++ b/resources/machines/RigidBot.json @@ -28,7 +28,7 @@ "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." }, "machine_end_gcode": { "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" diff --git a/resources/machines/RigidBotBig.json b/resources/machines/RigidBotBig.json index b3f3f29728..6518444db0 100644 --- a/resources/machines/RigidBotBig.json +++ b/resources/machines/RigidBotBig.json @@ -26,7 +26,7 @@ "machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" }, "machine_start_gcode": { - "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." + "default": ";Sliced at: {day} {date} {time}\n;Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;Print time: {print_time}\n;Filament used: {filament_amount}m {filament_weight}g\n;Filament cost: {filament_cost}\n;M190 S{print_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{travel_speed}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." }, "machine_end_gcode": { "default": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{travel_speed} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning\n;{profile_string}" diff --git a/resources/machines/fdmprinter.json b/resources/machines/fdmprinter.json index e28ad26a9d..3da70165bc 100644 --- a/resources/machines/fdmprinter.json +++ b/resources/machines/fdmprinter.json @@ -158,7 +158,8 @@ "default": 0.1, "min_value": "0.001", "min_value_warning": "0.04", - "max_value_warning": "0.32" + "max_value_warning": "0.32", + "global_only": "print_sequence != \"one_at_a_time\"" }, "layer_height_0": { "label": "Initial Layer Height", @@ -580,7 +581,7 @@ "description": "Data linking material flow (in mm³/s) to temperature (°C).", "unit": "", "type": "string", - "default": "[[0.1,180],[20,230]]", + "default": "[[3.5,200],[7.0,240]]", "enabled": "material_flow_dependent_temperature" }, "material_standby_temperature": { @@ -922,61 +923,17 @@ "default": 0.064, "visible": false, "inherit": false, - "enabled": "coasting_enable", - "children": { - "coasting_volume_retract": { - "label": "Retract-Coasting Volume", - "description": "The volume otherwise oozed in a travel move with retraction.", - "unit": "mm³", - "type": "float", - "default": 0.064, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - }, - "coasting_volume_move": { - "label": "Move-Coasting Volume", - "description": "The volume otherwise oozed in a travel move without retraction.", - "unit": "mm³", - "type": "float", - "default": 0.096, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - } - } + "enabled": "coasting_enable" }, "coasting_min_volume": { "label": "Minimal Volume Before Coasting", - "description": "The least volume an extrusion path should have to coast the full amount. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly.", + "description": "The least volume an extrusion path should have to coast the full amount. For smaller extrusion paths, less pressure has been built up in the bowden tube and so the coasted volume is scaled linearly. This value should always be larger than the Coasting Volume.", "unit": "mm³", "type": "float", "default": 0.8, + "min_value": "0", "visible": false, - "inherit": false, - "enabled": "coasting_enable", - "children": { - "coasting_min_volume_retract": { - "label": "Min Volume Retract-Coasting", - "description": "The minimum volume an extrusion path must have in order to coast the full amount before doing a retraction.", - "unit": "mm³", - "type": "float", - "default": 0.6, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - }, - "coasting_min_volume_move": { - "label": "Min Volume Move-Coasting", - "description": "The minimum volume an extrusion path must have in order to coast the full amount before doing a travel move without retraction.", - "unit": "mm³", - "type": "float", - "default": 0.8, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - } - } + "enabled": "coasting_enable" }, "coasting_speed": { "label": "Coasting Speed", @@ -986,29 +943,7 @@ "default": 90, "visible": false, "inherit": false, - "enabled": "coasting_enable", - "children": { - "coasting_speed_retract": { - "label": "Retract-Coasting Speed", - "description": "The speed by which to move during coasting before a retraction, relative to the speed of the extrusion path.", - "unit": "%", - "type": "float", - "default": 90, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - }, - "coasting_speed_move": { - "label": "Move-Coasting Speed", - "description": "The speed by which to move during coasting before a travel move without retraction, relative to the speed of the extrusion path.", - "unit": "%", - "type": "float", - "default": 90, - "visible": false, - "inherit": true, - "enabled": "coasting_enable" - } - } + "enabled": "coasting_enable" } } }, @@ -1311,7 +1246,7 @@ "enabled": "support_roof_enable" }, "support_use_towers": { - "label": "Use towers.", + "label": "Use towers", "description": "Use specialized towers to support tiny overhang areas. These towers have a larger diameter than the region they support. Near the overhang the towers' diameter decreases, forming a roof.", "type": "boolean", "default": true, @@ -1436,12 +1371,23 @@ "default": 250, "enabled": "adhesion_type == \"skirt\"" }, - "brim_line_count": { - "label": "Brim Line Count", - "description": "The number of lines used for a brim: More lines means a larger brim which sticks better, but this also makes your effective print area smaller.", - "type": "int", - "default": 10, - "enabled": "adhesion_type == \"brim\"" + "brim_width": { + "label": "Brim Width", + "description": "The distance from the model to the end of the brim. A larger brim sticks better to the build platform, but also makes your effective print area smaller.", + "type": "float", + "unit": "mm", + "default": 5.0, + "enabled": "adhesion_type == \"brim\"", + "children": { + "brim_line_count": { + "label": "Brim Line Count", + "description": "The number of lines used for a brim. More lines means a larger brim which sticks better to the build plate, but this also makes your effective print area smaller.", + "type": "int", + "default": 13, + "inherit_function": "math.ceil(parent_value / skirt_line_width)", + "enabled": "adhesion_type == \"brim\"" + } + } }, "raft_margin": { "label": "Raft Extra Margin", @@ -1718,7 +1664,8 @@ "one_at_a_time": "One at a Time" }, "default": "all_at_once", - "visible": true + "visible": true, + "global_only": true }, "magic_mesh_surface_mode": { "label": "Surface Mode",