mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-11-02 20:52:20 -07:00
Merge branch 'master' into feature_preheat_extruder
This commit is contained in:
commit
6e0717a967
58 changed files with 806 additions and 328 deletions
|
|
@ -81,8 +81,10 @@ class ThreeMFReader(MeshReader):
|
|||
self._object_count += 1
|
||||
node_name = "Object %s" % self._object_count
|
||||
|
||||
active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
|
||||
|
||||
um_node = CuraSceneNode()
|
||||
um_node.addDecorator(BuildPlateDecorator(0))
|
||||
um_node.addDecorator(BuildPlateDecorator(active_build_plate))
|
||||
um_node.setName(node_name)
|
||||
transformation = self._createMatrixFromTransformationString(savitar_node.getTransformation())
|
||||
um_node.setTransformation(transformation)
|
||||
|
|
|
|||
|
|
@ -168,11 +168,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
Logger.log("w", "Unknown definition container type %s for %s",
|
||||
definition_container_type, each_definition_container_file)
|
||||
Job.yieldThread()
|
||||
# sanity check
|
||||
|
||||
if machine_definition_container_count != 1:
|
||||
msg = "Expecting one machine definition container but got %s" % machine_definition_container_count
|
||||
Logger.log("e", msg)
|
||||
raise RuntimeError(msg)
|
||||
return WorkspaceReader.PreReadResult.failed #Not a workspace file but ordinary 3MF.
|
||||
|
||||
material_labels = []
|
||||
material_conflict = False
|
||||
|
|
@ -271,7 +269,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
# if the global stack is found, we check if there are conflicts in the extruder stacks
|
||||
if containers_found_dict["machine"] and not machine_conflict:
|
||||
for extruder_stack_file in extruder_stack_files:
|
||||
container_id = self._stripFileToId(extruder_stack_file)
|
||||
serialized = archive.open(extruder_stack_file).read().decode("utf-8")
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string(serialized)
|
||||
|
|
@ -303,7 +300,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
break
|
||||
|
||||
num_visible_settings = 0
|
||||
has_visible_settings_string = False
|
||||
try:
|
||||
temp_preferences = Preferences()
|
||||
serialized = archive.open("Cura/preferences.cfg").read().decode("utf-8")
|
||||
|
|
@ -609,7 +605,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
|
||||
instance_container.setName(self._container_registry.uniqueName(instance_container.getName()))
|
||||
new_changes_container_id = self.getNewId(instance_container.getId())
|
||||
instance_container._id = new_changes_container_id
|
||||
instance_container.setMetaDataEntry("id", new_changes_container_id)
|
||||
|
||||
# TODO: we don't know the following is correct or not, need to verify
|
||||
# AND REFACTOR!!!
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ from UM.Math.Vector import Vector
|
|||
from UM.Logger import Logger
|
||||
from UM.Math.Matrix import Matrix
|
||||
from UM.Application import Application
|
||||
import UM.Scene.SceneNode
|
||||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
import Savitar
|
||||
|
||||
|
|
@ -62,11 +63,15 @@ class ThreeMFWriter(MeshWriter):
|
|||
self._store_archive = store_archive
|
||||
|
||||
## Convenience function that converts an Uranium SceneNode object to a SavitarSceneNode
|
||||
# \returns Uranium Scenen node.
|
||||
# \returns Uranium Scene node.
|
||||
def _convertUMNodeToSavitarNode(self, um_node, transformation = Matrix()):
|
||||
if type(um_node) not in [UM.Scene.SceneNode.SceneNode, CuraSceneNode]:
|
||||
if not isinstance(um_node, SceneNode):
|
||||
return None
|
||||
|
||||
active_build_plate_nr = CuraApplication.getInstance().getBuildPlateModel().activeBuildPlate
|
||||
if um_node.callDecoration("getBuildPlateNumber") != active_build_plate_nr:
|
||||
return
|
||||
|
||||
savitar_node = Savitar.SceneNode()
|
||||
|
||||
node_matrix = um_node.getLocalTransformation()
|
||||
|
|
@ -97,6 +102,9 @@ class ThreeMFWriter(MeshWriter):
|
|||
savitar_node.setSetting(key, str(stack.getProperty(key, "value")))
|
||||
|
||||
for child_node in um_node.getChildren():
|
||||
# only save the nodes on the active build plate
|
||||
if child_node.callDecoration("getBuildPlateNumber") != active_build_plate_nr:
|
||||
continue
|
||||
savitar_child_node = self._convertUMNodeToSavitarNode(child_node)
|
||||
if savitar_child_node is not None:
|
||||
savitar_node.addChild(savitar_child_node)
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
#
|
||||
self._global_container_stack = None
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
|
||||
Application.getInstance().getExtruderManager().activeExtruderChanged.connect(self._onGlobalStackChanged)
|
||||
Application.getInstance().getExtruderManager().extrudersAdded.connect(self._onGlobalStackChanged)
|
||||
self._onGlobalStackChanged()
|
||||
|
||||
Application.getInstance().stacksValidationFinished.connect(self._onStackErrorCheckFinished)
|
||||
|
|
@ -423,7 +423,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
#
|
||||
# \param source The scene node that was changed.
|
||||
def _onSceneChanged(self, source):
|
||||
if not issubclass(type(source), SceneNode):
|
||||
if not isinstance(source, SceneNode):
|
||||
return
|
||||
|
||||
build_plate_changed = set()
|
||||
|
|
@ -722,7 +722,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
if self._global_container_stack:
|
||||
self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged)
|
||||
self._global_container_stack.containersChanged.disconnect(self._onChanged)
|
||||
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
extruders = list(self._global_container_stack.extruders.values())
|
||||
|
||||
for extruder in extruders:
|
||||
extruder.propertyChanged.disconnect(self._onSettingChanged)
|
||||
|
|
@ -733,7 +733,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
if self._global_container_stack:
|
||||
self._global_container_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed.
|
||||
self._global_container_stack.containersChanged.connect(self._onChanged)
|
||||
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
|
||||
extruders = list(self._global_container_stack.extruders.values())
|
||||
for extruder in extruders:
|
||||
extruder.propertyChanged.connect(self._onSettingChanged)
|
||||
extruder.containersChanged.connect(self._onChanged)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,12 @@ class StartSliceJob(Job):
|
|||
self.setResult(StartJobResult.BuildPlateError)
|
||||
return
|
||||
|
||||
# Don't slice if the buildplate or the nozzle type is incompatible with the materials
|
||||
if not Application.getInstance().getMachineManager().variantBuildplateCompatible and \
|
||||
not Application.getInstance().getMachineManager().variantBuildplateUsable:
|
||||
self.setResult(StartJobResult.MaterialIncompatible)
|
||||
return
|
||||
|
||||
for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
|
||||
material = extruder_stack.findContainer({"type": "material"})
|
||||
if material:
|
||||
|
|
|
|||
|
|
@ -225,7 +225,10 @@ class MachineSettingsAction(MachineAction):
|
|||
material_approximate_diameter = str(round(material_diameter))
|
||||
machine_diameter = extruder_stack.definitionChanges.getProperty("material_diameter", "value")
|
||||
if not machine_diameter:
|
||||
machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
|
||||
if extruder_stack.definition.hasProperty("material_diameter", "value"):
|
||||
machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
|
||||
else:
|
||||
machine_diameter = self._global_container_stack.definition.getProperty("material_diameter", "value")
|
||||
machine_approximate_diameter = str(round(machine_diameter))
|
||||
|
||||
if material_approximate_diameter != machine_approximate_diameter:
|
||||
|
|
|
|||
|
|
@ -54,7 +54,11 @@ class PostProcessingPlugin(QObject, Extension):
|
|||
## Execute all post-processing scripts on the gcode.
|
||||
def execute(self, output_device):
|
||||
scene = Application.getInstance().getController().getScene()
|
||||
gcode_dict = getattr(scene, "gcode_dict")
|
||||
gcode_dict = None
|
||||
|
||||
if hasattr(scene, "gcode_dict"):
|
||||
gcode_dict = getattr(scene, "gcode_dict")
|
||||
|
||||
if not gcode_dict:
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class SimulationPass(RenderPass):
|
|||
nozzle_node = node
|
||||
nozzle_node.setVisible(False)
|
||||
|
||||
elif issubclass(type(node), SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible():
|
||||
elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible():
|
||||
layer_data = node.callDecoration("getLayerData")
|
||||
if not layer_data:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import sys
|
||||
|
|
@ -344,7 +344,12 @@ class SimulationView(View):
|
|||
self._max_feedrate = max(float(p.lineFeedrates.max()), self._max_feedrate)
|
||||
self._min_feedrate = min(float(p.lineFeedrates.min()), self._min_feedrate)
|
||||
self._max_thickness = max(float(p.lineThicknesses.max()), self._max_thickness)
|
||||
self._min_thickness = min(float(p.lineThicknesses.min()), self._min_thickness)
|
||||
try:
|
||||
self._min_thickness = min(float(p.lineThicknesses[numpy.nonzero(p.lineThicknesses)].min()), self._min_thickness)
|
||||
except:
|
||||
# Sometimes, when importing a GCode the line thicknesses are zero and so the minimum (avoiding
|
||||
# the zero) can't be calculated
|
||||
Logger.log("i", "Min thickness can't be calculated because all the values are zero")
|
||||
if max_layer_number < layer_id:
|
||||
max_layer_number = layer_id
|
||||
if min_layer_number > layer_id:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
|
||||
|
|
@ -117,7 +117,7 @@ class SimulationViewProxy(QObject):
|
|||
def setSimulationViewType(self, layer_view_type):
|
||||
active_view = self._controller.getActiveView()
|
||||
if isinstance(active_view, SimulationView.SimulationView.SimulationView):
|
||||
active_view.setSimulationViewisinstance(layer_view_type)
|
||||
active_view.setSimulationViewType(layer_view_type)
|
||||
|
||||
@pyqtSlot(result=int)
|
||||
def getSimulationViewType(self):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtQml import qmlRegisterSingletonType
|
||||
|
|
@ -18,7 +18,7 @@ def getMetaData():
|
|||
}
|
||||
|
||||
def createSimulationViewProxy(engine, script_engine):
|
||||
return SimulationViewProxy.SimulatorViewProxy()
|
||||
return SimulationViewProxy.SimulationViewProxy()
|
||||
|
||||
def register(app):
|
||||
simulation_view = SimulationView.SimulationView()
|
||||
|
|
|
|||
|
|
@ -52,13 +52,19 @@ Component
|
|||
{
|
||||
id: addRemovePrintersLabel
|
||||
anchors.right: parent.right
|
||||
text: "Add / remove printers"
|
||||
text: catalog.i18nc("@label link to connect manager", "Add/Remove printers")
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text")
|
||||
linkColor: UM.Theme.getColor("text_link")
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: addRemovePrintersLabel
|
||||
hoverEnabled: true
|
||||
onClicked: Cura.MachineManager.printerOutputDevices[0].openPrinterControlPanel()
|
||||
onEntered: addRemovePrintersLabel.font.underline = true
|
||||
onExited: addRemovePrintersLabel.font.underline = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
self.setShortDescription(i18n_catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print over network"))
|
||||
self.setDescription(i18n_catalog.i18nc("@properties:tooltip", "Print over network"))
|
||||
|
||||
self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network"))
|
||||
|
||||
self._printer_uuid_to_unique_name_mapping = {}
|
||||
|
||||
self._finished_jobs = []
|
||||
|
|
@ -76,20 +78,26 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
self._cluster_size = int(properties.get(b"cluster_size", 0))
|
||||
|
||||
def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs):
|
||||
# Notify the UI that a switch to the print monitor should happen
|
||||
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||
self.writeStarted.emit(self)
|
||||
|
||||
self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list", [])
|
||||
if not self._gcode:
|
||||
gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", [])
|
||||
active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
|
||||
gcode_list = gcode_dict[active_build_plate_id]
|
||||
|
||||
if not gcode_list:
|
||||
# Unable to find g-code. Nothing to send
|
||||
return
|
||||
|
||||
self._gcode = gcode_list
|
||||
|
||||
if len(self._printers) > 1:
|
||||
self._spawnPrinterSelectionDialog()
|
||||
else:
|
||||
self.sendPrintJob()
|
||||
|
||||
# Notify the UI that a switch to the print monitor should happen
|
||||
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||
|
||||
def _spawnPrinterSelectionDialog(self):
|
||||
if self._printer_selection_dialog is None:
|
||||
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "PrintWindow.qml")
|
||||
|
|
@ -240,7 +248,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
|
||||
newly_finished_jobs = [job for job in finished_jobs if job not in self._finished_jobs and job.owner == username]
|
||||
for job in newly_finished_jobs:
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.".format(printer_name=job.assignedPrinter.name, job_name = job.name))
|
||||
if job.assignedPrinter:
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.".format(printer_name=job.assignedPrinter.name, job_name = job.name))
|
||||
else:
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "The print job '{job_name}' was finished.".format(job_name = job.name))
|
||||
job_completed_message = Message(text=job_completed_text, title = i18n_catalog.i18nc("@info:status", "Print finished"))
|
||||
job_completed_message.show()
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,16 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
|
||||
def _onAuthenticationStateChanged(self):
|
||||
# We only accept commands if we are authenticated.
|
||||
self._setAcceptsCommands(self._authentication_state == AuthState.Authenticated)
|
||||
|
||||
if self._authentication_state == AuthState.Authenticated:
|
||||
self._setAcceptsCommands(True)
|
||||
else:
|
||||
self._setAcceptsCommands(False)
|
||||
self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network."))
|
||||
elif self._authentication_state == AuthState.AuthenticationRequested:
|
||||
self.setConnectionText(i18n_catalog.i18nc("@info:status",
|
||||
"Connected over the network. Please approve the access request on the printer."))
|
||||
elif self._authentication_state == AuthState.AuthenticationDenied:
|
||||
self.setConnectionText(i18n_catalog.i18nc("@info:status", "Connected over the network. No access to control the printer."))
|
||||
|
||||
|
||||
def _setupMessages(self):
|
||||
self._authentication_requested_message = Message(i18n_catalog.i18nc("@info:status",
|
||||
|
|
@ -175,15 +181,18 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
# Not authenticated, so unable to send job.
|
||||
return
|
||||
|
||||
# Notify the UI that a switch to the print monitor should happen
|
||||
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||
self.writeStarted.emit(self)
|
||||
|
||||
self._gcode = getattr(Application.getInstance().getController().getScene(), "gcode_list", [])
|
||||
if not self._gcode:
|
||||
gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", [])
|
||||
active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
|
||||
gcode_list = gcode_dict[active_build_plate_id]
|
||||
|
||||
if not gcode_list:
|
||||
# Unable to find g-code. Nothing to send
|
||||
return
|
||||
|
||||
self._gcode = gcode_list
|
||||
|
||||
errors = self._checkForErrors()
|
||||
if errors:
|
||||
text = i18n_catalog.i18nc("@label", "Unable to start a new print job.")
|
||||
|
|
@ -229,6 +238,9 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
# No warnings or errors, so we're good to go.
|
||||
self._startPrint()
|
||||
|
||||
# Notify the UI that a switch to the print monitor should happen
|
||||
Application.getInstance().getController().setActiveStage("MonitorStage")
|
||||
|
||||
def _startPrint(self):
|
||||
Logger.log("i", "Sending print job to printer.")
|
||||
if self._sending_gcode:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ UM.Dialog
|
|||
|
||||
property var printersModel: ListModel{}
|
||||
function resetPrintersModel() {
|
||||
printersModel.clear()
|
||||
printersModel.append({ name: "Automatic", key: ""})
|
||||
|
||||
for (var index in OutputDevice.printers)
|
||||
|
|
|
|||
|
|
@ -115,24 +115,8 @@ Item
|
|||
{
|
||||
tooltip: catalog.i18nc("@info:tooltip", "Load the configuration of the printer into Cura")
|
||||
text: catalog.i18nc("@action:button", "Activate Configuration")
|
||||
visible: printerConnected && !isClusterPrinter()
|
||||
visible: false // printerConnected && !isClusterPrinter()
|
||||
onClicked: manager.loadConfigurationFromPrinter()
|
||||
|
||||
function isClusterPrinter() {
|
||||
return false
|
||||
//TODO: Hardcoded this for the moment now. These info components might also need to move.
|
||||
/*if(Cura.MachineManager.printerOutputDevices.length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize;
|
||||
// This is not a cluster printer or the cluster it is just one printer
|
||||
if(clusterSize == undefined || clusterSize == 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._firmware_progress = 0
|
||||
self._firmware_update_state = FirmwareUpdateState.idle
|
||||
|
||||
self.setConnectionText(catalog.i18nc("@info:status", "Connected via USB"))
|
||||
|
||||
# Queue for commands that need to be send. Used when command is sent when a print is active.
|
||||
self._command_queue = Queue()
|
||||
|
||||
|
|
|
|||
|
|
@ -576,6 +576,42 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
if is_new_material:
|
||||
containers_to_add.append(new_material)
|
||||
|
||||
# Find the buildplates compatibility
|
||||
buildplates = machine.iterfind("./um:buildplate", self.__namespaces)
|
||||
buildplate_map = {}
|
||||
buildplate_map["buildplate_compatible"] = {}
|
||||
buildplate_map["buildplate_recommended"] = {}
|
||||
for buildplate in buildplates:
|
||||
buildplate_id = buildplate.get("id")
|
||||
if buildplate_id is None:
|
||||
continue
|
||||
|
||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(
|
||||
id = buildplate_id)
|
||||
if not variant_containers:
|
||||
# It is not really properly defined what "ID" is so also search for variants by name.
|
||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(
|
||||
definition = machine_id, name = buildplate_id)
|
||||
|
||||
if not variant_containers:
|
||||
continue
|
||||
|
||||
buildplate_compatibility = machine_compatibility
|
||||
buildplate_recommended = machine_compatibility
|
||||
settings = buildplate.iterfind("./um:setting", self.__namespaces)
|
||||
for entry in settings:
|
||||
key = entry.get("key")
|
||||
if key in self.__unmapped_settings:
|
||||
if key == "hardware compatible":
|
||||
buildplate_compatibility = self._parseCompatibleValue(entry.text)
|
||||
elif key == "hardware recommended":
|
||||
buildplate_recommended = self._parseCompatibleValue(entry.text)
|
||||
else:
|
||||
Logger.log("d", "Unsupported material setting %s", key)
|
||||
|
||||
buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_compatibility
|
||||
buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_recommended
|
||||
|
||||
hotends = machine.iterfind("./um:hotend", self.__namespaces)
|
||||
for hotend in hotends:
|
||||
hotend_id = hotend.get("id")
|
||||
|
|
@ -605,8 +641,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
|
||||
new_hotend_id = self.getId() + "_" + machine_id + "_" + hotend_id.replace(" ", "_")
|
||||
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent
|
||||
# material
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent material
|
||||
if ContainerRegistry.getInstance().isLoaded(new_hotend_id):
|
||||
new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_id)[0]
|
||||
is_new_material = False
|
||||
|
|
@ -623,6 +658,9 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
new_hotend_material.getMetaData()["compatible"] = hotend_compatibility
|
||||
new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
|
||||
new_hotend_material.getMetaData()["definition"] = machine_id
|
||||
if buildplate_map["buildplate_compatible"]:
|
||||
new_hotend_material.getMetaData()["buildplate_compatible"] = buildplate_map["buildplate_compatible"]
|
||||
new_hotend_material.getMetaData()["buildplate_recommended"] = buildplate_map["buildplate_recommended"]
|
||||
|
||||
cached_hotend_setting_properties = cached_machine_setting_properties.copy()
|
||||
cached_hotend_setting_properties.update(hotend_setting_values)
|
||||
|
|
@ -763,6 +801,34 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
if len(found_materials) == 0: #This is a new material.
|
||||
result_metadata.append(new_material_metadata)
|
||||
|
||||
buildplates = machine.iterfind("./um:buildplate", cls.__namespaces)
|
||||
buildplate_map = {}
|
||||
buildplate_map["buildplate_compatible"] = {}
|
||||
buildplate_map["buildplate_recommended"] = {}
|
||||
for buildplate in buildplates:
|
||||
buildplate_id = buildplate.get("id")
|
||||
if buildplate_id is None:
|
||||
continue
|
||||
|
||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = buildplate_id)
|
||||
if not variant_containers:
|
||||
# It is not really properly defined what "ID" is so also search for variants by name.
|
||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = buildplate_id)
|
||||
|
||||
if not variant_containers:
|
||||
continue
|
||||
|
||||
settings = buildplate.iterfind("./um:setting", cls.__namespaces)
|
||||
for entry in settings:
|
||||
key = entry.get("key")
|
||||
if key == "hardware compatible":
|
||||
buildplate_compatibility = cls._parseCompatibleValue(entry.text)
|
||||
elif key == "hardware recommended":
|
||||
buildplate_recommended = cls._parseCompatibleValue(entry.text)
|
||||
|
||||
buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_map["buildplate_compatible"]
|
||||
buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_map["buildplate_recommended"]
|
||||
|
||||
for hotend in machine.iterfind("./um:hotend", cls.__namespaces):
|
||||
hotend_id = hotend.get("id")
|
||||
if hotend_id is None:
|
||||
|
|
@ -781,8 +847,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
|
||||
new_hotend_id = container_id + "_" + machine_id + "_" + hotend_id.replace(" ", "_")
|
||||
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent
|
||||
# material
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent material
|
||||
found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_id)
|
||||
if found_materials:
|
||||
new_hotend_material_metadata = found_materials[0]
|
||||
|
|
@ -799,6 +864,9 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
new_hotend_material_metadata["machine_manufacturer"] = machine_manufacturer
|
||||
new_hotend_material_metadata["id"] = new_hotend_id
|
||||
new_hotend_material_metadata["definition"] = machine_id
|
||||
if buildplate_map["buildplate_compatible"]:
|
||||
new_hotend_material_metadata["buildplate_compatible"] = buildplate_map["buildplate_compatible"]
|
||||
new_hotend_material_metadata["buildplate_recommended"] = buildplate_map["buildplate_recommended"]
|
||||
|
||||
if len(found_materials) == 0:
|
||||
result_metadata.append(new_hotend_material_metadata)
|
||||
|
|
@ -874,7 +942,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
# Map XML file setting names to internal names
|
||||
__material_settings_setting_map = {
|
||||
"print temperature": "default_material_print_temperature",
|
||||
"heated bed temperature": "material_bed_temperature",
|
||||
"heated bed temperature": "default_material_bed_temperature",
|
||||
"standby temperature": "material_standby_temperature",
|
||||
"processing temperature graph": "material_flow_temp_graph",
|
||||
"print cooling": "cool_fan_speed",
|
||||
|
|
@ -884,7 +952,8 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
"surface energy": "material_surface_energy"
|
||||
}
|
||||
__unmapped_settings = [
|
||||
"hardware compatible"
|
||||
"hardware compatible",
|
||||
"hardware recommended"
|
||||
]
|
||||
__material_properties_setting_map = {
|
||||
"diameter": "material_diameter"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue