mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-12 09:17:50 -06:00
resolve merge conflict
This commit is contained in:
commit
f61efb8e20
7 changed files with 61 additions and 46 deletions
|
@ -501,11 +501,6 @@ class CuraApplication(QtApplication):
|
||||||
def getStaticVersion(cls):
|
def getStaticVersion(cls):
|
||||||
return CuraVersion
|
return CuraVersion
|
||||||
|
|
||||||
## Handle removing the unneeded plugins
|
|
||||||
# \sa PluginRegistry
|
|
||||||
def _removePlugins(self):
|
|
||||||
self._plugin_registry.removePlugins()
|
|
||||||
|
|
||||||
## Handle loading of all plugin types (and the backend explicitly)
|
## Handle loading of all plugin types (and the backend explicitly)
|
||||||
# \sa PluginRegistry
|
# \sa PluginRegistry
|
||||||
def _loadPlugins(self):
|
def _loadPlugins(self):
|
||||||
|
|
34
cura/Utils/Threading.py
Normal file
34
cura/Utils/Threading.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HACK:
|
||||||
|
#
|
||||||
|
# In project loading, when override the existing machine is selected, the stacks and containers that are correctly
|
||||||
|
# active in the system will be overridden at runtime. Because the project loading is done in a different thread than
|
||||||
|
# the Qt thread, something else can kick in the middle of the process. One of them is the rendering. It will access
|
||||||
|
# the current stacks and container, which have not completely been updated yet, so Cura will crash in this case.
|
||||||
|
#
|
||||||
|
# This "@call_on_qt_thread" decorator makes sure that a function will always be called on the Qt thread (blocking).
|
||||||
|
# It is applied to the read() function of project loading so it can be guaranteed that only after the project loading
|
||||||
|
# process is completely done, everything else that needs to occupy the QT thread will be executed.
|
||||||
|
#
|
||||||
|
class InterCallObject:
|
||||||
|
def __init__(self):
|
||||||
|
self.finish_event = threading.Event()
|
||||||
|
self.result = None
|
||||||
|
|
||||||
|
|
||||||
|
def call_on_qt_thread(func):
|
||||||
|
def _call_on_qt_thread_wrapper(*args, **kwargs):
|
||||||
|
def _handle_call(ico, *args, **kwargs):
|
||||||
|
ico.result = func(*args, **kwargs)
|
||||||
|
ico.finish_event.set()
|
||||||
|
inter_call_object = InterCallObject()
|
||||||
|
new_args = tuple([inter_call_object] + list(args)[:])
|
||||||
|
CuraApplication.getInstance().callLater(_handle_call, *new_args, **kwargs)
|
||||||
|
inter_call_object.finish_event.wait()
|
||||||
|
return inter_call_object.result
|
||||||
|
return _call_on_qt_thread_wrapper
|
|
@ -7,6 +7,7 @@ import os
|
||||||
import threading
|
import threading
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
||||||
|
@ -28,43 +29,13 @@ from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.Utils.Threading import call_on_qt_thread
|
||||||
|
|
||||||
from .WorkspaceDialog import WorkspaceDialog
|
from .WorkspaceDialog import WorkspaceDialog
|
||||||
|
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# HACK:
|
|
||||||
#
|
|
||||||
# In project loading, when override the existing machine is selected, the stacks and containers that are correctly
|
|
||||||
# active in the system will be overridden at runtime. Because the project loading is done in a different thread than
|
|
||||||
# the Qt thread, something else can kick in the middle of the process. One of them is the rendering. It will access
|
|
||||||
# the current stacks and container, which have not completely been updated yet, so Cura will crash in this case.
|
|
||||||
#
|
|
||||||
# This "@call_on_qt_thread" decorator makes sure that a function will always be called on the Qt thread (blocking).
|
|
||||||
# It is applied to the read() function of project loading so it can be guaranteed that only after the project loading
|
|
||||||
# process is completely done, everything else that needs to occupy the QT thread will be executed.
|
|
||||||
#
|
|
||||||
class InterCallObject:
|
|
||||||
def __init__(self):
|
|
||||||
self.finish_event = threading.Event()
|
|
||||||
self.result = None
|
|
||||||
|
|
||||||
|
|
||||||
def call_on_qt_thread(func):
|
|
||||||
def _call_on_qt_thread_wrapper(*args, **kwargs):
|
|
||||||
def _handle_call(ico, *args, **kwargs):
|
|
||||||
ico.result = func(*args, **kwargs)
|
|
||||||
ico.finish_event.set()
|
|
||||||
inter_call_object = InterCallObject()
|
|
||||||
new_args = tuple([inter_call_object] + list(args)[:])
|
|
||||||
CuraApplication.getInstance().callLater(_handle_call, *new_args, **kwargs)
|
|
||||||
inter_call_object.finish_event.wait()
|
|
||||||
return inter_call_object.result
|
|
||||||
return _call_on_qt_thread_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerInfo:
|
class ContainerInfo:
|
||||||
def __init__(self, file_name: str, serialized: str, parser: ConfigParser):
|
def __init__(self, file_name: str, serialized: str, parser: ConfigParser):
|
||||||
self.file_name = file_name
|
self.file_name = file_name
|
||||||
|
|
|
@ -6,16 +6,18 @@ from io import StringIO
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.Workspace.WorkspaceWriter import WorkspaceWriter
|
from UM.Workspace.WorkspaceWriter import WorkspaceWriter
|
||||||
|
|
||||||
|
from cura.Utils.Threading import call_on_qt_thread
|
||||||
|
|
||||||
|
|
||||||
class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@call_on_qt_thread
|
||||||
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
|
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
|
||||||
application = Application.getInstance()
|
application = Application.getInstance()
|
||||||
machine_manager = application.getMachineManager()
|
machine_manager = application.getMachineManager()
|
||||||
|
|
|
@ -121,7 +121,7 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
self._slice_start_time = None
|
self._slice_start_time = None
|
||||||
self._is_disabled = False
|
self._is_disabled = False
|
||||||
|
|
||||||
Preferences.getInstance().addPreference("general/auto_slice", True)
|
Preferences.getInstance().addPreference("general/auto_slice", False)
|
||||||
|
|
||||||
self._use_timer = False
|
self._use_timer = False
|
||||||
# When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired.
|
# When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired.
|
||||||
|
|
|
@ -49,6 +49,13 @@ class ModelChecker(QObject, Extension):
|
||||||
warning_size_xy = 150 #The horizontal size of a model that would be too large when dealing with shrinking materials.
|
warning_size_xy = 150 #The horizontal size of a model that would be too large when dealing with shrinking materials.
|
||||||
warning_size_z = 100 #The vertical size of a model that would be too large when dealing with shrinking materials.
|
warning_size_z = 100 #The vertical size of a model that would be too large when dealing with shrinking materials.
|
||||||
|
|
||||||
|
# This function can be triggered in the middle of a machine change, so do not proceed if the machine change
|
||||||
|
# has not done yet.
|
||||||
|
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
if global_container_stack is None:
|
||||||
|
Application.getInstance().callLater(lambda: self.onChanged.emit())
|
||||||
|
return False
|
||||||
|
|
||||||
material_shrinkage = self._getMaterialShrinkage()
|
material_shrinkage = self._getMaterialShrinkage()
|
||||||
|
|
||||||
warning_nodes = []
|
warning_nodes = []
|
||||||
|
@ -56,6 +63,13 @@ class ModelChecker(QObject, Extension):
|
||||||
# Check node material shrinkage and bounding box size
|
# Check node material shrinkage and bounding box size
|
||||||
for node in self.sliceableNodes():
|
for node in self.sliceableNodes():
|
||||||
node_extruder_position = node.callDecoration("getActiveExtruderPosition")
|
node_extruder_position = node.callDecoration("getActiveExtruderPosition")
|
||||||
|
|
||||||
|
# This function can be triggered in the middle of a machine change, so do not proceed if the machine change
|
||||||
|
# has not done yet.
|
||||||
|
if str(node_extruder_position) not in global_container_stack.extruders:
|
||||||
|
Application.getInstance().callLater(lambda: self.onChanged.emit())
|
||||||
|
return False
|
||||||
|
|
||||||
if material_shrinkage[node_extruder_position] > shrinkage_threshold:
|
if material_shrinkage[node_extruder_position] > shrinkage_threshold:
|
||||||
bbox = node.getBoundingBox()
|
bbox = node.getBoundingBox()
|
||||||
if bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z:
|
if bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z:
|
||||||
|
@ -63,11 +77,11 @@ class ModelChecker(QObject, Extension):
|
||||||
|
|
||||||
self._caution_message.setText(catalog.i18nc(
|
self._caution_message.setText(catalog.i18nc(
|
||||||
"@info:status",
|
"@info:status",
|
||||||
"Some models may not be printed optimally due to object size and chosen material for models: {model_names}.\n"
|
"<p>One or more 3D models may not print optimally due to the model size and material configuration:</p>\n"
|
||||||
"Tips that may be useful to improve the print quality:\n"
|
"<p>{model_names}</p>\n"
|
||||||
"1) Use rounded corners.\n"
|
"<p>Find out how to ensure the best possible print quality and reliability.</p>\n"
|
||||||
"2) Turn the fan off (only if there are no tiny details on the model).\n"
|
"<p><a href=\"https://ultimaker.com/3D-model-assistant\">View print quality guide</a></p>"
|
||||||
"3) Use a different material.").format(model_names = ", ".join([n.getName() for n in warning_nodes])))
|
).format(model_names = ", ".join([n.getName() for n in warning_nodes])))
|
||||||
|
|
||||||
return len(warning_nodes) > 0
|
return len(warning_nodes) > 0
|
||||||
|
|
||||||
|
@ -92,9 +106,8 @@ class ModelChecker(QObject, Extension):
|
||||||
Logger.log("d", "Model checker view created.")
|
Logger.log("d", "Model checker view created.")
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = onChanged)
|
@pyqtProperty(bool, notify = onChanged)
|
||||||
def runChecks(self):
|
def hasWarnings(self):
|
||||||
danger_shrinkage = self.checkObjectsForShrinkage()
|
danger_shrinkage = self.checkObjectsForShrinkage()
|
||||||
|
|
||||||
return any((danger_shrinkage, )) #If any of the checks fail, show the warning button.
|
return any((danger_shrinkage, )) #If any of the checks fail, show the warning button.
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
|
|
@ -18,7 +18,7 @@ Button
|
||||||
|
|
||||||
UM.I18nCatalog{id: catalog; name:"cura"}
|
UM.I18nCatalog{id: catalog; name:"cura"}
|
||||||
|
|
||||||
visible: manager.runChecks
|
visible: manager.hasWarnings
|
||||||
tooltip: catalog.i18nc("@info:tooltip", "Some things could be problematic in this print. Click to see tips for adjustment.")
|
tooltip: catalog.i18nc("@info:tooltip", "Some things could be problematic in this print. Click to see tips for adjustment.")
|
||||||
onClicked: manager.showWarnings()
|
onClicked: manager.showWarnings()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue