mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
Merge branch 'main' into ender3_v2_neo_config
This commit is contained in:
commit
7a6604d5fb
705 changed files with 2763 additions and 879 deletions
|
@ -350,6 +350,7 @@ class CuraConan(ConanFile):
|
|||
self.requires("cpython/3.10.4@ultimaker/stable")
|
||||
self.requires("clipper/6.4.2@ultimaker/stable")
|
||||
self.requires("openssl/3.2.0")
|
||||
self.requires("protobuf/3.21.12")
|
||||
self.requires("boost/1.82.0")
|
||||
self.requires("spdlog/1.12.0")
|
||||
self.requires("fmt/10.1.1")
|
||||
|
|
|
@ -880,7 +880,7 @@ class BuildVolume(SceneNode):
|
|||
result[extruder.getId()] = []
|
||||
|
||||
# Currently, the only normally printed object is the prime tower.
|
||||
if self._global_container_stack.getProperty("prime_tower_mode", "value") != 'none':
|
||||
if self._global_container_stack.getProperty("prime_tower_enable", "value"):
|
||||
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
|
@ -1208,7 +1208,7 @@ class BuildVolume(SceneNode):
|
|||
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_layers", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
|
||||
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
|
||||
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "prime_blob_enable"]
|
||||
_tower_settings = ["prime_tower_mode", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable", "prime_tower_base_size", "prime_tower_base_height"]
|
||||
_tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y", "prime_tower_brim_enable", "prime_tower_base_size", "prime_tower_base_height"]
|
||||
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
|
||||
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts", "travel_avoid_supports", "wall_line_count", "wall_line_width_0", "wall_line_width_x"]
|
||||
_extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "skirt_brim_extruder_nr", "raft_base_extruder_nr", "raft_interface_extruder_nr", "raft_surface_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
|
||||
|
|
|
@ -273,7 +273,11 @@ class CuraActions(QObject):
|
|||
# deselect currently selected nodes, and select the new nodes
|
||||
for node in Selection.getAllSelectedObjects():
|
||||
Selection.remove(node)
|
||||
|
||||
numberOfFixedNodes = len(fixed_nodes)
|
||||
for node in nodes:
|
||||
numberOfFixedNodes += 1
|
||||
node.printOrder = numberOfFixedNodes
|
||||
Selection.add(node)
|
||||
|
||||
def _openUrl(self, url: QUrl) -> None:
|
||||
|
|
|
@ -601,7 +601,9 @@ class CuraApplication(QtApplication):
|
|||
preferences.addPreference("mesh/scale_to_fit", False)
|
||||
preferences.addPreference("mesh/scale_tiny_meshes", True)
|
||||
preferences.addPreference("cura/dialog_on_project_save", True)
|
||||
preferences.addPreference("cura/dialog_on_ucp_project_save", True)
|
||||
preferences.addPreference("cura/asked_dialog_on_project_save", False)
|
||||
preferences.addPreference("cura/asked_dialog_on_ucp_project_save", False)
|
||||
preferences.addPreference("cura/choice_on_profile_override", "always_ask")
|
||||
preferences.addPreference("cura/choice_on_open_project", "always_ask")
|
||||
preferences.addPreference("cura/use_multi_build_plate", False)
|
||||
|
@ -617,6 +619,7 @@ class CuraApplication(QtApplication):
|
|||
|
||||
preferences.addPreference("view/invert_zoom", False)
|
||||
preferences.addPreference("view/filter_current_build_plate", False)
|
||||
preferences.addPreference("view/navigation_style", "cura")
|
||||
preferences.addPreference("cura/sidebar_collapsed", False)
|
||||
|
||||
preferences.addPreference("cura/favorite_materials", "")
|
||||
|
@ -1082,9 +1085,9 @@ class CuraApplication(QtApplication):
|
|||
def getTextManager(self, *args) -> "TextManager":
|
||||
return self._text_manager
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def getWorkplaceDropToBuildplate(self, drop_to_build_plate: bool) ->None:
|
||||
return self._physics.setAppPerModelDropDown(drop_to_build_plate)
|
||||
@pyqtSlot()
|
||||
def setWorkplaceDropToBuildplate(self):
|
||||
return self._physics.setAppAllModelDropDown()
|
||||
|
||||
def getCuraFormulaFunctions(self, *args) -> "CuraFormulaFunctions":
|
||||
if self._cura_formula_functions is None:
|
||||
|
@ -1141,6 +1144,16 @@ class CuraApplication(QtApplication):
|
|||
self._build_plate_model = BuildPlateModel(self)
|
||||
return self._build_plate_model
|
||||
|
||||
@pyqtSlot()
|
||||
def exportUcp(self):
|
||||
writer = self.getMeshFileHandler().getWriter("3MFWriter")
|
||||
|
||||
if writer is None:
|
||||
Logger.warning("3mf writer is not enabled")
|
||||
return
|
||||
|
||||
writer.exportUcp()
|
||||
|
||||
def getCuraSceneController(self, *args) -> CuraSceneController:
|
||||
if self._cura_scene_controller is None:
|
||||
self._cura_scene_controller = CuraSceneController.createCuraSceneController()
|
||||
|
|
|
@ -38,14 +38,12 @@ class PlatformPhysics:
|
|||
self._minimum_gap = 2 # It is a minimum distance (in mm) between two models, applicable for small models
|
||||
|
||||
Application.getInstance().getPreferences().addPreference("physics/automatic_push_free", False)
|
||||
Application.getInstance().getPreferences().addPreference("physics/automatic_drop_down", False)
|
||||
self._app_per_model_drop = Application.getInstance().getPreferences().getValue("physics/automatic_drop_down")
|
||||
Application.getInstance().getPreferences().addPreference("physics/automatic_drop_down", True)
|
||||
self._app_all_model_drop = False
|
||||
|
||||
def getAppPerModelDropDown(self):
|
||||
return self._app_per_model_drop
|
||||
|
||||
def setAppPerModelDropDown(self, drop_to_buildplate):
|
||||
self._app_per_model_drop = drop_to_buildplate
|
||||
def setAppAllModelDropDown(self):
|
||||
self._app_all_model_drop = True
|
||||
self._onChangeTimerFinished()
|
||||
|
||||
def _onSceneChanged(self, source):
|
||||
if not source.callDecoration("isSliceable"):
|
||||
|
@ -78,7 +76,6 @@ class PlatformPhysics:
|
|||
# We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A.
|
||||
# By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve.
|
||||
random.shuffle(nodes)
|
||||
|
||||
for node in nodes:
|
||||
if node is root or not isinstance(node, SceneNode) or node.getBoundingBox() is None:
|
||||
continue
|
||||
|
@ -88,10 +85,7 @@ class PlatformPhysics:
|
|||
# Move it downwards if bottom is above platform
|
||||
move_vector = Vector()
|
||||
|
||||
# if per model drop is different then app_automatic_drop, in case of 3mf loading when user changes this setting for that model
|
||||
if (self._app_per_model_drop != app_automatic_drop_down):
|
||||
node.setSetting(SceneNodeSettings.AutoDropDown, self._app_per_model_drop)
|
||||
if node.getSetting(SceneNodeSettings.AutoDropDown, self._app_per_model_drop) and not (node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent() != root) and node.isEnabled(): #If an object is grouped, don't move it down
|
||||
if (node.getSetting(SceneNodeSettings.AutoDropDown, app_automatic_drop_down) or self._app_all_model_drop) and not (node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent() != root) and node.isEnabled():
|
||||
z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
|
||||
move_vector = move_vector.set(y=-bbox.bottom + z_offset)
|
||||
|
||||
|
@ -180,7 +174,7 @@ class PlatformPhysics:
|
|||
op.push()
|
||||
|
||||
# setting this drop to model same as app_automatic_drop_down
|
||||
self._app_per_model_drop = app_automatic_drop_down
|
||||
self._app_all_model_drop = False
|
||||
# After moving, we have to evaluate the boundary checks for nodes
|
||||
build_volume.updateNodeBoundaryCheck()
|
||||
|
||||
|
|
|
@ -116,6 +116,9 @@ class PrintOrderManager(QObject):
|
|||
) -> (Optional[CuraSceneNode], Optional[CuraSceneNode], Optional[CuraSceneNode]):
|
||||
nodes = self._get_nodes()
|
||||
ordered_nodes = sorted(nodes, key=lambda n: n.printOrder)
|
||||
for i, node in enumerate(ordered_nodes, 1):
|
||||
node.printOrder = i
|
||||
|
||||
selected_node = PrintOrderManager._getSingleSelectedNode()
|
||||
if selected_node and selected_node in ordered_nodes:
|
||||
selected_node_index = ordered_nodes.index(selected_node)
|
||||
|
|
|
@ -11,6 +11,7 @@ from UM.Scene.SceneNode import SceneNode
|
|||
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator # To cast the deepcopy of every decorator back to SceneNodeDecorator.
|
||||
|
||||
import cura.CuraApplication # To get the build plate.
|
||||
from UM.Scene.SceneNodeSettings import SceneNodeSettings
|
||||
from cura.Settings.ExtruderStack import ExtruderStack # For typing.
|
||||
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator # For per-object settings.
|
||||
|
||||
|
@ -41,6 +42,10 @@ class CuraSceneNode(SceneNode):
|
|||
def isOutsideBuildArea(self) -> bool:
|
||||
return self._outside_buildarea or self.callDecoration("getBuildPlateNumber") < 0
|
||||
|
||||
@property
|
||||
def isDropDownEnabled(self) ->bool:
|
||||
return self.getSetting(SceneNodeSettings.AutoDropDown, Application.getInstance().getPreferences().getValue("physics/automatic_drop_down"))
|
||||
|
||||
def isVisible(self) -> bool:
|
||||
return super().isVisible() and self.callDecoration("getBuildPlateNumber") == cura.CuraApplication.CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
|
||||
|
||||
|
|
38
plugins/3MFReader/SpecificSettingsModel.py
Normal file
38
plugins/3MFReader/SpecificSettingsModel.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Copyright (c) 2024 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from UM.Settings.SettingDefinition import SettingDefinition
|
||||
from UM.Qt.ListModel import ListModel
|
||||
|
||||
|
||||
class SpecificSettingsModel(ListModel):
|
||||
CategoryRole = Qt.ItemDataRole.UserRole + 1
|
||||
LabelRole = Qt.ItemDataRole.UserRole + 2
|
||||
ValueRole = Qt.ItemDataRole.UserRole + 3
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent = parent)
|
||||
self.addRoleName(self.CategoryRole, "category")
|
||||
self.addRoleName(self.LabelRole, "label")
|
||||
self.addRoleName(self.ValueRole, "value")
|
||||
|
||||
self._i18n_catalog = None
|
||||
|
||||
def addSettingsFromStack(self, stack, category, settings):
|
||||
for setting, value in settings.items():
|
||||
unit = stack.getProperty(setting, "unit")
|
||||
|
||||
setting_type = stack.getProperty(setting, "type")
|
||||
if setting_type is not None:
|
||||
# This is not very good looking, but will do for now
|
||||
value = SettingDefinition.settingValueToString(setting_type, value) + " " + unit
|
||||
else:
|
||||
value = str(value)
|
||||
|
||||
self.appendItem({
|
||||
"category": category,
|
||||
"label": stack.getProperty(setting, "label"),
|
||||
"value": value
|
||||
})
|
|
@ -16,6 +16,7 @@ from UM.Mesh.MeshReader import MeshReader
|
|||
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
|
||||
from UM.Scene.GroupDecorator import GroupDecorator
|
||||
from UM.Scene.SceneNode import SceneNode # For typing.
|
||||
from UM.Scene.SceneNodeSettings import SceneNodeSettings
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
|
||||
|
@ -180,6 +181,9 @@ class ThreeMFReader(MeshReader):
|
|||
if key == "print_order":
|
||||
um_node.printOrder = int(setting_value)
|
||||
continue
|
||||
if key =="drop_to_buildplate":
|
||||
um_node.setSetting(SceneNodeSettings.AutoDropDown, eval(setting_value))
|
||||
continue
|
||||
if key in known_setting_keys:
|
||||
setting_container.setProperty(key, "value", setting_value)
|
||||
else:
|
||||
|
|
|
@ -5,6 +5,7 @@ from configparser import ConfigParser
|
|||
import zipfile
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
from typing import cast, Dict, List, Optional, Tuple, Any, Set
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
@ -57,6 +58,7 @@ _ignored_machine_network_metadata: Set[str] = {
|
|||
"is_abstract_machine"
|
||||
}
|
||||
|
||||
USER_SETTINGS_PATH = "Cura/user-settings.json"
|
||||
|
||||
class ContainerInfo:
|
||||
def __init__(self, file_name: Optional[str], serialized: Optional[str], parser: Optional[ConfigParser]) -> None:
|
||||
|
@ -141,10 +143,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
self._old_new_materials: Dict[str, str] = {}
|
||||
self._machine_info = None
|
||||
|
||||
self._load_profile = False
|
||||
self._user_settings: Dict[str, Dict[str, Any]] = {}
|
||||
|
||||
def _clearState(self):
|
||||
self._id_mapping = {}
|
||||
self._old_new_materials = {}
|
||||
self._machine_info = None
|
||||
self._load_profile = False
|
||||
self._user_settings = {}
|
||||
|
||||
def getNewId(self, old_id: str):
|
||||
"""Get a unique name based on the old_id. This is different from directly calling the registry in that it caches results.
|
||||
|
@ -228,11 +235,14 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
self._resolve_strategies = {k: None for k in resolve_strategy_keys}
|
||||
containers_found_dict = {k: False for k in resolve_strategy_keys}
|
||||
|
||||
# Check whether the file is a UCP, which changes some import options
|
||||
is_ucp = USER_SETTINGS_PATH in cura_file_names
|
||||
|
||||
#
|
||||
# Read definition containers
|
||||
#
|
||||
machine_definition_id = None
|
||||
updatable_machines = []
|
||||
updatable_machines = None if is_ucp else []
|
||||
machine_definition_container_count = 0
|
||||
extruder_definition_container_count = 0
|
||||
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
|
||||
|
@ -250,7 +260,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
if definition_container_type == "machine":
|
||||
machine_definition_id = container_id
|
||||
machine_definition_containers = self._container_registry.findDefinitionContainers(id = machine_definition_id)
|
||||
if machine_definition_containers:
|
||||
if machine_definition_containers and updatable_machines is not None:
|
||||
updatable_machines = [machine for machine in self._container_registry.findContainerStacks(type = "machine") if machine.definition == machine_definition_containers[0]]
|
||||
machine_type = definition_container["name"]
|
||||
variant_type_name = definition_container.get("variants_name", variant_type_name)
|
||||
|
@ -597,6 +607,37 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
package_metadata = self._parse_packages_metadata(archive)
|
||||
missing_package_metadata = self._filter_missing_package_metadata(package_metadata)
|
||||
|
||||
# Load the user specifically exported settings
|
||||
self._dialog.exportedSettingModel.clear()
|
||||
if is_ucp:
|
||||
try:
|
||||
self._user_settings = json.loads(archive.open("Cura/user-settings.json").read().decode("utf-8"))
|
||||
any_extruder_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
||||
actual_global_stack = CuraApplication.getInstance().getGlobalContainerStack()
|
||||
|
||||
for stack_name, settings in self._user_settings.items():
|
||||
if stack_name == 'global':
|
||||
self._dialog.exportedSettingModel.addSettingsFromStack(actual_global_stack, i18n_catalog.i18nc("@label", "Global"), settings)
|
||||
else:
|
||||
extruder_match = re.fullmatch('extruder_([0-9]+)', stack_name)
|
||||
if extruder_match is not None:
|
||||
extruder_nr = int(extruder_match.group(1))
|
||||
self._dialog.exportedSettingModel.addSettingsFromStack(any_extruder_stack,
|
||||
i18n_catalog.i18nc("@label",
|
||||
"Extruder {0}", extruder_nr + 1),
|
||||
settings)
|
||||
except KeyError as e:
|
||||
# If there is no user settings file, it's not a UCP, so notify user of failure.
|
||||
Logger.log("w", "File %s is not a valid UCP.", file_name)
|
||||
message = Message(
|
||||
i18n_catalog.i18nc("@info:error Don't translate the XML tags <filename> or <message>!",
|
||||
"Project file <filename>{0}</filename> is corrupt: <message>{1}</message>.",
|
||||
file_name, str(e)),
|
||||
title=i18n_catalog.i18nc("@info:title", "Can't Open Project File"),
|
||||
message_type=Message.MessageType.ERROR)
|
||||
message.show()
|
||||
return WorkspaceReader.PreReadResult.failed
|
||||
|
||||
# Show the dialog, informing the user what is about to happen.
|
||||
self._dialog.setMachineConflict(machine_conflict)
|
||||
self._dialog.setIsPrinterGroup(is_printer_group)
|
||||
|
@ -617,8 +658,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
self._dialog.setVariantType(variant_type_name)
|
||||
self._dialog.setHasObjectsOnPlate(Application.getInstance().platformActivity)
|
||||
self._dialog.setMissingPackagesMetadata(missing_package_metadata)
|
||||
self._dialog.setHasVisibleSelectSameProfileChanged(is_ucp)
|
||||
self._dialog.setAllowCreatemachine(not is_ucp)
|
||||
self._dialog.show()
|
||||
|
||||
|
||||
# Choosing the initially selected printer in MachineSelector
|
||||
is_networked_machine = False
|
||||
is_abstract_machine = False
|
||||
|
@ -648,6 +692,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
self._dialog.setIsNetworkedMachine(is_networked_machine)
|
||||
self._dialog.setIsAbstractMachine(is_abstract_machine)
|
||||
self._dialog.setMachineName(machine_name)
|
||||
self._dialog.updateCompatibleMachine()
|
||||
self._dialog.setSelectSameProfileChecked(self._dialog.isCompatibleMachine)
|
||||
|
||||
# Block until the dialog is closed.
|
||||
self._dialog.waitForClose()
|
||||
|
@ -655,6 +701,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
if self._dialog.getResult() == {}:
|
||||
return WorkspaceReader.PreReadResult.cancelled
|
||||
|
||||
self._load_profile = not is_ucp or (self._dialog.selectSameProfileChecked and self._dialog.isCompatibleMachine)
|
||||
|
||||
self._resolve_strategies = self._dialog.getResult()
|
||||
#
|
||||
# There can be 3 resolve strategies coming from the dialog:
|
||||
|
@ -777,6 +825,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
for stack in extruder_stacks:
|
||||
stack.setNextStack(global_stack, connect_signals = False)
|
||||
|
||||
if self._load_profile:
|
||||
Logger.log("d", "Workspace loading is checking definitions...")
|
||||
# Get all the definition files & check if they exist. If not, add them.
|
||||
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
|
||||
|
@ -850,11 +899,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
|
||||
|
||||
if global_stack:
|
||||
if self._load_profile:
|
||||
# Handle quality changes if any
|
||||
self._processQualityChanges(global_stack)
|
||||
|
||||
# Prepare the machine
|
||||
self._applyChangesToMachine(global_stack, extruder_stack_dict)
|
||||
else:
|
||||
# Just clear the settings now, so that we can change the active machine without conflicts
|
||||
self._clearMachineSettings(global_stack, extruder_stack_dict)
|
||||
|
||||
Logger.log("d", "Workspace loading is notifying rest of the code of changes...")
|
||||
# Actually change the active machine.
|
||||
|
@ -866,6 +919,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
# To solve this, we schedule _updateActiveMachine() for later so it will have the latest data.
|
||||
self._updateActiveMachine(global_stack)
|
||||
|
||||
if not self._load_profile:
|
||||
# Now we have switched, apply the user settings
|
||||
self._applyUserSettings(global_stack, extruder_stack_dict, self._user_settings)
|
||||
|
||||
# Load all the nodes / mesh data of the workspace
|
||||
nodes = self._3mf_mesh_reader.read(file_name)
|
||||
if nodes is None:
|
||||
|
@ -1177,21 +1234,44 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
material_node = machine_node.variants[extruder_stack.variant.getName()].materials[root_material_id]
|
||||
extruder_stack.material = material_node.container
|
||||
|
||||
def _applyChangesToMachine(self, global_stack, extruder_stack_dict):
|
||||
# Clear all first
|
||||
def _clearMachineSettings(self, global_stack, extruder_stack_dict):
|
||||
self._clearStack(global_stack)
|
||||
for extruder_stack in extruder_stack_dict.values():
|
||||
self._clearStack(extruder_stack)
|
||||
|
||||
self._quality_changes_to_apply = None
|
||||
self._quality_type_to_apply = None
|
||||
self._intent_category_to_apply = None
|
||||
self._user_settings_to_apply = None
|
||||
|
||||
def _applyUserSettings(self, global_stack, extruder_stack_dict, user_settings):
|
||||
for stack_name, settings in user_settings.items():
|
||||
if stack_name == 'global':
|
||||
ThreeMFWorkspaceReader._applyUserSettingsOnStack(global_stack, settings)
|
||||
else:
|
||||
extruder_match = re.fullmatch('extruder_([0-9]+)', stack_name)
|
||||
if extruder_match is not None:
|
||||
extruder_nr = extruder_match.group(1)
|
||||
if extruder_nr in extruder_stack_dict:
|
||||
ThreeMFWorkspaceReader._applyUserSettingsOnStack(extruder_stack_dict[extruder_nr], settings)
|
||||
|
||||
@staticmethod
|
||||
def _applyUserSettingsOnStack(stack, user_settings):
|
||||
user_settings_container = stack.userChanges
|
||||
|
||||
for setting_to_import, setting_value in user_settings.items():
|
||||
user_settings_container.setProperty(setting_to_import, 'value', setting_value)
|
||||
|
||||
def _applyChangesToMachine(self, global_stack, extruder_stack_dict):
|
||||
# Clear all first
|
||||
self._clearMachineSettings(global_stack, extruder_stack_dict)
|
||||
|
||||
self._applyDefinitionChanges(global_stack, extruder_stack_dict)
|
||||
self._applyUserChanges(global_stack, extruder_stack_dict)
|
||||
self._applyVariants(global_stack, extruder_stack_dict)
|
||||
self._applyMaterials(global_stack, extruder_stack_dict)
|
||||
|
||||
# prepare the quality to select
|
||||
self._quality_changes_to_apply = None
|
||||
self._quality_type_to_apply = None
|
||||
self._intent_category_to_apply = None
|
||||
if self._machine_info.quality_changes_info is not None:
|
||||
self._quality_changes_to_apply = self._machine_info.quality_changes_info.name
|
||||
else:
|
||||
|
|
|
@ -22,6 +22,8 @@ import time
|
|||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
from .SpecificSettingsModel import SpecificSettingsModel
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
|
@ -71,6 +73,11 @@ class WorkspaceDialog(QObject):
|
|||
self._install_missing_package_dialog: Optional[QObject] = None
|
||||
self._is_abstract_machine = False
|
||||
self._is_networked_machine = False
|
||||
self._is_compatible_machine = False
|
||||
self._has_visible_select_same_profile = False
|
||||
self._select_same_profile_checked = True
|
||||
self._allow_create_machine = True
|
||||
self._exported_settings_model = SpecificSettingsModel()
|
||||
|
||||
machineConflictChanged = pyqtSignal()
|
||||
qualityChangesConflictChanged = pyqtSignal()
|
||||
|
@ -94,6 +101,9 @@ class WorkspaceDialog(QObject):
|
|||
extrudersChanged = pyqtSignal()
|
||||
isPrinterGroupChanged = pyqtSignal()
|
||||
missingPackagesChanged = pyqtSignal()
|
||||
isCompatibleMachineChanged = pyqtSignal()
|
||||
hasVisibleSelectSameProfileChanged = pyqtSignal()
|
||||
selectSameProfileCheckedChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(bool, notify = isPrinterGroupChanged)
|
||||
def isPrinterGroup(self) -> bool:
|
||||
|
@ -292,6 +302,50 @@ class WorkspaceDialog(QObject):
|
|||
@pyqtSlot(str)
|
||||
def setMachineToOverride(self, machine_name: str) -> None:
|
||||
self._override_machine = machine_name
|
||||
self.updateCompatibleMachine()
|
||||
|
||||
def updateCompatibleMachine(self):
|
||||
registry = ContainerRegistry.getInstance()
|
||||
containers_expected = registry.findDefinitionContainers(name=self._machine_type)
|
||||
containers_selected = registry.findContainerStacks(id=self._override_machine)
|
||||
if len(containers_expected) == 1 and len(containers_selected) == 1:
|
||||
new_compatible_machine = (containers_expected[0] == containers_selected[0].definition)
|
||||
if new_compatible_machine != self._is_compatible_machine:
|
||||
self._is_compatible_machine = new_compatible_machine
|
||||
self.isCompatibleMachineChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = isCompatibleMachineChanged)
|
||||
def isCompatibleMachine(self) -> bool:
|
||||
return self._is_compatible_machine
|
||||
|
||||
def setHasVisibleSelectSameProfileChanged(self, has_visible_select_same_profile):
|
||||
if has_visible_select_same_profile != self._has_visible_select_same_profile:
|
||||
self._has_visible_select_same_profile = has_visible_select_same_profile
|
||||
self.hasVisibleSelectSameProfileChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = hasVisibleSelectSameProfileChanged)
|
||||
def hasVisibleSelectSameProfile(self):
|
||||
return self._has_visible_select_same_profile
|
||||
|
||||
def setSelectSameProfileChecked(self, select_same_profile_checked):
|
||||
if select_same_profile_checked != self._select_same_profile_checked:
|
||||
self._select_same_profile_checked = select_same_profile_checked
|
||||
self.selectSameProfileCheckedChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = selectSameProfileCheckedChanged, fset = setSelectSameProfileChecked)
|
||||
def selectSameProfileChecked(self):
|
||||
return self._select_same_profile_checked
|
||||
|
||||
def setAllowCreatemachine(self, allow_create_machine):
|
||||
self._allow_create_machine = allow_create_machine
|
||||
|
||||
@pyqtProperty(bool, constant = True)
|
||||
def allowCreateMachine(self):
|
||||
return self._allow_create_machine
|
||||
|
||||
@pyqtProperty(QObject, constant = True)
|
||||
def exportedSettingModel(self):
|
||||
return self._exported_settings_model
|
||||
|
||||
@pyqtSlot()
|
||||
def closeBackend(self) -> None:
|
||||
|
@ -299,11 +353,6 @@ class WorkspaceDialog(QObject):
|
|||
|
||||
Application.getInstance().getBackend().close()
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def setDropToBuildPlateForModel(self, drop_to_buildplate: bool) -> None:
|
||||
CuraApplication.getInstance().getWorkplaceDropToBuildplate(drop_to_buildplate)
|
||||
|
||||
|
||||
def setMaterialConflict(self, material_conflict: bool) -> None:
|
||||
if self._has_material_conflict != material_conflict:
|
||||
self._has_material_conflict = material_conflict
|
||||
|
|
|
@ -6,7 +6,7 @@ import QtQuick.Controls 2.3
|
|||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.5 as UM
|
||||
import UM 1.6 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
UM.Dialog
|
||||
|
@ -120,13 +120,17 @@ UM.Dialog
|
|||
|
||||
minDropDownWidth: machineSelector.width
|
||||
|
||||
buttons: [
|
||||
Component
|
||||
{
|
||||
id: componentNewPrinter
|
||||
|
||||
Cura.SecondaryButton
|
||||
{
|
||||
id: createNewPrinter
|
||||
text: catalog.i18nc("@button", "Create new")
|
||||
fixedWidthMode: true
|
||||
width: parent.width - leftPadding * 1.5
|
||||
visible: manager.allowCreateMachine
|
||||
onClicked:
|
||||
{
|
||||
toggleContent()
|
||||
|
@ -136,7 +140,9 @@ UM.Dialog
|
|||
manager.setIsNetworkedMachine(false)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
buttons: manager.allowCreateMachine ? [componentNewPrinter.createObject()] : []
|
||||
|
||||
onSelectPrinter: function(machine)
|
||||
{
|
||||
|
@ -165,26 +171,71 @@ UM.Dialog
|
|||
{
|
||||
leftLabelText: catalog.i18nc("@action:label", "Name")
|
||||
rightLabelText: manager.qualityName
|
||||
visible: manager.isCompatibleMachine
|
||||
}
|
||||
|
||||
WorkspaceRow
|
||||
{
|
||||
leftLabelText: catalog.i18nc("@action:label", "Intent")
|
||||
rightLabelText: manager.intentName
|
||||
visible: manager.isCompatibleMachine
|
||||
}
|
||||
|
||||
WorkspaceRow
|
||||
{
|
||||
leftLabelText: catalog.i18nc("@action:label", "Not in profile")
|
||||
rightLabelText: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.numUserSettings).arg(manager.numUserSettings)
|
||||
visible: manager.numUserSettings != 0
|
||||
visible: manager.numUserSettings != 0 && manager.selectSameProfileChecked && manager.isCompatibleMachine
|
||||
}
|
||||
|
||||
WorkspaceRow
|
||||
{
|
||||
leftLabelText: catalog.i18nc("@action:label", "Derivative from")
|
||||
rightLabelText: catalog.i18ncp("@action:label", "%1, %2 override", "%1, %2 overrides", manager.numSettingsOverridenByQualityChanges).arg(manager.qualityType).arg(manager.numSettingsOverridenByQualityChanges)
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0 && manager.selectSameProfileChecked && manager.isCompatibleMachine
|
||||
}
|
||||
|
||||
WorkspaceRow
|
||||
{
|
||||
leftLabelText: catalog.i18nc("@action:label", "Specific settings")
|
||||
rightLabelText: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.exportedSettingModel.rowCount()).arg(manager.exportedSettingModel.rowCount())
|
||||
buttonText: tableViewSpecificSettings.shouldBeVisible ? catalog.i18nc("@action:button", "Hide settings") : catalog.i18nc("@action:button", "Show settings")
|
||||
visible: !manager.selectSameProfileChecked || !manager.isCompatibleMachine
|
||||
onButtonClicked: tableViewSpecificSettings.shouldBeVisible = !tableViewSpecificSettings.shouldBeVisible
|
||||
}
|
||||
|
||||
Cura.TableView
|
||||
{
|
||||
id: tableViewSpecificSettings
|
||||
width: parent.width - parent.leftPadding - UM.Theme.getSize("default_margin").width
|
||||
height: UM.Theme.getSize("card").height
|
||||
visible: shouldBeVisible && (!manager.selectSameProfileChecked || !manager.isCompatibleMachine)
|
||||
property bool shouldBeVisible: false
|
||||
|
||||
columnHeaders:
|
||||
[
|
||||
catalog.i18nc("@title:column", "Applies on"),
|
||||
catalog.i18nc("@title:column", "Setting"),
|
||||
catalog.i18nc("@title:column", "Value")
|
||||
]
|
||||
|
||||
model: UM.TableModel
|
||||
{
|
||||
id: tableModel
|
||||
headers: ["category", "label", "value"]
|
||||
rows: manager.exportedSettingModel.items
|
||||
}
|
||||
}
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
text: catalog.i18nc("@action:checkbox", "Select the same profile")
|
||||
onEnabledChanged: manager.selectSameProfileChecked = enabled
|
||||
tooltip: enabled ? "" : catalog.i18nc("@tooltip", "You can use the same profile only if you have the same printer as the project was published with")
|
||||
visible: manager.hasVisibleSelectSameProfile && manager.isCompatibleMachine
|
||||
|
||||
checked: manager.selectSameProfileChecked
|
||||
onCheckedChanged: manager.selectSameProfileChecked = checked
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,25 +351,6 @@ UM.Dialog
|
|||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: dropToBuildPlate
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
UM.CheckBox
|
||||
{
|
||||
id: checkDropModels
|
||||
text: catalog.i18nc("@text:window", "Drop models to buildplate")
|
||||
checked: UM.Preferences.getValue("physics/automatic_drop_down")
|
||||
onCheckedChanged: manager.setDropToBuildPlateForModel(checked)
|
||||
}
|
||||
function reloadValue()
|
||||
{
|
||||
checkDropModels.checked = UM.Preferences.getValue("physics/automatic_drop_down")
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
id: clearBuildPlateWarning
|
||||
|
@ -441,7 +473,6 @@ UM.Dialog
|
|||
materialSection.reloadValues()
|
||||
profileSection.reloadValues()
|
||||
printerSection.reloadValues()
|
||||
dropToBuildPlate.reloadValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,26 +9,38 @@ import QtQuick.Window 2.2
|
|||
import UM 1.5 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
Row
|
||||
RowLayout
|
||||
{
|
||||
id: root
|
||||
|
||||
property alias leftLabelText: leftLabel.text
|
||||
property alias rightLabelText: rightLabel.text
|
||||
property alias buttonText: button.text
|
||||
signal buttonClicked
|
||||
|
||||
width: parent.width
|
||||
height: visible ? childrenRect.height : 0
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: leftLabel
|
||||
text: catalog.i18nc("@action:label", "Type")
|
||||
width: Math.round(parent.width / 4)
|
||||
Layout.preferredWidth: Math.round(parent.width / 4)
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: rightLabel
|
||||
text: manager.machineType
|
||||
width: Math.round(parent.width / 3)
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
id: button
|
||||
visible: !text.isEmpty
|
||||
Layout.maximumHeight: leftLabel.implicitHeight
|
||||
Layout.fillWidth: true
|
||||
onClicked: root.buttonClicked()
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import QtQuick 2.10
|
|||
import QtQuick.Controls 2.3
|
||||
|
||||
|
||||
import UM 1.5 as UM
|
||||
import UM 1.8 as UM
|
||||
|
||||
|
||||
Item
|
||||
|
@ -80,34 +80,13 @@ Item
|
|||
sourceComponent: combobox
|
||||
}
|
||||
|
||||
MouseArea
|
||||
UM.HelpIcon
|
||||
{
|
||||
id: helpIconMouseArea
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: comboboxLabel.verticalCenter
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
hoverEnabled: true
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
width: UM.Theme.getSize("section_icon").width
|
||||
height: width
|
||||
|
||||
visible: comboboxTooltipText != ""
|
||||
source: UM.Theme.getIcon("Help")
|
||||
color: UM.Theme.getColor("text")
|
||||
|
||||
UM.ToolTip
|
||||
{
|
||||
text: comboboxTooltipText
|
||||
visible: helpIconMouseArea.containsMouse
|
||||
targetPoint: Qt.point(parent.x + Math.round(parent.width / 2), parent.y)
|
||||
x: 0
|
||||
y: parent.y + parent.height + UM.Theme.getSize("default_margin").height
|
||||
width: UM.Theme.getSize("tooltip").width
|
||||
}
|
||||
}
|
||||
visible: comboboxTooltipText != ""
|
||||
}
|
||||
}
|
||||
|
||||
|
|
38
plugins/3MFWriter/SettingExport.py
Normal file
38
plugins/3MFWriter/SettingExport.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Copyright (c) 2024 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
|
||||
|
||||
class SettingExport(QObject):
|
||||
|
||||
def __init__(self, id, name, value, selectable):
|
||||
super().__init__()
|
||||
self.id = id
|
||||
self._name = name
|
||||
self._value = value
|
||||
self._selected = selectable
|
||||
self._selectable = selectable
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
selectedChanged = pyqtSignal(bool)
|
||||
|
||||
def setSelected(self, selected):
|
||||
if selected != self._selected:
|
||||
self._selected = selected
|
||||
self.selectedChanged.emit(self._selected)
|
||||
|
||||
@pyqtProperty(bool, fset = setSelected, notify = selectedChanged)
|
||||
def selected(self):
|
||||
return self._selected
|
||||
|
||||
@pyqtProperty(bool, constant=True)
|
||||
def selectable(self):
|
||||
return self._selectable
|
38
plugins/3MFWriter/SettingSelection.qml
Normal file
38
plugins/3MFWriter/SettingSelection.qml
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2024 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.8 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
RowLayout
|
||||
{
|
||||
id: settingSelection
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
text: modelData.name
|
||||
Layout.preferredWidth: UM.Theme.getSize("setting").width
|
||||
checked: modelData.selected
|
||||
onClicked: modelData.selected = checked
|
||||
enabled: modelData.selectable
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: modelData.value
|
||||
}
|
||||
|
||||
UM.HelpIcon
|
||||
{
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
text: catalog.i18nc("@tooltip",
|
||||
"This setting can't be exported because it depends on the used printer capacities")
|
||||
visible: !modelData.selectable
|
||||
}
|
||||
}
|
49
plugins/3MFWriter/SettingsExportGroup.py
Normal file
49
plugins/3MFWriter/SettingsExportGroup.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Copyright (c) 2024 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from enum import IntEnum
|
||||
|
||||
from PyQt6.QtCore import QObject, pyqtProperty, pyqtEnum
|
||||
|
||||
|
||||
class SettingsExportGroup(QObject):
|
||||
|
||||
@pyqtEnum
|
||||
class Category(IntEnum):
|
||||
Global = 0
|
||||
Extruder = 1
|
||||
Model = 2
|
||||
|
||||
def __init__(self, stack, name, category, settings, category_details = '', extruder_index = 0, extruder_color = ''):
|
||||
super().__init__()
|
||||
self.stack = stack
|
||||
self._name = name
|
||||
self._settings = settings
|
||||
self._category = category
|
||||
self._category_details = category_details
|
||||
self._extruder_index = extruder_index
|
||||
self._extruder_color = extruder_color
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@pyqtProperty(list, constant=True)
|
||||
def settings(self):
|
||||
return self._settings
|
||||
|
||||
@pyqtProperty(int, constant=True)
|
||||
def category(self):
|
||||
return self._category
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def category_details(self):
|
||||
return self._category_details
|
||||
|
||||
@pyqtProperty(int, constant=True)
|
||||
def extruder_index(self):
|
||||
return self._extruder_index
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def extruder_color(self):
|
||||
return self._extruder_color
|
130
plugins/3MFWriter/SettingsExportModel.py
Normal file
130
plugins/3MFWriter/SettingsExportModel.py
Normal file
|
@ -0,0 +1,130 @@
|
|||
# Copyright (c) 2024 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from dataclasses import asdict
|
||||
from typing import Optional, cast, List, Dict, Pattern, Set
|
||||
|
||||
from PyQt6.QtCore import QObject, pyqtProperty
|
||||
|
||||
from UM.Settings.SettingDefinition import SettingDefinition
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
||||
from .SettingsExportGroup import SettingsExportGroup
|
||||
from .SettingExport import SettingExport
|
||||
|
||||
|
||||
class SettingsExportModel(QObject):
|
||||
|
||||
EXPORTABLE_SETTINGS = {'infill_sparse_density',
|
||||
'adhesion_type',
|
||||
'support_enable',
|
||||
'infill_pattern',
|
||||
'support_type',
|
||||
'support_structure',
|
||||
'support_angle',
|
||||
'support_infill_rate',
|
||||
'ironing_enabled',
|
||||
'fill_outline_gaps',
|
||||
'coasting_enable',
|
||||
'skin_monotonic',
|
||||
'z_seam_position',
|
||||
'infill_before_walls',
|
||||
'ironing_only_highest_layer',
|
||||
'xy_offset',
|
||||
'adaptive_layer_height_enabled',
|
||||
'brim_gap',
|
||||
'support_offset',
|
||||
'brim_outside_only',
|
||||
'magic_spiralize',
|
||||
'slicing_tolerance',
|
||||
'outer_inset_first',
|
||||
'magic_fuzzy_skin_outside_only',
|
||||
'conical_overhang_enabled',
|
||||
'min_infill_area',
|
||||
'small_hole_max_size',
|
||||
'magic_mesh_surface_mode',
|
||||
'carve_multiple_volumes',
|
||||
'meshfix_union_all_remove_holes',
|
||||
'support_tree_rest_preference',
|
||||
'small_feature_max_length',
|
||||
'draft_shield_enabled',
|
||||
'brim_smart_ordering',
|
||||
'ooze_shield_enabled',
|
||||
'bottom_skin_preshrink',
|
||||
'skin_edge_support_thickness',
|
||||
'alternate_carve_order',
|
||||
'top_skin_preshrink',
|
||||
'interlocking_enable'}
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
self._settings_groups = []
|
||||
|
||||
application = CuraApplication.getInstance()
|
||||
|
||||
# Display global settings
|
||||
global_stack = application.getGlobalContainerStack()
|
||||
self._settings_groups.append(SettingsExportGroup(global_stack,
|
||||
"Global settings",
|
||||
SettingsExportGroup.Category.Global,
|
||||
self._exportSettings(global_stack)))
|
||||
|
||||
# Display per-extruder settings
|
||||
extruders_stacks = ExtruderManager.getInstance().getUsedExtruderStacks()
|
||||
for extruder_stack in extruders_stacks:
|
||||
color = ""
|
||||
if extruder_stack.material:
|
||||
color = extruder_stack.material.getMetaDataEntry("color_code")
|
||||
|
||||
self._settings_groups.append(SettingsExportGroup(extruder_stack,
|
||||
"Extruder settings",
|
||||
SettingsExportGroup.Category.Extruder,
|
||||
self._exportSettings(extruder_stack),
|
||||
extruder_index=extruder_stack.position,
|
||||
extruder_color=color))
|
||||
|
||||
# Display per-model settings
|
||||
scene_root = application.getController().getScene().getRoot()
|
||||
for scene_node in scene_root.getChildren():
|
||||
per_model_stack = scene_node.callDecoration("getStack")
|
||||
if per_model_stack is not None:
|
||||
self._settings_groups.append(SettingsExportGroup(per_model_stack,
|
||||
"Model settings",
|
||||
SettingsExportGroup.Category.Model,
|
||||
self._exportSettings(per_model_stack),
|
||||
scene_node.getName()))
|
||||
|
||||
@pyqtProperty(list, constant=True)
|
||||
def settingsGroups(self) -> List[SettingsExportGroup]:
|
||||
return self._settings_groups
|
||||
|
||||
@staticmethod
|
||||
def _exportSettings(settings_stack):
|
||||
user_settings_container = settings_stack.userChanges
|
||||
user_keys = user_settings_container.getAllKeys()
|
||||
|
||||
settings_export = []
|
||||
|
||||
for setting_to_export in user_keys:
|
||||
label = settings_stack.getProperty(setting_to_export, "label")
|
||||
value = settings_stack.getProperty(setting_to_export, "value")
|
||||
unit = settings_stack.getProperty(setting_to_export, "unit")
|
||||
|
||||
setting_type = settings_stack.getProperty(setting_to_export, "type")
|
||||
if setting_type is not None:
|
||||
# This is not very good looking, but will do for now
|
||||
value = f"{str(SettingDefinition.settingValueToString(setting_type, value))} {unit}"
|
||||
else:
|
||||
value = str(value)
|
||||
|
||||
settings_export.append(SettingExport(setting_to_export,
|
||||
label,
|
||||
value,
|
||||
setting_to_export in SettingsExportModel.EXPORTABLE_SETTINGS))
|
||||
|
||||
return settings_export
|
87
plugins/3MFWriter/SettingsSelectionGroup.qml
Normal file
87
plugins/3MFWriter/SettingsSelectionGroup.qml
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2024 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.1 as Cura
|
||||
import ThreeMFWriter 1.0 as ThreeMFWriter
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: settingsGroup
|
||||
spacing: UM.Theme.getSize("narrow_margin").width
|
||||
|
||||
RowLayout
|
||||
{
|
||||
id: settingsGroupTitleRow
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Item
|
||||
{
|
||||
id: icon
|
||||
height: UM.Theme.getSize("medium_button_icon").height
|
||||
width: height
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
id: settingsMainImage
|
||||
anchors.fill: parent
|
||||
source:
|
||||
{
|
||||
switch(modelData.category)
|
||||
{
|
||||
case ThreeMFWriter.SettingsExportGroup.Global:
|
||||
return UM.Theme.getIcon("Sliders")
|
||||
case ThreeMFWriter.SettingsExportGroup.Model:
|
||||
return UM.Theme.getIcon("View3D")
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
color: UM.Theme.getColor("text")
|
||||
}
|
||||
|
||||
Cura.ExtruderIcon
|
||||
{
|
||||
id: settingsExtruderIcon
|
||||
anchors.fill: parent
|
||||
visible: modelData.category === ThreeMFWriter.SettingsExportGroup.Extruder
|
||||
text: (modelData.extruder_index + 1).toString()
|
||||
font: UM.Theme.getFont("tiny_emphasis")
|
||||
materialColor: modelData.extruder_color
|
||||
}
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: settingsTitle
|
||||
text: modelData.name + (modelData.category_details ? ' (%1)'.arg(modelData.category_details) : '')
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
id: settingsExportList
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
spacing: 0
|
||||
model: modelData.settings
|
||||
visible: modelData.settings.length > 0
|
||||
|
||||
delegate: SettingSelection { }
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
text: catalog.i18nc("@label", "No specific value has been set")
|
||||
visible: modelData.settings.length === 0
|
||||
}
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
# Copyright (c) 2020 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
import configparser
|
||||
from io import StringIO
|
||||
from threading import Lock
|
||||
import zipfile
|
||||
from typing import Dict, Any
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Logger import Logger
|
||||
|
@ -13,15 +17,23 @@ from UM.Workspace.WorkspaceWriter import WorkspaceWriter
|
|||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
from cura.Utils.Threading import call_on_qt_thread
|
||||
from .ThreeMFWriter import ThreeMFWriter
|
||||
from .SettingsExportModel import SettingsExportModel
|
||||
from .SettingsExportGroup import SettingsExportGroup
|
||||
|
||||
USER_SETTINGS_PATH = "Cura/user-settings.json"
|
||||
|
||||
|
||||
class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._ucp_model: Optional[SettingsExportModel] = None
|
||||
|
||||
@call_on_qt_thread
|
||||
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
|
||||
def setExportModel(self, model: SettingsExportModel) -> None:
|
||||
if self._ucp_model != model:
|
||||
self._ucp_model = model
|
||||
|
||||
def _write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
|
||||
application = Application.getInstance()
|
||||
machine_manager = application.getMachineManager()
|
||||
|
||||
|
@ -34,13 +46,14 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
|
||||
global_stack = machine_manager.activeMachine
|
||||
if global_stack is None:
|
||||
self.setInformation(catalog.i18nc("@error", "There is no workspace yet to write. Please add a printer first."))
|
||||
self.setInformation(
|
||||
catalog.i18nc("@error", "There is no workspace yet to write. Please add a printer first."))
|
||||
Logger.error("Tried to write a 3MF workspace before there was a global stack.")
|
||||
return False
|
||||
|
||||
# Indicate that the 3mf mesh writer should not close the archive just yet (we still need to add stuff to it).
|
||||
mesh_writer.setStoreArchive(True)
|
||||
if not mesh_writer.write(stream, nodes, mode):
|
||||
if not mesh_writer.write(stream, nodes, mode, self._ucp_model):
|
||||
self.setInformation(mesh_writer.getInformation())
|
||||
return False
|
||||
|
||||
|
@ -48,7 +61,6 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
if archive is None: # This happens if there was no mesh data to write.
|
||||
archive = zipfile.ZipFile(stream, "w", compression=zipfile.ZIP_DEFLATED)
|
||||
|
||||
|
||||
try:
|
||||
# Add global container stack data to the archive.
|
||||
self._writeContainerToArchive(global_stack, archive)
|
||||
|
@ -62,6 +74,11 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
self._writeContainerToArchive(extruder_stack, archive)
|
||||
for container in extruder_stack.getContainers():
|
||||
self._writeContainerToArchive(container, archive)
|
||||
|
||||
# Write user settings data
|
||||
if self._ucp_model is not None:
|
||||
user_settings_data = self._getUserSettings(self._ucp_model)
|
||||
ThreeMFWriter._storeMetadataJson(user_settings_data, archive, USER_SETTINGS_PATH)
|
||||
except PermissionError:
|
||||
self.setInformation(catalog.i18nc("@error:zip", "No permission to write the workspace here."))
|
||||
Logger.error("No permission to write workspace to this stream.")
|
||||
|
@ -70,7 +87,8 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
# Write preferences to archive
|
||||
original_preferences = Application.getInstance().getPreferences() # Copy only the preferences that we use to the workspace.
|
||||
temp_preferences = Preferences()
|
||||
for preference in {"general/visible_settings", "cura/active_mode", "cura/categories_expanded", "metadata/setting_version"}:
|
||||
for preference in {"general/visible_settings", "cura/active_mode", "cura/categories_expanded",
|
||||
"metadata/setting_version"}:
|
||||
temp_preferences.addPreference(preference, None)
|
||||
temp_preferences.setValue(preference, original_preferences.getValue(preference))
|
||||
preferences_string = StringIO()
|
||||
|
@ -104,8 +122,14 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
Logger.error("EnvironmentError when writing workspace to this stream: {err}".format(err=str(e)))
|
||||
return False
|
||||
mesh_writer.setStoreArchive(False)
|
||||
|
||||
return True
|
||||
|
||||
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
|
||||
success = self._write(stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode)
|
||||
self._ucp_model = None
|
||||
return success
|
||||
|
||||
@staticmethod
|
||||
def _writePluginMetadataToArchive(archive: zipfile.ZipFile) -> None:
|
||||
file_name_template = "%s/plugin_metadata.json"
|
||||
|
@ -166,3 +190,26 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||
except (FileNotFoundError, EnvironmentError):
|
||||
Logger.error("File became inaccessible while writing to it: {archive_filename}".format(archive_filename = archive.fp.name))
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
def _getUserSettings(model: SettingsExportModel) -> Dict[str, Dict[str, Any]]:
|
||||
user_settings = {}
|
||||
|
||||
for group in model.settingsGroups:
|
||||
category = ''
|
||||
if group.category == SettingsExportGroup.Category.Global:
|
||||
category = 'global'
|
||||
elif group.category == SettingsExportGroup.Category.Extruder:
|
||||
category = f"extruder_{group.extruder_index}"
|
||||
|
||||
if len(category) > 0:
|
||||
settings_values = {}
|
||||
stack = group.stack
|
||||
|
||||
for setting in group.settings:
|
||||
if setting.selected:
|
||||
settings_values[setting.id] = stack.getProperty(setting.id, "value")
|
||||
|
||||
user_settings[category] = settings_values
|
||||
|
||||
return user_settings
|
|
@ -10,6 +10,9 @@ from UM.Math.Vector import Vector
|
|||
from UM.Logger import Logger
|
||||
from UM.Math.Matrix import Matrix
|
||||
from UM.Application import Application
|
||||
from UM.OutputDevice import OutputDeviceError
|
||||
from UM.Message import Message
|
||||
from UM.Resources import Resources
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
|
@ -20,10 +23,11 @@ from cura.Utils.Threading import call_on_qt_thread
|
|||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||
from cura.Snapshot import Snapshot
|
||||
|
||||
from PyQt6.QtCore import QBuffer
|
||||
from PyQt6.QtCore import Qt, QBuffer
|
||||
from PyQt6.QtGui import QImage, QPainter
|
||||
|
||||
import pySavitar as Savitar
|
||||
|
||||
from .UCPDialog import UCPDialog
|
||||
import numpy
|
||||
import datetime
|
||||
|
||||
|
@ -38,6 +42,9 @@ except ImportError:
|
|||
import zipfile
|
||||
import UM.Application
|
||||
|
||||
from .SettingsExportModel import SettingsExportModel
|
||||
from .SettingsExportGroup import SettingsExportGroup
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
@ -85,7 +92,9 @@ class ThreeMFWriter(MeshWriter):
|
|||
self._store_archive = store_archive
|
||||
|
||||
@staticmethod
|
||||
def _convertUMNodeToSavitarNode(um_node, transformation=Matrix()):
|
||||
def _convertUMNodeToSavitarNode(um_node,
|
||||
transformation = Matrix(),
|
||||
exported_settings: Optional[Dict[str, Set[str]]] = None):
|
||||
"""Convenience function that converts an Uranium SceneNode object to a SavitarSceneNode
|
||||
|
||||
:returns: Uranium Scene node.
|
||||
|
@ -127,6 +136,7 @@ class ThreeMFWriter(MeshWriter):
|
|||
if stack is not None:
|
||||
changed_setting_keys = stack.getTop().getAllKeys()
|
||||
|
||||
if exported_settings is None:
|
||||
# Ensure that we save the extruder used for this object in a multi-extrusion setup
|
||||
if stack.getProperty("machine_extruder_count", "value") > 1:
|
||||
changed_setting_keys.add("extruder_nr")
|
||||
|
@ -134,9 +144,18 @@ class ThreeMFWriter(MeshWriter):
|
|||
# Get values for all changed settings & save them.
|
||||
for key in changed_setting_keys:
|
||||
savitar_node.setSetting("cura:" + key, str(stack.getProperty(key, "value")))
|
||||
else:
|
||||
# We want to export only the specified settings
|
||||
if um_node.getName() in exported_settings:
|
||||
model_exported_settings = exported_settings[um_node.getName()]
|
||||
|
||||
# Get values for all exported settings & save them.
|
||||
for key in model_exported_settings:
|
||||
savitar_node.setSetting("cura:" + key, str(stack.getProperty(key, "value")))
|
||||
|
||||
if isinstance(um_node, CuraSceneNode):
|
||||
savitar_node.setSetting("cura:print_order", str(um_node.printOrder))
|
||||
savitar_node.setSetting("cura:drop_to_buildplate", str(um_node.isDropDownEnabled))
|
||||
|
||||
# Store the metadata.
|
||||
for key, value in um_node.metadata.items():
|
||||
|
@ -146,7 +165,8 @@ class ThreeMFWriter(MeshWriter):
|
|||
# only save the nodes on the active build plate
|
||||
if child_node.callDecoration("getBuildPlateNumber") != active_build_plate_nr:
|
||||
continue
|
||||
savitar_child_node = ThreeMFWriter._convertUMNodeToSavitarNode(child_node)
|
||||
savitar_child_node = ThreeMFWriter._convertUMNodeToSavitarNode(child_node,
|
||||
exported_settings = exported_settings)
|
||||
if savitar_child_node is not None:
|
||||
savitar_node.addChild(savitar_child_node)
|
||||
|
||||
|
@ -155,7 +175,24 @@ class ThreeMFWriter(MeshWriter):
|
|||
def getArchive(self):
|
||||
return self._archive
|
||||
|
||||
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode) -> bool:
|
||||
def _addLogoToThumbnail(self, primary_image, logo_name):
|
||||
# Load the icon png image
|
||||
icon_image = QImage(Resources.getPath(Resources.Images, logo_name))
|
||||
|
||||
# Resize icon_image to be 1/4 of primary_image size
|
||||
new_width = int(primary_image.width() / 4)
|
||||
new_height = int(primary_image.height() / 4)
|
||||
icon_image = icon_image.scaled(new_width, new_height, Qt.AspectRatioMode.KeepAspectRatio)
|
||||
# Create a QPainter to draw on the image
|
||||
painter = QPainter(primary_image)
|
||||
|
||||
# Draw the icon in the top-left corner (adjust coordinates as needed)
|
||||
icon_position = (10, 10)
|
||||
painter.drawImage(icon_position[0], icon_position[1], icon_image)
|
||||
|
||||
painter.end()
|
||||
|
||||
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode, export_settings_model = None) -> bool:
|
||||
self._archive = None # Reset archive
|
||||
archive = zipfile.ZipFile(stream, "w", compression = zipfile.ZIP_DEFLATED)
|
||||
try:
|
||||
|
@ -179,6 +216,10 @@ class ThreeMFWriter(MeshWriter):
|
|||
# Attempt to add a thumbnail
|
||||
snapshot = self._createSnapshot()
|
||||
if snapshot:
|
||||
if export_settings_model != None:
|
||||
self._addLogoToThumbnail(snapshot, "cura-share.png")
|
||||
elif export_settings_model == None and self._store_archive:
|
||||
self._addLogoToThumbnail(snapshot, "cura-icon.png")
|
||||
thumbnail_buffer = QBuffer()
|
||||
thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite)
|
||||
snapshot.save(thumbnail_buffer, "PNG")
|
||||
|
@ -233,14 +274,20 @@ class ThreeMFWriter(MeshWriter):
|
|||
transformation_matrix.preMultiply(translation_matrix)
|
||||
|
||||
root_node = UM.Application.Application.getInstance().getController().getScene().getRoot()
|
||||
exported_model_settings = ThreeMFWriter._extractModelExportedSettings(export_settings_model) if export_settings_model != None else None
|
||||
|
||||
for node in nodes:
|
||||
if node == root_node:
|
||||
for root_child in node.getChildren():
|
||||
savitar_node = ThreeMFWriter._convertUMNodeToSavitarNode(root_child, transformation_matrix)
|
||||
savitar_node = ThreeMFWriter._convertUMNodeToSavitarNode(root_child,
|
||||
transformation_matrix,
|
||||
exported_model_settings)
|
||||
if savitar_node:
|
||||
savitar_scene.addSceneNode(savitar_node)
|
||||
else:
|
||||
savitar_node = self._convertUMNodeToSavitarNode(node, transformation_matrix)
|
||||
savitar_node = self._convertUMNodeToSavitarNode(node,
|
||||
transformation_matrix,
|
||||
exported_model_settings)
|
||||
if savitar_node:
|
||||
savitar_scene.addSceneNode(savitar_node)
|
||||
|
||||
|
@ -396,3 +443,59 @@ class ThreeMFWriter(MeshWriter):
|
|||
parser = Savitar.ThreeMFParser()
|
||||
scene_string = parser.sceneToString(savitar_scene)
|
||||
return scene_string
|
||||
|
||||
@staticmethod
|
||||
def _extractModelExportedSettings(model: Optional[SettingsExportModel]) -> Dict[str, Set[str]]:
|
||||
extra_settings = {}
|
||||
|
||||
if model is not None:
|
||||
for group in model.settingsGroups:
|
||||
if group.category == SettingsExportGroup.Category.Model:
|
||||
exported_model_settings = set()
|
||||
|
||||
for exported_setting in group.settings:
|
||||
if exported_setting.selected:
|
||||
exported_model_settings.add(exported_setting.id)
|
||||
|
||||
extra_settings[group.category_details] = exported_model_settings
|
||||
|
||||
return extra_settings
|
||||
|
||||
def exportUcp(self):
|
||||
preferences = CuraApplication.getInstance().getPreferences()
|
||||
if preferences.getValue("cura/dialog_on_ucp_project_save"):
|
||||
self._config_dialog = UCPDialog()
|
||||
self._config_dialog.show()
|
||||
else:
|
||||
application = CuraApplication.getInstance()
|
||||
workspace_handler = application.getInstance().getWorkspaceFileHandler()
|
||||
|
||||
# Set the model to the workspace writer
|
||||
mesh_writer = workspace_handler.getWriter("3MFWriter")
|
||||
mesh_writer.setExportModel(SettingsExportModel())
|
||||
|
||||
# Open file dialog and write the file
|
||||
device = application.getOutputDeviceManager().getOutputDevice("local_file")
|
||||
nodes = [application.getController().getScene().getRoot()]
|
||||
|
||||
file_name = CuraApplication.getInstance().getPrintInformation().baseName
|
||||
|
||||
try:
|
||||
device.requestWrite(
|
||||
nodes,
|
||||
file_name,
|
||||
["application/vnd.ms-package.3dmanufacturing-3dmodel+xml"],
|
||||
workspace_handler,
|
||||
preferred_mimetype_list="application/vnd.ms-package.3dmanufacturing-3dmodel+xml"
|
||||
)
|
||||
except OutputDeviceError.UserCanceledError:
|
||||
self._onRejected()
|
||||
except Exception as e:
|
||||
message = Message(
|
||||
catalog.i18nc("@info:error", "Unable to write to file: {0}", file_name),
|
||||
title=catalog.i18nc("@info:title", "Error"),
|
||||
message_type=Message.MessageType.ERROR
|
||||
)
|
||||
message.show()
|
||||
Logger.logException("e", "Unable to write to file %s: %s", file_name, e)
|
||||
self._onRejected()
|
||||
|
|
114
plugins/3MFWriter/UCPDialog.py
Normal file
114
plugins/3MFWriter/UCPDialog.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
# Copyright (c) 2024 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal, QObject
|
||||
|
||||
import UM
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM.OutputDevice import OutputDeviceError
|
||||
from UM.Workspace.WorkspaceWriter import WorkspaceWriter
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
from .SettingsExportModel import SettingsExportModel
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
class UCPDialog(QObject):
|
||||
finished = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, parent = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
plugin_path = os.path.dirname(__file__)
|
||||
dialog_path = os.path.join(plugin_path, 'UCPDialog.qml')
|
||||
self._model = SettingsExportModel()
|
||||
self._view = CuraApplication.getInstance().createQmlComponent(
|
||||
dialog_path,
|
||||
{
|
||||
"manager": self,
|
||||
"settingsExportModel": self._model
|
||||
}
|
||||
)
|
||||
self._view.accepted.connect(self._onAccepted)
|
||||
self._view.rejected.connect(self._onRejected)
|
||||
self._finished = False
|
||||
self._accepted = False
|
||||
|
||||
def show(self) -> None:
|
||||
self._finished = False
|
||||
self._accepted = False
|
||||
self._view.show()
|
||||
|
||||
def getModel(self) -> SettingsExportModel:
|
||||
return self._model
|
||||
|
||||
@pyqtSlot()
|
||||
def notifyClosed(self):
|
||||
self._onFinished()
|
||||
|
||||
def save3mf(self):
|
||||
application = CuraApplication.getInstance()
|
||||
workspace_handler = application.getInstance().getWorkspaceFileHandler()
|
||||
|
||||
# Set the model to the workspace writer
|
||||
mesh_writer = workspace_handler.getWriter("3MFWriter")
|
||||
mesh_writer.setExportModel(self._model)
|
||||
|
||||
# Open file dialog and write the file
|
||||
device = application.getOutputDeviceManager().getOutputDevice("local_file")
|
||||
nodes = [application.getController().getScene().getRoot()]
|
||||
|
||||
device.writeError.connect(lambda: self._onRejected())
|
||||
device.writeSuccess.connect(lambda: self._onSuccess())
|
||||
device.writeFinished.connect(lambda: self._onFinished())
|
||||
|
||||
file_name = CuraApplication.getInstance().getPrintInformation().baseName
|
||||
|
||||
try:
|
||||
device.requestWrite(
|
||||
nodes,
|
||||
file_name,
|
||||
["application/vnd.ms-package.3dmanufacturing-3dmodel+xml"],
|
||||
workspace_handler,
|
||||
preferred_mimetype_list="application/vnd.ms-package.3dmanufacturing-3dmodel+xml"
|
||||
)
|
||||
except OutputDeviceError.UserCanceledError:
|
||||
self._onRejected()
|
||||
except Exception as e:
|
||||
message = Message(
|
||||
i18n_catalog.i18nc("@info:error", "Unable to write to file: {0}", file_name),
|
||||
title=i18n_catalog.i18nc("@info:title", "Error"),
|
||||
message_type=Message.MessageType.ERROR
|
||||
)
|
||||
message.show()
|
||||
Logger.logException("e", "Unable to write to file %s: %s", file_name, e)
|
||||
self._onRejected()
|
||||
|
||||
def _onAccepted(self):
|
||||
self.save3mf()
|
||||
|
||||
def _onRejected(self):
|
||||
self._onFinished()
|
||||
|
||||
def _onSuccess(self):
|
||||
self._accepted = True
|
||||
self._onFinished()
|
||||
|
||||
def _onFinished(self):
|
||||
# Make sure we don't send the finished signal twice, whatever happens
|
||||
if self._finished:
|
||||
return
|
||||
self._finished = True
|
||||
|
||||
# Reset the model to the workspace writer
|
||||
mesh_writer = CuraApplication.getInstance().getInstance().getWorkspaceFileHandler().getWriter("3MFWriter")
|
||||
mesh_writer.setExportModel(None)
|
||||
|
||||
self.finished.emit(self._accepted)
|
125
plugins/3MFWriter/UCPDialog.qml
Normal file
125
plugins/3MFWriter/UCPDialog.qml
Normal file
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) 2024 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
id: exportDialog
|
||||
title: catalog.i18nc("@title:window", "Export Universal Cura Project")
|
||||
|
||||
margin: UM.Theme.getSize("default_margin").width
|
||||
minimumWidth: UM.Theme.getSize("modal_window_minimum").width
|
||||
minimumHeight: UM.Theme.getSize("modal_window_minimum").height
|
||||
|
||||
backgroundColor: UM.Theme.getColor("detail_background")
|
||||
property bool dontShowAgain: false
|
||||
|
||||
function storeDontShowAgain()
|
||||
{
|
||||
UM.Preferences.setValue("cura/dialog_on_ucp_project_save", !dontShowAgainCheckbox.checked)
|
||||
UM.Preferences.setValue("cura/asked_dialog_on_ucp_project_save", false)
|
||||
}
|
||||
|
||||
onVisibleChanged:
|
||||
{
|
||||
if(visible && UM.Preferences.getValue("cura/asked_dialog_on_ucp_project_save"))
|
||||
{
|
||||
dontShowAgain = !UM.Preferences.getValue("cura/dialog_on_ucp_project_save")
|
||||
}
|
||||
}
|
||||
|
||||
headerComponent: Rectangle
|
||||
{
|
||||
height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").height
|
||||
color: UM.Theme.getColor("main_background")
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: headerColumn
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.rightMargin: anchors.leftMargin
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: titleLabel
|
||||
text: catalog.i18nc("@action:title", "Summary - Universal Cura Project")
|
||||
font: UM.Theme.getFont("large")
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: descriptionLabel
|
||||
text: catalog.i18nc("@action:description", "When exporting a Universal Cura Project, all the models present on the build plate will be included with their current position, orientation and scale. You can also select which per-extruder or per-model settings should be included to ensure a proper printing of the batch, even on different printers.")
|
||||
font: UM.Theme.getFont("default")
|
||||
wrapMode: Text.Wrap
|
||||
Layout.maximumWidth: headerColumn.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors.fill: parent
|
||||
color: UM.Theme.getColor("main_background")
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura" }
|
||||
|
||||
ListView
|
||||
{
|
||||
id: settingsExportList
|
||||
anchors.fill: parent
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
spacing: UM.Theme.getSize("thick_margin").height
|
||||
model: settingsExportModel.settingsGroups
|
||||
clip: true
|
||||
|
||||
ScrollBar.vertical: UM.ScrollBar { id: verticalScrollBar }
|
||||
|
||||
delegate: SettingsSelectionGroup { Layout.margins: 0 }
|
||||
}
|
||||
}
|
||||
leftButtons:
|
||||
[
|
||||
UM.CheckBox
|
||||
{
|
||||
id: dontShowAgainCheckbox
|
||||
text: catalog.i18nc("@action:label", "Don't show project summary on save again")
|
||||
checked: dontShowAgain
|
||||
}
|
||||
]
|
||||
rightButtons:
|
||||
[
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Cancel")
|
||||
onClicked: reject()
|
||||
},
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
text: catalog.i18nc("@action:button", "Save project")
|
||||
onClicked: accept()
|
||||
}
|
||||
]
|
||||
|
||||
buttonSpacing: UM.Theme.getSize("wide_margin").width
|
||||
|
||||
onClosing:
|
||||
{
|
||||
storeDontShowAgain()
|
||||
manager.notifyClosed()
|
||||
}
|
||||
onRejected: storeDontShowAgain()
|
||||
onAccepted: storeDontShowAgain()
|
||||
}
|
|
@ -2,9 +2,12 @@
|
|||
# Uranium is released under the terms of the LGPLv3 or higher.
|
||||
import sys
|
||||
|
||||
from PyQt6.QtQml import qmlRegisterType
|
||||
|
||||
from UM.Logger import Logger
|
||||
try:
|
||||
from . import ThreeMFWriter
|
||||
from .SettingsExportGroup import SettingsExportGroup
|
||||
threemf_writer_was_imported = True
|
||||
except ImportError:
|
||||
Logger.log("w", "Could not import ThreeMFWriter; libSavitar may be missing")
|
||||
|
@ -23,20 +26,24 @@ def getMetaData():
|
|||
|
||||
if threemf_writer_was_imported:
|
||||
metaData["mesh_writer"] = {
|
||||
"output": [{
|
||||
"output": [
|
||||
{
|
||||
"extension": "3mf",
|
||||
"description": i18n_catalog.i18nc("@item:inlistbox", "3MF file"),
|
||||
"mime_type": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
|
||||
"mode": ThreeMFWriter.ThreeMFWriter.OutputMode.BinaryMode
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
metaData["workspace_writer"] = {
|
||||
"output": [{
|
||||
"output": [
|
||||
{
|
||||
"extension": workspace_extension,
|
||||
"description": i18n_catalog.i18nc("@item:inlistbox", "Cura Project 3MF file"),
|
||||
"mime_type": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
|
||||
"mode": ThreeMFWorkspaceWriter.ThreeMFWorkspaceWriter.OutputMode.BinaryMode
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
return metaData
|
||||
|
@ -44,6 +51,8 @@ def getMetaData():
|
|||
|
||||
def register(app):
|
||||
if "3MFWriter.ThreeMFWriter" in sys.modules:
|
||||
qmlRegisterType(SettingsExportGroup, "ThreeMFWriter", 1, 0, "SettingsExportGroup")
|
||||
|
||||
return {"mesh_writer": ThreeMFWriter.ThreeMFWriter(),
|
||||
"workspace_writer": ThreeMFWorkspaceWriter.ThreeMFWorkspaceWriter()}
|
||||
else:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "3MF Writer",
|
||||
"author": "Ultimaker B.V.",
|
||||
"version": "1.0.1",
|
||||
"description": "Provides support for writing 3MF files.",
|
||||
"description": "Provides support for writing 3MF and UCP files.",
|
||||
"api": 8,
|
||||
"i18n-catalog": "cura"
|
||||
}
|
||||
|
|
|
@ -181,7 +181,10 @@ class CuraEngineBackend(QObject, Backend):
|
|||
application.getPreferences().preferenceChanged.connect(self._onPreferencesChanged)
|
||||
|
||||
self._slicing_error_message = Message(
|
||||
text = catalog.i18nc("@message", "Slicing failed with an unexpected error. Please consider reporting a bug on our issue tracker."),
|
||||
text = catalog.i18nc("@message", "Oops! We encountered an unexpected error during your slicing process. "
|
||||
"Rest assured, we've automatically received the crash logs for analysis, "
|
||||
"if you have not disabled data sharing in your preferences. To assist us "
|
||||
"further, consider sharing your project details on our issue tracker."),
|
||||
title = catalog.i18nc("@message:title", "Slicing failed"),
|
||||
message_type = Message.MessageType.ERROR
|
||||
)
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
"meshfix_keep_open_polygons": "fix_horrible_use_open_bits",
|
||||
"magic_mesh_surface_mode": "\"surface\" if simple_mode else \"normal\"",
|
||||
"magic_spiralize": "spiralize",
|
||||
"prime_tower_mode": "\"normal\" if wipe_tower else \"none\"",
|
||||
"prime_tower_enable": "wipe_tower",
|
||||
"prime_tower_size": "math.sqrt(float(wipe_tower_volume) / float(layer_height))",
|
||||
"ooze_shield_enabled": "ooze_shield",
|
||||
"skin_overlap": "fill_overlap"
|
||||
|
|
|
@ -263,6 +263,7 @@ class SliceInfo(QObject, Extension):
|
|||
print_settings["retraction_enable"] = global_stack.getProperty("retraction_enable", "value")
|
||||
|
||||
# Prime tower settings
|
||||
print_settings["prime_tower_enable"] = global_stack.getProperty("prime_tower_enable", "value")
|
||||
print_settings["prime_tower_mode"] = global_stack.getProperty("prime_tower_mode", "value")
|
||||
|
||||
# Infill settings
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
"machine_max_jerk_xy": { "value": 10 },
|
||||
"machine_max_jerk_z": { "value": 2 },
|
||||
"machine_name": { "default_value": "Anycubic Kobra 2" },
|
||||
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ; use absolute coordinates\nM82 ; use absolute distances for extrusion\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 ; home all axes\nM300 S1318 P266\nG1 Z5 F5000 ; lift nozzle\nG1 X5 Y0 F3000\nG1 Z0.3 ; set nozzle height\nG92 E0\nG1 X50 Y0 E20 F500 ; Extrude 20mm of filament in a 5cm line \nG92 E0 ; zero the extruded length again \nG1 E-4.5 F4800 ; Retract a little \nG92 E0\nG1 X120 F4000 ; Quickly wipe away from the filament line\nM117 ; Printing\u2026\nG5" },
|
||||
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ; use absolute coordinates\nM82 ; use absolute distances for extrusion\nM104 S{material_print_temperature_layer_0} ; set extruder temp\nM140 S{material_bed_temperature_layer_0} ; set bed temp\nM190 S{material_bed_temperature_layer_0} ; wait for bed temp\nM109 S{material_print_temperature_layer_0} ; wait for extruder temp\nG28 ; home all axes\nM300 S1318 P266\nG1 Z5 F5000 ; lift nozzle\nG1 X5 Y0 F3000\nG1 Z0.3 ; set nozzle height\nG92 E0\nG1 X50 Y0 E20 F500 ; Extrude 20mm of filament in a 5cm line \nG92 E0 ; zero the extruded length again \nG1 E-4.5 F4800 ; Retract a little \nG92 E0\nG1 X120 F4000 ; Quickly wipe away from the filament line\nM117 ; Printing\u2026\nG5" },
|
||||
"machine_width": { "default_value": 220 },
|
||||
"material_bed_temperature": { "maximum_value_warning": 110 },
|
||||
"material_bed_temperature_layer_0": { "maximum_value_warning": 110 },
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_height": { "default_value": 250 },
|
||||
"machine_name": { "default_value": "Anycubic Kobra Go" },
|
||||
"machine_start_gcode": { "default_value": "M140 S[first_layer_bed_temperature]; Heat bed\nM104 S[first_layer_temperature\n ]; Heat extruder\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG28 ; Home all axes\nG92 E0 ; Reset Extruder\nM420 S1 ; Enable Bed Levelling Mesh\nM190 S[first_layer_bed_temperature\n ]; Wait for bed to get up to temperature\nM109 S[first_layer_temperature\n ]; Wait for extruder to get up to temperature\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X2 Y20 Z0.3 F5000.0 ; Move to start position\nG1 X2 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line\nG1 X2.4 Y200.0 Z0.3 F5000.0 ; Move to side a little\nG1 X2.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 F2400 E-1\nG1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish" },
|
||||
"machine_start_gcode": { "default_value": "M140 S{material_bed_temperature_layer_0}; Heat bed\nM104 S{material_print_temperature_layer_0}; Heat extruder\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG28 ; Home all axes\nG92 E0 ; Reset Extruder\nM420 S1 ; Enable Bed Levelling Mesh\nM190 S{material_bed_temperature_layer_0}; Wait for bed to get up to temperature\nM109 S{material_print_temperature_layer_0}; Wait for extruder to get up to temperature\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 X2 Y20 Z0.3 F5000.0 ; Move to start position\nG1 X2 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line\nG1 X2.4 Y200.0 Z0.3 F5000.0 ; Move to side a little\nG1 X2.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line\nG92 E0 ; Reset Extruder\nG1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed\nG1 F2400 E-1\nG1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish" },
|
||||
"machine_width": { "default_value": 222 }
|
||||
}
|
||||
}
|
|
@ -110,7 +110,7 @@
|
|||
"min_infill_area": { "value": "5.0" },
|
||||
"minimum_polygon_circumference": { "value": "0.2" },
|
||||
"optimize_wall_printing_order": { "value": "True" },
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"prime_tower_enable": { "value": "True" },
|
||||
"retraction_amount": { "value": "1" },
|
||||
"retraction_combing": { "value": "'noskin'" },
|
||||
"retraction_combing_max_distance": { "value": "10" },
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
"machine_max_feedrate_y": { "value": 500 },
|
||||
"machine_max_feedrate_z": { "value": 30 },
|
||||
"machine_name": { "default_value": "Creality Ender-3 V3 SE" },
|
||||
"machine_start_gcode": { "default_value": "M220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nM420 S1; Enable mesh leveling\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM109 S[material_print_temperature_layer_0]\nG1 X10.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y145.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 E-1.0000 F1800 ;Retract a bit\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 E0.0000 F1800 \n" },
|
||||
"machine_start_gcode": { "default_value": "M220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nM420 S1; Use saved mesh leveling data\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nM190 S{material_bed_temperature_layer_0} ; Set bed temperature and wait\nM109 S{material_print_temperature_layer_0} ; Set hotend temperature and wait\nG1 X10.1 Y145.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y145.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 E-1.0000 F1800 ;Retract a bit\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 E0.0000 F1800 \n" },
|
||||
"machine_width": { "default_value": 220 },
|
||||
"retraction_amount": { "value": 0.8 },
|
||||
"retraction_speed": { "default_value": 40 },
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"machine_height": { "default_value": 400 },
|
||||
"machine_name": { "default_value": "Creality Ender-5 Plus" },
|
||||
"machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" },
|
||||
"machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nG29 ;Auto bed level\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" },
|
||||
"machine_width": { "default_value": 350 },
|
||||
"speed_print": { "value": 80.0 }
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_standby_temperature": { "value": "material_print_temperature" },
|
||||
"prime_tower_enable": { "value": true },
|
||||
"prime_tower_min_volume": { "value": "50" },
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"switch_extruder_retraction_amount": { "value": "0" }
|
||||
}
|
||||
}
|
|
@ -31,8 +31,8 @@
|
|||
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_standby_temperature": { "value": "material_print_temperature" },
|
||||
"prime_tower_enable": { "value": true },
|
||||
"prime_tower_min_volume": { "value": "50" },
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"switch_extruder_retraction_amount": { "value": "0" }
|
||||
}
|
||||
}
|
|
@ -31,8 +31,8 @@
|
|||
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||
"material_standby_temperature": { "value": "material_print_temperature" },
|
||||
"prime_tower_enable": { "value": "True" },
|
||||
"prime_tower_min_volume": { "value": "50" },
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"switch_extruder_retraction_amount": { "value": "0" }
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
"overrides":
|
||||
{
|
||||
"machine_end_gcode": { "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\"" },
|
||||
"machine_start_gcode": { "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \";material_bed_temperature={material_bed_temperature} material_print_temperature={material_print_temperature} material_print_temperature_layer_0={material_print_temperature_layer_0}\\nM190 S{material_bed_temperature_layer_0}\\nM104 T0 S{material_standby_temperature, 0}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nG21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 ;home all\\nT1 ; move to the nozzle 2\\nG0 Z20 F2400 ;move the platform to 30mm\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500 ; retract\\nT0 ; move to the nozzle 1\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM109 T0 S{material_print_temperature_layer_0, 0}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500\\nM104 T0 S{material_standby_temperature, 0}\\nT{initial_extruder_nr} ;switch to the first nozzle used for print\\nM109 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nM400 ;finish all moves\\nG1 E0 F1500\\nG92 E0\\n;end of startup sequence\\n\"" }
|
||||
"machine_start_gcode": { "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \";material_bed_temperature={material_bed_temperature} material_print_temperature={material_print_temperature} material_print_temperature_layer_0={material_print_temperature_layer_0}\\nM190 S{material_bed_temperature_layer_0}\\nM104 T0 S{material_standby_temperature, 0}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nG21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 ;home all\\nT1 ; move to the nozzle 2\\nG0 Z20 F2400 ;move the platform to 30mm\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500 ; retract\\nT0 ; move to the nozzle 1\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM109 T0 S{material_print_temperature_layer_0, 0}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500\\nM104 T0 S{material_standby_temperature, 0}\\nT{initial_extruder_nr} ;switch to the first nozzle used for print\\nM109 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nM400 ;finish all moves\\nG1 E0 F1500\\nG92 E0\\n;end of startup sequence\\n\"" },
|
||||
"prime_tower_enable": { "default_value": true }
|
||||
}
|
||||
}
|
|
@ -55,6 +55,7 @@
|
|||
"settable_per_extruder": false
|
||||
},
|
||||
"prime_blob_enable": { "default_value": false },
|
||||
"prime_tower_enable": { "default_value": true },
|
||||
"prime_tower_min_volume": { "default_value": 90 },
|
||||
"prime_tower_size": { "default_value": 30 },
|
||||
"raft_airgap": { "default_value": 0.25 },
|
||||
|
|
|
@ -979,7 +979,7 @@
|
|||
"description": "Width of a single prime tower line.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": 0.4,
|
||||
"value": "line_width",
|
||||
"minimum_value": "0.001",
|
||||
|
@ -3363,7 +3363,7 @@
|
|||
"description": "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal.",
|
||||
"type": "float",
|
||||
"unit": "mm/s",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": 60,
|
||||
"value": "speed_print",
|
||||
"minimum_value": "0.1",
|
||||
|
@ -3741,7 +3741,7 @@
|
|||
"maximum_value_warning": "10000",
|
||||
"default_value": 3000,
|
||||
"value": "acceleration_print",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and resolveOrValue('acceleration_enabled')",
|
||||
"enabled": "prime_tower_enable and resolveOrValue('acceleration_enabled')",
|
||||
"settable_per_mesh": false
|
||||
}
|
||||
}
|
||||
|
@ -4060,7 +4060,7 @@
|
|||
"maximum_value_warning": "50",
|
||||
"default_value": 20,
|
||||
"value": "jerk_print",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and resolveOrValue('jerk_enabled')",
|
||||
"enabled": "prime_tower_enable and resolveOrValue('jerk_enabled')",
|
||||
"settable_per_mesh": false
|
||||
}
|
||||
}
|
||||
|
@ -6794,20 +6794,30 @@
|
|||
"description": "Settings used for printing with multiple extruders.",
|
||||
"children":
|
||||
{
|
||||
"prime_tower_enable":
|
||||
{
|
||||
"label": "Enable Prime Tower",
|
||||
"description": "Print a tower next to the print which serves to prime the material after each nozzle switch.",
|
||||
"type": "bool",
|
||||
"enabled": "extruders_enabled_count > 1",
|
||||
"default_value": false,
|
||||
"resolve": "(extruders_enabled_count > 1) and any(extruderValues('prime_tower_enable'))",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
},
|
||||
"prime_tower_mode":
|
||||
{
|
||||
"label": "Prime Tower",
|
||||
"description": "<html>Print a tower next to the model, which serves to prime the material after each nozzle switch.<ul><li><b>None:</b> do not generate a prime tower</li><li><b>Normal:</b> generate a bucket in which secondary materials are primed</li><li><b>Interleaved:</b> generate a prime tower as sparse as possible. This will save time and filament, but is only possible if the used materials adhere to each other.</li></ul></html>",
|
||||
"label": "Prime Tower Type",
|
||||
"description": "<html>How to generate the prime tower:<ul><li><b>Normal:</b> create a bucket in which secondary materials are primed</li><li><b>Interleaved:</b> create a prime tower as sparse as possible. This will save time and filament, but is only possible if the used materials adhere to each other.</li></ul></html>",
|
||||
"type": "enum",
|
||||
"value": "'none' if (extruders_enabled_count < 2) else ('interleaved' if (all(material_type_var == extruderValues('material_type')[0] for material_type_var in extruderValues('material_type')) and all(material_brand_var == extruderValues('material_brand')[0] for material_brand_var in extruderValues('material_brand'))) else 'normal')",
|
||||
"value": "'interleaved' if (all(material_type_var == extruderValues('material_type')[0] for material_type_var in extruderValues('material_type')) and all(material_brand_var == extruderValues('material_brand')[0] for material_brand_var in extruderValues('material_brand'))) else 'normal'",
|
||||
"options":
|
||||
{
|
||||
"none": "None",
|
||||
"normal": "Normal",
|
||||
"interleaved": "Interleaved"
|
||||
},
|
||||
"default_value": "none",
|
||||
"enabled": "extruders_enabled_count > 1",
|
||||
"default_value": "normal",
|
||||
"enabled": "prime_tower_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
},
|
||||
|
@ -6817,7 +6827,7 @@
|
|||
"description": "The width of the prime tower.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": 20,
|
||||
"resolve": "max(extruderValues('prime_tower_size'))",
|
||||
"minimum_value": "0",
|
||||
|
@ -6836,7 +6846,7 @@
|
|||
"default_value": 6,
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "(resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height') - sum(extruderValues('prime_tower_min_volume')) + prime_tower_min_volume",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
|
@ -6849,7 +6859,7 @@
|
|||
"default_value": 5,
|
||||
"minimum_value": "line_width",
|
||||
"maximum_value_warning": "10.0",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
|
@ -6859,9 +6869,9 @@
|
|||
"description": "The x coordinate of the position of the prime tower.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": 200,
|
||||
"value": "(resolveOrValue('machine_width') / 2 + resolveOrValue('prime_tower_size') / 2) if resolveOrValue('machine_shape') == 'elliptic' else (resolveOrValue('machine_width') - (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0) - max(max(extruderValues('travel_avoid_distance')) + max(extruderValues('machine_nozzle_offset_x')) + max(extruderValues('support_offset')) + (extruderValue(skirt_brim_extruder_nr, 'skirt_brim_line_width') * extruderValue(skirt_brim_extruder_nr, 'skirt_line_count') * extruderValue(skirt_brim_extruder_nr, 'initial_layer_line_width_factor') / 100 + extruderValue(skirt_brim_extruder_nr, 'skirt_gap') if resolveOrValue('adhesion_type') == 'skirt' else 0) + (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0), max(map(abs, extruderValues('machine_nozzle_offset_x'))), 1)) - (resolveOrValue('machine_width') / 2 if resolveOrValue('machine_center_is_zero') else 0)",
|
||||
"value": "((resolveOrValue('machine_width') / 2 + resolveOrValue('prime_tower_size') / 2) if resolveOrValue('machine_shape') == 'elliptic' else (resolveOrValue('machine_width') - (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0) - max(max(extruderValues('travel_avoid_distance')) + max(extruderValues('machine_nozzle_offset_x')) + max(extruderValues('support_offset')) + (extruderValue(skirt_brim_extruder_nr, 'skirt_brim_line_width') * extruderValue(skirt_brim_extruder_nr, 'skirt_line_count') * extruderValue(skirt_brim_extruder_nr, 'initial_layer_line_width_factor') / 100 + extruderValue(skirt_brim_extruder_nr, 'skirt_gap') if resolveOrValue('adhesion_type') == 'skirt' else 0) + (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0), max(map(abs, extruderValues('machine_nozzle_offset_x'))), 1))) - (resolveOrValue('machine_width') / 2 if resolveOrValue('machine_center_is_zero') else 0)",
|
||||
"maximum_value": "(machine_width / 2 if machine_center_is_zero else machine_width) - (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0)",
|
||||
"minimum_value": "resolveOrValue('prime_tower_size') + (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0) - (machine_width / 2 if machine_center_is_zero else 0)",
|
||||
"settable_per_mesh": false,
|
||||
|
@ -6873,7 +6883,7 @@
|
|||
"description": "The y coordinate of the position of the prime tower.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": 200,
|
||||
"value": "machine_depth - prime_tower_size - (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0) - max(max(extruderValues('travel_avoid_distance')) + max(extruderValues('machine_nozzle_offset_y')) + max(extruderValues('support_offset')) + (extruderValue(skirt_brim_extruder_nr, 'skirt_brim_line_width') * extruderValue(skirt_brim_extruder_nr, 'skirt_line_count') * extruderValue(skirt_brim_extruder_nr, 'initial_layer_line_width_factor') / 100 + extruderValue(skirt_brim_extruder_nr, 'skirt_gap') if resolveOrValue('adhesion_type') == 'skirt' else 0) + (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0), max(map(abs, extruderValues('machine_nozzle_offset_y'))), 1) - (resolveOrValue('machine_depth') / 2 if resolveOrValue('machine_center_is_zero') else 0)",
|
||||
"maximum_value": "(machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')) - (resolveOrValue('prime_tower_base_size') if (resolveOrValue('adhesion_type') == 'raft' or resolveOrValue('prime_tower_brim_enable')) else 0)",
|
||||
|
@ -6886,7 +6896,7 @@
|
|||
"label": "Wipe Inactive Nozzle on Prime Tower",
|
||||
"description": "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower.",
|
||||
"type": "bool",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none'",
|
||||
"enabled": "prime_tower_enable",
|
||||
"default_value": true,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
|
@ -6897,7 +6907,7 @@
|
|||
"label": "Prime Tower Base",
|
||||
"description": "By enabling this setting, your prime-tower will get a brim, even if the model doesn't. If you want a sturdier base for a high tower, you can increase the base height.",
|
||||
"type": "bool",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and resolveOrValue('adhesion_type') != 'raft'",
|
||||
"enabled": "prime_tower_enable and resolveOrValue('adhesion_type') != 'raft'",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
|
@ -6909,7 +6919,7 @@
|
|||
"description": "The width of the prime tower brim/base. A larger base enhances adhesion to the build plate, but also reduces the effective print area.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"enabled": "prime_tower_enable and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"default_value": 1.2,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
|
||||
|
@ -6923,7 +6933,7 @@
|
|||
"description": "The height of the prime tower base. Increasing this value will result in a more sturdy prime tower because the base will be wider. If this setting is too low, the prime tower will not have a sturdy base.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"enabled": "prime_tower_enable and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"default_value": 0,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "machine_height",
|
||||
|
@ -6935,7 +6945,7 @@
|
|||
"label": "Prime Tower Base Slope",
|
||||
"description": "The magnitude factor used for the slope of the prime tower base. If you increase this value, the base will become slimmer. If you decrease it, the base will become thicker.",
|
||||
"type": "float",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"enabled": "prime_tower_enable and (resolveOrValue('prime_tower_brim_enable') or resolveOrValue('adhesion_type') == 'raft')",
|
||||
"default_value": 4,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "10",
|
||||
|
@ -6953,7 +6963,7 @@
|
|||
"minimum_value": "0",
|
||||
"minimum_value_warning": "raft_base_line_width",
|
||||
"maximum_value_warning": "100",
|
||||
"enabled": "resolveOrValue('prime_tower_mode') != 'none' and resolveOrValue('adhesion_type') == 'raft'",
|
||||
"enabled": "prime_tower_enable and resolveOrValue('adhesion_type') == 'raft'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"limit_to_extruder": "raft_base_extruder_nr"
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
"material_final_print_temperature": { "value": "default_material_print_temperature" },
|
||||
"material_initial_print_temperature": { "value": "default_material_print_temperature" },
|
||||
"material_standby_temperature": { "enabled": false },
|
||||
"prime_tower_mode": { "resolve": "'normal' if extruders_enabled_count > 1 else 'none'" },
|
||||
"prime_tower_enable": { "resolve": "extruders_enabled_count > 1" },
|
||||
"retraction_amount": { "default_value": 2 },
|
||||
"retraction_combing": { "value": "'all'" },
|
||||
"skirt_line_count": { "default_value": 3 },
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
"machine_width": { "default_value": 235 },
|
||||
"meshfix_maximum_resolution": { "value": 0.25 },
|
||||
"optimize_wall_printing_order": { "value": true },
|
||||
"prime_tower_enable": { "value": true },
|
||||
"prime_tower_min_volume": { "value": 30 },
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"retract_at_layer_change": { "value": false },
|
||||
"retraction_amount": { "value": 4.5 },
|
||||
"roofing_layer_count": { "value": 1 },
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"platform": "ratrig_vcore3_200.stl",
|
||||
"platform_offset": [
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"weight": 16
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"machine_extruder_trains": { "0": "ratrig_base_extruder_0" },
|
||||
"platform_offset": [
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"preferred_variant_name": "0.4mm Nozzle",
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
"machine_use_extruder_offset_to_offset_coords": { "default_value": false },
|
||||
"machine_width": { "default_value": 420 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"prime_tower_enable": { "default_value": true },
|
||||
"prime_tower_min_volume": { "default_value": 35.6 },
|
||||
"raft_acceleration": { "value": "machine_acceleration" },
|
||||
"raft_base_acceleration": { "value": "machine_acceleration" },
|
||||
|
|
|
@ -96,12 +96,9 @@
|
|||
"raft_interface_thickness": { "value": "(raft_base_thickness + raft_surface_thickness) / 2" },
|
||||
"raft_speed": { "value": 15 },
|
||||
"raft_surface_fan_speed": { "value": "cool_fan_speed_min" },
|
||||
"raft_surface_monotonic": { "value": true },
|
||||
"raft_surface_speed": { "value": "speed_topbottom" },
|
||||
"relative_extrusion":
|
||||
{
|
||||
"enabled": false,
|
||||
"value": false
|
||||
},
|
||||
"relative_extrusion": { "enabled": false },
|
||||
"retraction_combing": { "value": "'no_outer_surfaces'" },
|
||||
"retraction_combing_max_distance": { "value": 15 },
|
||||
"retraction_count_max": { "value": 25 },
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
"enabled": true,
|
||||
"value": "resolveOrValue('print_sequence') != 'one_at_a_time'"
|
||||
},
|
||||
"prime_tower_enable": { "default_value": true },
|
||||
"prime_tower_position_x": { "value": "185" },
|
||||
"prime_tower_wipe_enabled": { "default_value": false },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
"generic_hips_175",
|
||||
"generic_pc_175",
|
||||
"ultimaker_rapidrinse_175",
|
||||
"ultimaker_sr30_175",
|
||||
"generic_tpu_175",
|
||||
"goofoo_",
|
||||
"ideagen3D_",
|
||||
|
@ -346,9 +345,9 @@
|
|||
"prime_tower_base_curve_magnitude": { "value": 2 },
|
||||
"prime_tower_base_height": { "value": 6 },
|
||||
"prime_tower_base_size": { "value": 10 },
|
||||
"prime_tower_enable": { "value": false },
|
||||
"prime_tower_flow": { "value": "material_flow" },
|
||||
"prime_tower_line_width": { "value": 1 },
|
||||
"prime_tower_mode": { "value": "none" },
|
||||
"prime_tower_raft_base_line_spacing": { "value": "raft_base_line_width" },
|
||||
"prime_tower_wipe_enabled": { "value": true },
|
||||
"print_sequence": { "enabled": false },
|
||||
|
@ -376,10 +375,8 @@
|
|||
"retraction_prime_speed": { "value": "retraction_speed" },
|
||||
"retraction_speed": { "value": 5 },
|
||||
"roofing_layer_count": { "value": 2 },
|
||||
"roofing_material_flow": { "value": "material_flow" },
|
||||
"roofing_monotonic": { "value": true },
|
||||
"skin_material_flow": { "value": "0.95*material_flow" },
|
||||
"skin_monotonic": { "value": true },
|
||||
"skin_outline_count": { "value": 0 },
|
||||
"skin_overlap": { "value": 0 },
|
||||
"skin_preshrink": { "value": 0 },
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
"generic_nylon_175",
|
||||
"generic_hips_175",
|
||||
"generic_pc_175",
|
||||
"ultimaker_sr30_175",
|
||||
"generic_tpu_175",
|
||||
"goofoo_",
|
||||
"ideagen3D_",
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
"default_value": false,
|
||||
"enabled": true
|
||||
},
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"prime_tower_enable": { "value": "True" },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
"retraction_hop": { "value": "2" },
|
||||
"retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
"default_value": false,
|
||||
"enabled": true
|
||||
},
|
||||
"prime_tower_mode": { "value": "normal" },
|
||||
"prime_tower_enable": { "value": "True" },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
"retraction_combing": { "value": "'no_outer_surfaces'" },
|
||||
"retraction_hop": { "value": "2" },
|
||||
|
|
16
resources/extruders/geeetech_A20_1.def.json
Normal file
16
resources/extruders/geeetech_A20_1.def.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"version": 2,
|
||||
"name": "Extruder 1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata":
|
||||
{
|
||||
"machine": "geeetech_A20",
|
||||
"position": "0"
|
||||
},
|
||||
"overrides":
|
||||
{
|
||||
"extruder_nr": { "default_value": 0 },
|
||||
"machine_nozzle_size": { "default_value": 0.4 },
|
||||
"material_diameter": { "default_value": 1.75 }
|
||||
}
|
||||
}
|
BIN
resources/images/cura-share.png
Normal file
BIN
resources/images/cura-share.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1C
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_nylon12-cf_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1C
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1XA
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_sr30_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 2XA
|
||||
|
||||
[values]
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = LABS
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodx
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_nylon12-cf_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = LABS
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1C
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_nylon12-cf_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1C
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 1XA
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_sr30_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = 2XA
|
||||
|
||||
[values]
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_asa_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = LABS
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
[general]
|
||||
definition = ultimaker_methodxl
|
||||
name = Solid
|
||||
version = 4
|
||||
|
||||
[metadata]
|
||||
intent_category = solid
|
||||
is_experimental = True
|
||||
material = ultimaker_nylon12-cf_175
|
||||
quality_type = draft
|
||||
setting_version = 22
|
||||
type = intent
|
||||
variant = LABS
|
||||
|
||||
[values]
|
||||
infill_pattern = lines
|
||||
infill_sparse_density = 100
|
||||
|
|
@ -39,7 +39,7 @@ Item
|
|||
property alias printObjectAfterNext: printObjectAfterNextAction
|
||||
|
||||
property alias multiplyObject: multiplyObjectAction
|
||||
|
||||
property alias dropAll: dropAllAction
|
||||
property alias selectAll: selectAllAction
|
||||
property alias deleteAll: deleteAllAction
|
||||
property alias reloadAll: reloadAllAction
|
||||
|
@ -490,6 +490,14 @@ Item
|
|||
shortcut: "Shift+Ctrl+R"
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: dropAllAction
|
||||
text: catalog.i18nc("@action:inmenu menubar:edit","Drop All Models to buildplate")
|
||||
shortcut: "Ctrl+B"
|
||||
onTriggered: CuraApplication.setWorkplaceDropToBuildplate()
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: resetAllTranslationAction
|
||||
|
|
|
@ -25,7 +25,7 @@ UM.Dialog
|
|||
function storeDontShowAgain()
|
||||
{
|
||||
UM.Preferences.setValue("cura/dialog_on_project_save", !dontShowAgainCheckbox.checked)
|
||||
UM.Preferences.setValue("asked_dialog_on_project_save", true)
|
||||
UM.Preferences.setValue("cura/asked_dialog_on_project_save", true)
|
||||
}
|
||||
|
||||
onClosing: storeDontShowAgain()
|
||||
|
|
|
@ -15,6 +15,7 @@ Item
|
|||
property int iconSize: UM.Theme.getSize("extruder_icon").width
|
||||
property string iconVariant: "medium"
|
||||
property alias font: extruderNumberText.font
|
||||
property alias text: extruderNumberText.text
|
||||
|
||||
implicitWidth: iconSize
|
||||
implicitHeight: iconSize
|
||||
|
|
|
@ -71,6 +71,7 @@ Cura.Menu
|
|||
Cura.MenuItem { action: Cura.Actions.reloadAll }
|
||||
Cura.MenuItem { action: Cura.Actions.resetAllTranslation }
|
||||
Cura.MenuItem { action: Cura.Actions.resetAll }
|
||||
Cura.MenuItem { action: Cura.Actions.dropAll }
|
||||
|
||||
// Group actions
|
||||
Cura.MenuSeparator {}
|
||||
|
|
|
@ -21,6 +21,7 @@ Cura.Menu
|
|||
Cura.MenuItem { action: Cura.Actions.deleteAll }
|
||||
Cura.MenuItem { action: Cura.Actions.resetAllTranslation }
|
||||
Cura.MenuItem { action: Cura.Actions.resetAll }
|
||||
Cura.MenuItem { action: Cura.Actions.dropAll }
|
||||
Cura.MenuSeparator { }
|
||||
Cura.MenuItem { action: Cura.Actions.groupObjects }
|
||||
Cura.MenuItem { action: Cura.Actions.mergeObjects }
|
||||
|
|
|
@ -47,7 +47,11 @@ Cura.Menu
|
|||
enabled: UM.WorkspaceFileHandler.enabled && saveProjectMenu.model.count == 1
|
||||
onTriggered:
|
||||
{
|
||||
var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml" };
|
||||
const args = {
|
||||
"filter_by_machine": false,
|
||||
"file_type": "workspace",
|
||||
"preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
|
||||
};
|
||||
if (UM.Preferences.getValue("cura/dialog_on_project_save"))
|
||||
{
|
||||
saveWorkspaceDialog.args = args
|
||||
|
@ -70,6 +74,14 @@ Cura.Menu
|
|||
enabled: UM.WorkspaceFileHandler.enabled
|
||||
}
|
||||
|
||||
Cura.MenuItem
|
||||
{
|
||||
id: saveUCPMenu
|
||||
text: catalog.i18nc("@title:menu menubar:file", "&Save Universal Cura Project...")
|
||||
enabled: UM.WorkspaceFileHandler.enabled && CuraApplication.getPackageManager().allEnabledPackages.includes("3MFWriter")
|
||||
onTriggered: CuraApplication.exportUcp()
|
||||
}
|
||||
|
||||
Cura.MenuSeparator { }
|
||||
|
||||
Cura.MenuItem
|
||||
|
@ -78,8 +90,11 @@ Cura.Menu
|
|||
text: catalog.i18nc("@title:menu menubar:file", "&Export...")
|
||||
onTriggered:
|
||||
{
|
||||
var localDeviceId = "local_file"
|
||||
UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"})
|
||||
const args = {
|
||||
"filter_by_machine": false,
|
||||
"preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
|
||||
};
|
||||
UM.OutputDeviceManager.requestWriteToDevice("local_file", PrintInformation.jobName, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +104,13 @@ Cura.Menu
|
|||
text: catalog.i18nc("@action:inmenu menubar:file", "Export Selection...")
|
||||
enabled: UM.Selection.hasSelection
|
||||
icon.name: "document-save-as"
|
||||
onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"})
|
||||
onTriggered: {
|
||||
const args = {
|
||||
"filter_by_machine": false,
|
||||
"preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml",
|
||||
};
|
||||
UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, args);
|
||||
}
|
||||
}
|
||||
|
||||
Cura.MenuSeparator { }
|
||||
|
|
|
@ -101,6 +101,7 @@ UM.PreferencesPage
|
|||
centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select"))
|
||||
UM.Preferences.resetPreference("view/invert_zoom");
|
||||
invertZoomCheckbox.checked = boolCheck(UM.Preferences.getValue("view/invert_zoom"))
|
||||
UM.Preferences.resetPreference("view/navigation_style");
|
||||
UM.Preferences.resetPreference("view/zoom_to_mouse");
|
||||
zoomToMouseCheckbox.checked = boolCheck(UM.Preferences.getValue("view/zoom_to_mouse"))
|
||||
//UM.Preferences.resetPreference("view/top_layer_count");
|
||||
|
@ -512,7 +513,6 @@ UM.PreferencesPage
|
|||
onCheckedChanged:
|
||||
{
|
||||
UM.Preferences.setValue("physics/automatic_drop_down", checked)
|
||||
CuraApplication.getWorkplaceDropToBuildplate(checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -614,6 +614,55 @@ UM.PreferencesPage
|
|||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip", "What type of camera navigation should be used?")
|
||||
Column
|
||||
{
|
||||
spacing: UM.Theme.getSize("narrow_margin").height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@window:text", "Camera navigation:")
|
||||
}
|
||||
ListModel
|
||||
{
|
||||
id: navigationStylesList
|
||||
Component.onCompleted:
|
||||
{
|
||||
append({ text: catalog.i18n("Cura"), code: "cura" })
|
||||
append({ text: catalog.i18n("FreeCAD trackpad"), code: "freecad_trackpad" })
|
||||
}
|
||||
}
|
||||
|
||||
Cura.ComboBox
|
||||
{
|
||||
id: cameraNavigationComboBox
|
||||
|
||||
model: navigationStylesList
|
||||
textRole: "text"
|
||||
width: UM.Theme.getSize("combobox").width
|
||||
height: UM.Theme.getSize("combobox").height
|
||||
|
||||
currentIndex:
|
||||
{
|
||||
var code = UM.Preferences.getValue("view/navigation_style");
|
||||
for(var i = 0; i < comboBoxList.count; ++i)
|
||||
{
|
||||
if(model.get(i).code == code)
|
||||
{
|
||||
return i
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
onActivated: UM.Preferences.setValue("view/navigation_style", model.get(index).code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
//: Spacer
|
||||
|
@ -735,6 +784,20 @@ UM.PreferencesPage
|
|||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip", "Should a summary be shown when saving a UCP project file?")
|
||||
|
||||
UM.CheckBox
|
||||
{
|
||||
text: catalog.i18nc("@option:check", "Show summary dialog when saving a UCP project")
|
||||
checked: boolCheck(UM.Preferences.getValue("cura/dialog_on_ucp_project_save"))
|
||||
onCheckedChanged: UM.Preferences.setValue("cura/dialog_on_ucp_project_save", checked)
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
width: childrenRect.width
|
||||
|
|
|
@ -38,8 +38,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -38,8 +38,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -36,8 +36,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -36,8 +36,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -35,8 +35,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -35,8 +35,8 @@ line_width = 0.4
|
|||
min_infill_area = 0
|
||||
optimize_wall_printing_order = True
|
||||
prime_tower_brim_enable = True
|
||||
prime_tower_enable = True
|
||||
prime_tower_min_volume = 6
|
||||
prime_tower_mode = normal
|
||||
prime_tower_size = 20
|
||||
prime_tower_wipe_enabled = True
|
||||
retract_at_layer_change = False
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = DBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.40mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = FBE 0.60mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = V-DBE 0.80mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = V-DBE 0.80mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = V-DBE 0.80mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = V-DBE 0.80mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
|
@ -13,7 +13,7 @@ variant = V-FBE 0.80mm
|
|||
[values]
|
||||
brim_replaces_support = False
|
||||
material_standby_temperature = 100
|
||||
prime_tower_mode = none
|
||||
prime_tower_enable = False
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_bottom_stair_step_height = 0
|
||||
support_bottom_stair_step_width = 0
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue