mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-10-10 07:17:52 -06:00
Merge branch 'master' of github.com:ultimaker/Cura into per_object_settings
* 'master' of github.com:ultimaker/Cura: (98 commits) 15.10 Restyling of the message stack Fixed machine head polygons Removed unused settings from fdmprinter Added action for togling fullscreen Fixed usage of wrong checkbox in viewpage Added preference to disable automatic push free Added preference to disable auto center when selecting object Cleanup 15.10 Restyling toolbar, viewmode button Update README.md Update README.md Added rudementary 3 point bed leveling 15.10 New font for Cura 15.10 Changes the styling for the open file button 15.10 Changes the label names for the different action buttons Fixed typo Endstop now stops listening upon destruction 15.10 Re-alignment of the messagestack Cleaned up code a bit Added heated bed check ...
This commit is contained in:
commit
f099c30dfd
66 changed files with 2608 additions and 1842 deletions
|
@ -25,20 +25,21 @@ class ConvexHullJob(Job):
|
|||
child_hull = child.callDecoration("getConvexHull")
|
||||
if child_hull:
|
||||
hull.setPoints(numpy.append(hull.getPoints(), child_hull.getPoints(), axis = 0))
|
||||
|
||||
|
||||
if hull.getPoints().size < 3:
|
||||
self._node.callDecoration("setConvexHull", None)
|
||||
self._node.callDecoration("setConvexHullJob", None)
|
||||
return
|
||||
|
||||
|
||||
else:
|
||||
if not self._node.getMeshData():
|
||||
return
|
||||
mesh = self._node.getMeshData()
|
||||
vertex_data = mesh.getTransformed(self._node.getWorldTransformation()).getVertices()
|
||||
|
||||
# Don't use data below 0. TODO; We need a better check for this as this gives poor results for meshes with long edges.
|
||||
vertex_data = vertex_data[vertex_data[:,1]>0]
|
||||
hull = Polygon(numpy.rint(vertex_data[:, [0, 2]]).astype(int))
|
||||
|
||||
|
||||
# First, calculate the normal convex hull around the points
|
||||
hull = hull.getConvexHull()
|
||||
|
||||
|
@ -57,7 +58,7 @@ class ConvexHullJob(Job):
|
|||
self._node.callDecoration("setConvexHullNode", hull_node)
|
||||
self._node.callDecoration("setConvexHull", hull)
|
||||
self._node.callDecoration("setConvexHullJob", None)
|
||||
|
||||
|
||||
if self._node.getParent().callDecoration("isGroup"):
|
||||
job = self._node.getParent().callDecoration("getConvexHullJob")
|
||||
if job:
|
||||
|
|
|
@ -33,14 +33,14 @@ class ConvexHullNode(SceneNode):
|
|||
self._hull = hull
|
||||
|
||||
hull_points = self._hull.getPoints()
|
||||
center = (hull_points.min(0) + hull_points.max(0)) / 2.0
|
||||
|
||||
mesh = MeshData()
|
||||
mesh.addVertex(center[0], 0.1, center[1])
|
||||
|
||||
if len(hull_points) > 3:
|
||||
center = (hull_points.min(0) + hull_points.max(0)) / 2.0
|
||||
mesh.addVertex(center[0], 0.1, center[1])
|
||||
else: #Hull has not enough points
|
||||
return
|
||||
for point in hull_points:
|
||||
mesh.addVertex(point[0], 0.1, point[1])
|
||||
|
||||
indices = []
|
||||
for i in range(len(hull_points) - 1):
|
||||
indices.append([0, i + 1, i + 2])
|
||||
|
|
|
@ -38,7 +38,11 @@ from . import PrintInformation
|
|||
from . import CuraActions
|
||||
from . import MultiMaterialDecorator
|
||||
|
||||
<<<<<<< HEAD
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, Qt, pyqtSignal, pyqtProperty, Q_ENUMS
|
||||
=======
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, Qt, pyqtSignal, pyqtProperty, QEvent
|
||||
>>>>>>> 3cb3cce31c821a56d2395607a90b51030fdf0916
|
||||
from PyQt5.QtGui import QColor, QIcon
|
||||
|
||||
import platform
|
||||
|
@ -84,6 +88,7 @@ class CuraApplication(QtApplication):
|
|||
self._platform_activity = False
|
||||
|
||||
self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged)
|
||||
self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity)
|
||||
|
||||
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
|
||||
Resources.addType(self.ResourceTypes.Firmware, "firmware")
|
||||
|
@ -92,6 +97,7 @@ class CuraApplication(QtApplication):
|
|||
Preferences.getInstance().addPreference("cura/active_mode", "simple")
|
||||
Preferences.getInstance().addPreference("cura/recent_files", "")
|
||||
Preferences.getInstance().addPreference("cura/categories_expanded", "")
|
||||
Preferences.getInstance().addPreference("view/center_on_select", True)
|
||||
|
||||
JobQueue.getInstance().jobFinished.connect(self._onJobFinished)
|
||||
|
||||
|
@ -123,6 +129,11 @@ class CuraApplication(QtApplication):
|
|||
def run(self):
|
||||
self._i18n_catalog = i18nCatalog("cura");
|
||||
|
||||
i18nCatalog.setTagReplacements({
|
||||
"filename": "font color=\"black\"",
|
||||
"message": "font color=UM.Theme.colors.message_text;",
|
||||
})
|
||||
|
||||
self.showSplashMessage(self._i18n_catalog.i18nc("Splash screen message", "Setting up scene..."))
|
||||
|
||||
controller = self.getController()
|
||||
|
@ -133,7 +144,7 @@ class CuraApplication(QtApplication):
|
|||
|
||||
t = controller.getTool("TranslateTool")
|
||||
if t:
|
||||
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.ZAxis])
|
||||
t.setEnabledAxis([ToolHandle.XAxis, ToolHandle.YAxis,ToolHandle.ZAxis])
|
||||
|
||||
Selection.selectionChanged.connect(self.onSelectionChanged)
|
||||
|
||||
|
@ -181,12 +192,17 @@ class CuraApplication(QtApplication):
|
|||
self.closeSplash()
|
||||
|
||||
for file in self.getCommandLineOption("file", []):
|
||||
job = ReadMeshJob(os.path.abspath(file))
|
||||
job.finished.connect(self._onFileLoaded)
|
||||
job.start()
|
||||
self._openFile(file)
|
||||
|
||||
self.exec_()
|
||||
|
||||
# Handle Qt events
|
||||
def event(self, event):
|
||||
if event.type() == QEvent.FileOpen:
|
||||
self._openFile(event.file())
|
||||
|
||||
return super().event(event)
|
||||
|
||||
def registerObjects(self, engine):
|
||||
engine.rootContext().setContextProperty("Printer", self)
|
||||
self._print_information = PrintInformation.PrintInformation()
|
||||
|
@ -202,10 +218,10 @@ class CuraApplication(QtApplication):
|
|||
self._previous_active_tool = None
|
||||
else:
|
||||
self.getController().setActiveTool("TranslateTool")
|
||||
|
||||
self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin())
|
||||
self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
|
||||
self._camera_animation.start()
|
||||
if Preferences.getInstance().getValue("view/center_on_select"):
|
||||
self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin())
|
||||
self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
|
||||
self._camera_animation.start()
|
||||
else:
|
||||
if self.getController().getActiveTool():
|
||||
self._previous_active_tool = self.getController().getActiveTool().getPluginId()
|
||||
|
@ -220,24 +236,15 @@ class CuraApplication(QtApplication):
|
|||
def getPlatformActivity(self):
|
||||
return self._platform_activity
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def setPlatformActivity(self, activity):
|
||||
##Sets the _platform_activity variable on true or false depending on whether there is a mesh on the platform
|
||||
if activity == True:
|
||||
self._platform_activity = activity
|
||||
elif activity == False:
|
||||
nodes = []
|
||||
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
|
||||
if type(node) is not SceneNode or not node.getMeshData():
|
||||
continue
|
||||
nodes.append(node)
|
||||
i = 0
|
||||
for node in nodes:
|
||||
if not node.getMeshData():
|
||||
continue
|
||||
i += 1
|
||||
if i <= 1: ## i == 0 when the meshes are removed using the deleteAll function; i == 1 when the last remaining mesh is removed using the deleteObject function
|
||||
self._platform_activity = activity
|
||||
def updatePlatformActivity(self, node = None):
|
||||
count = 0
|
||||
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
|
||||
if type(node) is not SceneNode or not node.getMeshData():
|
||||
continue
|
||||
|
||||
count += 1
|
||||
|
||||
self._platform_activity = True if count > 0 else False
|
||||
self.activityChanged.emit()
|
||||
|
||||
## Remove an object from the scene
|
||||
|
@ -258,8 +265,7 @@ class CuraApplication(QtApplication):
|
|||
group_node = group_node.getParent()
|
||||
op = RemoveSceneNodeOperation(group_node)
|
||||
op.push()
|
||||
self.setPlatformActivity(False)
|
||||
|
||||
|
||||
## Create a number of copies of existing object.
|
||||
@pyqtSlot("quint64", int)
|
||||
def multiplyObject(self, object_id, count):
|
||||
|
@ -306,8 +312,7 @@ class CuraApplication(QtApplication):
|
|||
op.addOperation(RemoveSceneNodeOperation(node))
|
||||
|
||||
op.push()
|
||||
self.setPlatformActivity(False)
|
||||
|
||||
|
||||
## Reset all translation on nodes with mesh data.
|
||||
@pyqtSlot()
|
||||
def resetAllTranslation(self):
|
||||
|
@ -490,12 +495,9 @@ class CuraApplication(QtApplication):
|
|||
self._platform.setPosition(Vector(0.0, 0.0, 0.0))
|
||||
|
||||
def _onFileLoaded(self, job):
|
||||
mesh = job.getResult()
|
||||
if mesh != None:
|
||||
node = SceneNode()
|
||||
|
||||
node = job.getResult()
|
||||
if node != None:
|
||||
node.setSelectable(True)
|
||||
node.setMeshData(mesh)
|
||||
node.setName(os.path.basename(job.getFileName()))
|
||||
|
||||
op = AddSceneNodeOperation(node, self.getController().getScene().getRoot())
|
||||
|
@ -521,4 +523,10 @@ class CuraApplication(QtApplication):
|
|||
self.recentFilesChanged.emit()
|
||||
|
||||
def _reloadMeshFinished(self, job):
|
||||
job._node.setMeshData(job.getResult())
|
||||
job._node = job.getResult()
|
||||
|
||||
def _openFile(self, file):
|
||||
job = ReadMeshJob(os.path.abspath(file))
|
||||
job.finished.connect(self._onFileLoaded)
|
||||
job.start()
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ from UM.Math.Vector import Vector
|
|||
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
||||
from UM.Application import Application
|
||||
from UM.Scene.Selection import Selection
|
||||
from UM.Preferences import Preferences
|
||||
|
||||
from cura.ConvexHullDecorator import ConvexHullDecorator
|
||||
|
||||
from . import PlatformPhysicsOperation
|
||||
|
@ -19,6 +21,7 @@ from . import ConvexHullJob
|
|||
|
||||
import time
|
||||
import threading
|
||||
import copy
|
||||
|
||||
class PlatformPhysics:
|
||||
def __init__(self, controller, volume):
|
||||
|
@ -36,6 +39,8 @@ class PlatformPhysics:
|
|||
self._change_timer.setSingleShot(True)
|
||||
self._change_timer.timeout.connect(self._onChangeTimerFinished)
|
||||
|
||||
Preferences.getInstance().addPreference("physics/automatic_push_free", True)
|
||||
|
||||
def _onSceneChanged(self, source):
|
||||
self._change_timer.start()
|
||||
|
||||
|
@ -53,16 +58,21 @@ class PlatformPhysics:
|
|||
self._change_timer.start()
|
||||
continue
|
||||
|
||||
build_volume_bounding_box = copy.deepcopy(self._build_volume.getBoundingBox())
|
||||
build_volume_bounding_box.setBottom(-9001) # Ignore intersections with the bottom
|
||||
|
||||
# Mark the node as outside the build volume if the bounding box test fails.
|
||||
if self._build_volume.getBoundingBox().intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
|
||||
if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
|
||||
node._outside_buildarea = True
|
||||
else:
|
||||
node._outside_buildarea = False
|
||||
|
||||
# Move the node upwards if the bottom is below the build platform.
|
||||
# Move it downwards if bottom is above platform
|
||||
move_vector = Vector()
|
||||
if not Float.fuzzyCompare(bbox.bottom, 0.0):
|
||||
if bbox.bottom > 0:
|
||||
move_vector.setY(-bbox.bottom)
|
||||
#if not Float.fuzzyCompare(bbox.bottom, 0.0):
|
||||
# pass#move_vector.setY(-bbox.bottom)
|
||||
|
||||
# If there is no convex hull for the node, start calculating it and continue.
|
||||
if not node.getDecorator(ConvexHullDecorator):
|
||||
|
@ -76,7 +86,7 @@ class PlatformPhysics:
|
|||
|
||||
elif Selection.isSelected(node):
|
||||
pass
|
||||
else:
|
||||
elif Preferences.getInstance().getValue("physics/automatic_push_free"):
|
||||
# Check for collisions between convex hulls
|
||||
for other_node in BreadthFirstIterator(root):
|
||||
# Ignore root, ourselves and anything that is not a normal SceneNode.
|
||||
|
@ -107,8 +117,10 @@ class PlatformPhysics:
|
|||
|
||||
move_vector.setX(overlap[0] * 1.1)
|
||||
move_vector.setZ(overlap[1] * 1.1)
|
||||
convex_hull = node.callDecoration("getConvexHull")
|
||||
convex_hull = node.callDecoration("getConvexHull")
|
||||
if convex_hull:
|
||||
if not convex_hull.isValid():
|
||||
return
|
||||
# Check for collisions between disallowed areas and the object
|
||||
for area in self._build_volume.getDisallowedAreas():
|
||||
overlap = convex_hull.intersectsPolygon(area)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue