resolve merge conflict

This commit is contained in:
Mark 2018-04-17 10:39:35 +02:00
commit f61efb8e20
7 changed files with 61 additions and 46 deletions

View file

@ -501,11 +501,6 @@ class CuraApplication(QtApplication):
def getStaticVersion(cls):
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)
# \sa PluginRegistry
def _loadPlugins(self):

34
cura/Utils/Threading.py Normal file
View 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

View file

@ -7,6 +7,7 @@ import os
import threading
from typing import List, Tuple
import xml.etree.ElementTree as ET
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.CuraContainerStack import _ContainerIndexes
from cura.CuraApplication import CuraApplication
from cura.Utils.Threading import call_on_qt_thread
from .WorkspaceDialog import WorkspaceDialog
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:
def __init__(self, file_name: str, serialized: str, parser: ConfigParser):
self.file_name = file_name

View file

@ -6,16 +6,18 @@ from io import StringIO
import zipfile
from UM.Application import Application
from UM.Logger import Logger
from UM.Preferences import Preferences
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Workspace.WorkspaceWriter import WorkspaceWriter
from cura.Utils.Threading import call_on_qt_thread
class ThreeMFWorkspaceWriter(WorkspaceWriter):
def __init__(self):
super().__init__()
@call_on_qt_thread
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
application = Application.getInstance()
machine_manager = application.getMachineManager()

View file

@ -121,7 +121,7 @@ class CuraEngineBackend(QObject, Backend):
self._slice_start_time = None
self._is_disabled = False
Preferences.getInstance().addPreference("general/auto_slice", True)
Preferences.getInstance().addPreference("general/auto_slice", False)
self._use_timer = False
# When you update a setting and other settings get changed through inheritance, many propertyChanged signals are fired.

View file

@ -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_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()
warning_nodes = []
@ -56,6 +63,13 @@ class ModelChecker(QObject, Extension):
# Check node material shrinkage and bounding box size
for node in self.sliceableNodes():
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:
bbox = node.getBoundingBox()
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(
"@info:status",
"Some models may not be printed optimally due to object size and chosen material for models: {model_names}.\n"
"Tips that may be useful to improve the print quality:\n"
"1) Use rounded corners.\n"
"2) Turn the fan off (only if there are no tiny details on the model).\n"
"3) Use a different material.").format(model_names = ", ".join([n.getName() for n in warning_nodes])))
"<p>One or more 3D models may not print optimally due to the model size and material configuration:</p>\n"
"<p>{model_names}</p>\n"
"<p>Find out how to ensure the best possible print quality and reliability.</p>\n"
"<p><a href=\"https://ultimaker.com/3D-model-assistant\">View print quality guide</a></p>"
).format(model_names = ", ".join([n.getName() for n in warning_nodes])))
return len(warning_nodes) > 0
@ -92,9 +106,8 @@ class ModelChecker(QObject, Extension):
Logger.log("d", "Model checker view created.")
@pyqtProperty(bool, notify = onChanged)
def runChecks(self):
def hasWarnings(self):
danger_shrinkage = self.checkObjectsForShrinkage()
return any((danger_shrinkage, )) #If any of the checks fail, show the warning button.
@pyqtSlot()

View file

@ -18,7 +18,7 @@ Button
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.")
onClicked: manager.showWarnings()