mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-15 02:16:01 +08:00
Merge branch 'master' into feature_headless_docker
This commit is contained in:
commit
3246480111
@ -409,6 +409,14 @@ class CuraApplication(QtApplication):
|
|||||||
else:
|
else:
|
||||||
self.exit(0)
|
self.exit(0)
|
||||||
|
|
||||||
|
## Signal to connect preferences action in QML
|
||||||
|
showPreferencesWindow = pyqtSignal()
|
||||||
|
|
||||||
|
## Show the preferences window
|
||||||
|
@pyqtSlot()
|
||||||
|
def showPreferences(self):
|
||||||
|
self.showPreferencesWindow.emit()
|
||||||
|
|
||||||
## A reusable dialogbox
|
## A reusable dialogbox
|
||||||
#
|
#
|
||||||
showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"])
|
showMessageBox = pyqtSignal(str, str, str, str, int, int, arguments = ["title", "text", "informativeText", "detailedText", "buttons", "icon"])
|
||||||
@ -683,7 +691,7 @@ class CuraApplication(QtApplication):
|
|||||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||||
|
|
||||||
run_without_gui = self.getCommandLineOption("headless", False) or self.getCommandLineOption("invisible", False)
|
run_without_gui = self.getCommandLineOption("headless", False)
|
||||||
if not run_without_gui:
|
if not run_without_gui:
|
||||||
self.initializeEngine()
|
self.initializeEngine()
|
||||||
controller.setActiveStage("PrepareStage")
|
controller.setActiveStage("PrepareStage")
|
||||||
|
@ -76,7 +76,8 @@ class PlatformPhysics:
|
|||||||
if not node.getDecorator(ConvexHullDecorator):
|
if not node.getDecorator(ConvexHullDecorator):
|
||||||
node.addDecorator(ConvexHullDecorator())
|
node.addDecorator(ConvexHullDecorator())
|
||||||
|
|
||||||
if Preferences.getInstance().getValue("physics/automatic_push_free"):
|
# only push away objects if this node is a printing mesh
|
||||||
|
if not node.callDecoration("isNonPrintingMesh") and Preferences.getInstance().getValue("physics/automatic_push_free"):
|
||||||
# Check for collisions between convex hulls
|
# Check for collisions between convex hulls
|
||||||
for other_node in BreadthFirstIterator(root):
|
for other_node in BreadthFirstIterator(root):
|
||||||
# Ignore root, ourselves and anything that is not a normal SceneNode.
|
# Ignore root, ourselves and anything that is not a normal SceneNode.
|
||||||
@ -98,6 +99,9 @@ class PlatformPhysics:
|
|||||||
if other_node in transformed_nodes:
|
if other_node in transformed_nodes:
|
||||||
continue # Other node is already moving, wait for next pass.
|
continue # Other node is already moving, wait for next pass.
|
||||||
|
|
||||||
|
if other_node.callDecoration("isNonPrintingMesh"):
|
||||||
|
continue
|
||||||
|
|
||||||
overlap = (0, 0) # Start loop with no overlap
|
overlap = (0, 0) # Start loop with no overlap
|
||||||
current_overlap_checks = 0
|
current_overlap_checks = 0
|
||||||
# Continue to check the overlap until we no longer find one.
|
# Continue to check the overlap until we no longer find one.
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
|
from PyQt5.QtGui import QOpenGLContext
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
@ -13,6 +14,7 @@ from UM.Logger import Logger
|
|||||||
from UM.Math.Color import Color
|
from UM.Math.Color import Color
|
||||||
from UM.Mesh.MeshBuilder import MeshBuilder
|
from UM.Mesh.MeshBuilder import MeshBuilder
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
|
from UM.Platform import Platform
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
from UM.Resources import Resources
|
from UM.Resources import Resources
|
||||||
@ -24,6 +26,7 @@ from UM.View.GL.OpenGLContext import OpenGLContext
|
|||||||
from UM.View.View import View
|
from UM.View.View import View
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
from cura.ConvexHullNode import ConvexHullNode
|
from cura.ConvexHullNode import ConvexHullNode
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from .NozzleNode import NozzleNode
|
from .NozzleNode import NozzleNode
|
||||||
from .SimulationPass import SimulationPass
|
from .SimulationPass import SimulationPass
|
||||||
@ -414,6 +417,23 @@ class SimulationView(View):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
if event.type == Event.ViewActivateEvent:
|
if event.type == Event.ViewActivateEvent:
|
||||||
|
# FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
|
||||||
|
# This can happen when you do the following steps:
|
||||||
|
# 1. Start Cura
|
||||||
|
# 2. Load a model
|
||||||
|
# 3. Switch to Custom mode
|
||||||
|
# 4. Select the model and click on the per-object tool icon
|
||||||
|
# 5. Switch view to Layer view or X-Ray
|
||||||
|
# 6. Cura will very likely crash
|
||||||
|
# It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why.
|
||||||
|
# This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL
|
||||||
|
# context is None.
|
||||||
|
if Platform.isOSX():
|
||||||
|
if QOpenGLContext.currentContext() is None:
|
||||||
|
Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later")
|
||||||
|
CuraApplication.getInstance().callLater(lambda e=event: self.event(e))
|
||||||
|
return
|
||||||
|
|
||||||
# Make sure the SimulationPass is created
|
# Make sure the SimulationPass is created
|
||||||
layer_pass = self.getSimulationPass()
|
layer_pass = self.getSimulationPass()
|
||||||
self.getRenderer().addRenderPass(layer_pass)
|
self.getRenderer().addRenderPass(layer_pass)
|
||||||
|
@ -39,19 +39,26 @@ class SliceInfo(Extension):
|
|||||||
Preferences.getInstance().addPreference("info/send_slice_info", True)
|
Preferences.getInstance().addPreference("info/send_slice_info", True)
|
||||||
Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
|
Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
|
||||||
|
|
||||||
if not Preferences.getInstance().getValue("info/asked_send_slice_info") and Preferences.getInstance().getValue("info/send_slice_info"):
|
if not Preferences.getInstance().getValue("info/asked_send_slice_info"):
|
||||||
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in the preferences."),
|
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymized usage statistics."),
|
||||||
lifetime = 0,
|
lifetime = 0,
|
||||||
dismissable = False,
|
dismissable = False,
|
||||||
title = catalog.i18nc("@info:title", "Collecting Data"))
|
title = catalog.i18nc("@info:title", "Collecting Data"))
|
||||||
|
|
||||||
self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "")
|
self.send_slice_info_message.addAction("Dismiss", name = catalog.i18nc("@action:button", "Allow"), icon = None,
|
||||||
|
description = catalog.i18nc("@action:tooltip", "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."))
|
||||||
|
self.send_slice_info_message.addAction("Disable", name = catalog.i18nc("@action:button", "Disable"), icon = None,
|
||||||
|
description = catalog.i18nc("@action:tooltip", "Don't allow Cura to send anonymized usage statistics. You can enable it again in the preferences."), button_style = Message.ActionButtonStyle.LINK)
|
||||||
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
||||||
self.send_slice_info_message.show()
|
self.send_slice_info_message.show()
|
||||||
|
|
||||||
|
## Perform action based on user input.
|
||||||
|
# Note that clicking "Disable" won't actually disable the data sending, but rather take the user to preferences where they can disable it.
|
||||||
def messageActionTriggered(self, message_id, action_id):
|
def messageActionTriggered(self, message_id, action_id):
|
||||||
self.send_slice_info_message.hide()
|
|
||||||
Preferences.getInstance().setValue("info/asked_send_slice_info", True)
|
Preferences.getInstance().setValue("info/asked_send_slice_info", True)
|
||||||
|
if action_id == "Disable":
|
||||||
|
CuraApplication.getInstance().showPreferences()
|
||||||
|
self.send_slice_info_message.hide()
|
||||||
|
|
||||||
def _onWriteStarted(self, output_device):
|
def _onWriteStarted(self, output_device):
|
||||||
try:
|
try:
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
from PyQt5.QtGui import QOpenGLContext
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
from UM.Logger import Logger
|
||||||
from UM.Math.Color import Color
|
from UM.Math.Color import Color
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
|
from UM.Platform import Platform
|
||||||
from UM.Event import Event
|
from UM.Event import Event
|
||||||
from UM.View.View import View
|
from UM.View.View import View
|
||||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
||||||
@ -13,6 +16,8 @@ from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
|||||||
from UM.View.RenderBatch import RenderBatch
|
from UM.View.RenderBatch import RenderBatch
|
||||||
from UM.View.GL.OpenGL import OpenGL
|
from UM.View.GL.OpenGL import OpenGL
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from . import XRayPass
|
from . import XRayPass
|
||||||
|
|
||||||
## View used to display a see-through version of objects with errors highlighted.
|
## View used to display a see-through version of objects with errors highlighted.
|
||||||
@ -52,6 +57,23 @@ class XRayView(View):
|
|||||||
|
|
||||||
def event(self, event):
|
def event(self, event):
|
||||||
if event.type == Event.ViewActivateEvent:
|
if event.type == Event.ViewActivateEvent:
|
||||||
|
# FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
|
||||||
|
# This can happen when you do the following steps:
|
||||||
|
# 1. Start Cura
|
||||||
|
# 2. Load a model
|
||||||
|
# 3. Switch to Custom mode
|
||||||
|
# 4. Select the model and click on the per-object tool icon
|
||||||
|
# 5. Switch view to Layer view or X-Ray
|
||||||
|
# 6. Cura will very likely crash
|
||||||
|
# It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why.
|
||||||
|
# This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL
|
||||||
|
# context is None.
|
||||||
|
if Platform.isOSX():
|
||||||
|
if QOpenGLContext.currentContext() is None:
|
||||||
|
Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later")
|
||||||
|
CuraApplication.getInstance().callLater(lambda e = event: self.event(e))
|
||||||
|
return
|
||||||
|
|
||||||
if not self._xray_pass:
|
if not self._xray_pass:
|
||||||
# Currently the RenderPass constructor requires a size > 0
|
# Currently the RenderPass constructor requires a size > 0
|
||||||
# This should be fixed in RenderPass's constructor.
|
# This should be fixed in RenderPass's constructor.
|
||||||
|
@ -528,6 +528,12 @@ UM.MainWindow
|
|||||||
onTriggered: preferences.visible = true
|
onTriggered: preferences.visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: CuraApplication
|
||||||
|
onShowPreferencesWindow: preferences.visible = true
|
||||||
|
}
|
||||||
|
|
||||||
MessageDialog
|
MessageDialog
|
||||||
{
|
{
|
||||||
id: newProjectDialog
|
id: newProjectDialog
|
||||||
|
Loading…
x
Reference in New Issue
Block a user