Update documentation & code cleanup

This commit is contained in:
Jaime van Kessel 2016-04-08 14:26:28 +02:00
parent 4c233e75f4
commit 97d16ae3bd
7 changed files with 63 additions and 51 deletions

View file

@ -15,6 +15,8 @@ from UM.View.GL.OpenGL import OpenGL
import numpy
## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas.
class BuildVolume(SceneNode):
VolumeOutlineColor = Color(12, 169, 227, 255)
@ -72,6 +74,7 @@ class BuildVolume(SceneNode):
renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)
return True
## Recalculates the build volume & disallowed areas.
def rebuild(self):
if self._width == 0 or self._height == 0 or self._depth == 0:
return
@ -127,9 +130,10 @@ class BuildVolume(SceneNode):
new_point = Vector(self._clamp(point[0], min_w, max_w), disallowed_area_height, self._clamp(point[1], min_d, max_d))
mb.addFace(first, previous_point, new_point, color = color)
previous_point = new_point
# Find the largest disallowed area to exclude it from the maximum scale bounds.
# This is a very nasty hack. This pretty much only works for UM machines. This disallowed area_size needs
# A -lot- of rework at some point in the future: TODO
# This is a very nasty hack. This pretty much only works for UM machines.
# This disallowed area_size needs a -lot- of rework at some point in the future: TODO
if numpy.min(points[:, 1]) >= 0: # This filters out all areas that have points to the left of the centre. This is done to filter the skirt area.
size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
else:
@ -148,7 +152,7 @@ class BuildVolume(SceneNode):
if profile:
skirt_size = self._getSkirtSize(profile)
# As this works better for UM machines, we only add the dissallowed_area_size for the z direction.
# As this works better for UM machines, we only add the disallowed_area_size for the z direction.
# This is probably wrong in all other cases. TODO!
# The +1 and -1 is added as there is always a bit of extra room required to work properly.
scale_to_max_bounds = AxisAlignedBox(
@ -194,8 +198,6 @@ class BuildVolume(SceneNode):
self._updateDisallowedAreas()
self.rebuild()
def _updateDisallowedAreas(self):
if not self._active_instance or not self._active_profile:
return
@ -224,7 +226,7 @@ class BuildVolume(SceneNode):
areas.append(poly)
# Add the skirt areas arround the borders of the build plate.
# Add the skirt areas around the borders of the build plate.
if skirt_size > 0:
half_machine_width = self._active_instance.getMachineSettingValue("machine_width") / 2
half_machine_depth = self._active_instance.getMachineSettingValue("machine_depth") / 2
@ -259,6 +261,7 @@ class BuildVolume(SceneNode):
self._disallowed_areas = areas
## Convenience function to calculate the size of the bed adhesion.
def _getSkirtSize(self, profile):
skirt_size = 0.0

View file

@ -1,17 +1,24 @@
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
from UM.Application import Application
## The convex hull decorator is a scene node decorator that adds the convex hull functionality to a scene node.
# If a scene node has a convex hull decorator, it will have a shadow in which other objects can not be printed.
class ConvexHullDecorator(SceneNodeDecorator):
def __init__(self):
super().__init__()
self._convex_hull = None
# In case of printing all at once this is the same as the convex hull. For one at the time this is the area without the head.
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is the area without the head.
self._convex_hull_boundary = None
# In case of printing all at once this is the same as the convex hull. For one at the time this is area with intersection of mirrored head
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is area with intersection of mirrored head
self._convex_hull_head = None
# In case of printing all at once this is the same as the convex hull. For one at the time this is area with intersection of full head
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is area with intersection of full head
self._convex_hull_head_full = None
self._convex_hull_node = None
@ -27,19 +34,27 @@ class ConvexHullDecorator(SceneNodeDecorator):
copy = ConvexHullDecorator()
return copy
## Get the unmodified convex hull of the node
def getConvexHull(self):
return self._convex_hull
## Get the convex hull of the node with the full head size
def getConvexHullHeadFull(self):
if not self._convex_hull_head_full:
return self.getConvexHull()
return self._convex_hull_head_full
## Get convex hull of the object + head size
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is area with intersection of mirrored head
def getConvexHullHead(self):
if not self._convex_hull_head:
return self.getConvexHull()
return self._convex_hull_head
## Get convex hull of the node
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is the area without the head.
def getConvexHullBoundary(self):
if not self._convex_hull_boundary:
return self.getConvexHull()

View file

@ -9,6 +9,7 @@ import numpy
import copy
from . import ConvexHullNode
## Job to async calculate the convex hull of a node.
class ConvexHullJob(Job):
def __init__(self, node):
super().__init__()
@ -38,7 +39,8 @@ class ConvexHullJob(Job):
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.
# 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))
@ -55,6 +57,7 @@ class ConvexHullJob(Job):
# Printing one at a time and it's not an object in a group
self._node.callDecoration("setConvexHullBoundary", copy.deepcopy(hull))
head_and_fans = Polygon(numpy.array(profile.getSettingValue("machine_head_with_fans_polygon"), numpy.float32))
# Full head hull is used to actually check the order.
full_head_hull = hull.getMinkowskiHull(head_and_fans)
self._node.callDecoration("setConvexHullHeadFull", full_head_hull)
@ -62,17 +65,19 @@ class ConvexHullJob(Job):
mirrored.mirror([0, 0], [0, 1]) #Mirror horizontally.
mirrored.mirror([0, 0], [1, 0]) #Mirror vertically.
head_and_fans = head_and_fans.intersectionConvexHulls(mirrored)
# Min head hull is used for the push free
min_head_hull = hull.getMinkowskiHull(head_and_fans)
self._node.callDecoration("setConvexHullHead", min_head_hull)
hull = hull.getMinkowskiHull(Polygon(numpy.array(profile.getSettingValue("machine_head_polygon"),numpy.float32)))
else:
self._node.callDecoration("setConvexHullHead", None)
if self._node.getParent() is None: #Node was already deleted before job is done.
if self._node.getParent() is None: # Node was already deleted before job is done.
self._node.callDecoration("setConvexHullNode",None)
self._node.callDecoration("setConvexHull", None)
self._node.callDecoration("setConvexHullJob", None)
return
hull_node = ConvexHullNode.ConvexHullNode(self._node, hull, Application.getInstance().getController().getScene().getRoot())
self._node.callDecoration("setConvexHullNode", hull_node)
self._node.callDecoration("setConvexHull", hull)

View file

@ -5,11 +5,15 @@ from UM.Scene.SceneNode import SceneNode
from UM.Resources import Resources
from UM.Math.Color import Color
from UM.Math.Vector import Vector
from UM.Mesh.MeshBuilder import MeshBuilder #To create a mesh to display the convex hull with.
from UM.Mesh.MeshBuilder import MeshBuilder # To create a mesh to display the convex hull with.
from UM.View.GL.OpenGL import OpenGL
class ConvexHullNode(SceneNode):
## Convex hull node is a special type of scene node that is used to display a 2D area, to indicate the
# location an object uses on the buildplate. This area (or area's in case of one at a time printing) is
# then displayed as a transparent shadow.
def __init__(self, node, hull, parent = None):
super().__init__(parent)
@ -22,18 +26,22 @@ class ConvexHullNode(SceneNode):
self._inherit_orientation = False
self._inherit_scale = False
# Color of the drawn convex hull
self._color = Color(35, 35, 35, 128)
self._mesh_height = 0.1 #The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
# The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
self._mesh_height = 0.1
# The node this mesh is "watching"
self._node = node
self._node.transformationChanged.connect(self._onNodePositionChanged)
self._node.parentChanged.connect(self._onNodeParentChanged)
self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
self._onNodeDecoratorsChanged(self._node)
self._convex_hull_head_mesh = None
self._hull = hull
hull_points = self._hull.getPoints() # TODO: @UnusedVariable
hull_mesh = self.createHullMesh(self._hull.getPoints())
if hull_mesh:
self.setMeshData(hull_mesh)
@ -41,18 +49,21 @@ class ConvexHullNode(SceneNode):
if convex_hull_head:
self._convex_hull_head_mesh = self.createHullMesh(convex_hull_head.getPoints())
## Actually create the mesh from the hullpoints
# /param hull_points list of xy values
# /return meshData
def createHullMesh(self, hull_points):
#Input checking.
# Input checking.
if len(hull_points) < 3:
return None
mesh_builder = MeshBuilder()
point_first = Vector(hull_points[0][0], self._mesh_height, hull_points[0][1])
point_previous = Vector(hull_points[1][0], self._mesh_height, hull_points[1][1])
for point in hull_points[2:]: #Add the faces in the order of a triangle fan.
for point in hull_points[2:]: # Add the faces in the order of a triangle fan.
point_new = Vector(point[0], self._mesh_height, point[1])
mesh_builder.addFace(point_first, point_previous, point_new, color = self._color)
point_previous = point_new #Prepare point_previous for the next triangle.
point_previous = point_new # Prepare point_previous for the next triangle.
return mesh_builder.getData()
@ -75,7 +86,7 @@ class ConvexHullNode(SceneNode):
if node.callDecoration("getConvexHull"):
node.callDecoration("setConvexHull", None)
node.callDecoration("setConvexHullNode", None)
self.setParent(None)
self.setParent(None) # Garbage collection should delete this node after a while.
def _onNodeParentChanged(self, node):
if node.getParent():

View file

@ -4,6 +4,7 @@ from PyQt5.QtGui import QDesktopServices
from UM.Event import CallFunctionEvent
from UM.Application import Application
class CuraActions(QObject):
def __init__(self, parent = None):
super().__init__(parent)

View file

@ -56,7 +56,8 @@ if platform.system() == "Linux": # Needed for platform.linux_distribution, which
try:
from cura.CuraVersion import CuraVersion
except ImportError:
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
class CuraApplication(QtApplication):
class ResourceTypes:
@ -69,7 +70,7 @@ class CuraApplication(QtApplication):
if not hasattr(sys, "frozen"):
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), ".."))
self._open_file_queue = [] #Files to open when plug-ins are loaded.
self._open_file_queue = [] # Files to open when plug-ins are loaded.
super().__init__(name = "cura", version = CuraVersion)
@ -96,6 +97,8 @@ class CuraApplication(QtApplication):
self._scene_boundingbox = AxisAlignedBox()
self._job_name = None
self._center_after_select = False
self._camera_animation = None
self._cura_actions = None
self.getMachineManager().activeMachineInstanceChanged.connect(self._onActiveMachineChanged)
self.getMachineManager().addMachineRequested.connect(self._onAddMachineRequested)
@ -205,7 +208,7 @@ class CuraApplication(QtApplication):
self.exec_()
# Handle Qt events
## Handle Qt events
def event(self, event):
if event.type() == QEvent.FileOpen:
if self._plugins_loaded:
@ -215,6 +218,7 @@ class CuraApplication(QtApplication):
return super().event(event)
## Get print information (duration / material used)
def getPrintInformation(self):
return self._print_information
@ -585,30 +589,7 @@ class CuraApplication(QtApplication):
return CuraSplashScreen.CuraSplashScreen()
def _onActiveMachineChanged(self):
machine = self.getMachineManager().getActiveMachineInstance()
if machine:
pass
#Preferences.getInstance().setValue("cura/active_machine", machine.getName())
#self._volume.setWidth(machine.getSettingValueByKey("machine_width"))
#self._volume.setHeight(machine.getSettingValueByKey("machine_height"))
#self._volume.setDepth(machine.getSettingValueByKey("machine_depth"))
#disallowed_areas = machine.getSettingValueByKey("machine_disallowed_areas")
#areas = []
#if disallowed_areas:
#for area in disallowed_areas:
#areas.append(Polygon(numpy.array(area, numpy.float32)))
#self._volume.setDisallowedAreas(areas)
#self._volume.rebuild()
#offset = machine.getSettingValueByKey("machine_platform_offset")
#if offset:
#self._platform.setPosition(Vector(offset[0], offset[1], offset[2]))
#else:
#self._platform.setPosition(Vector(0.0, 0.0, 0.0))
pass
def _onFileLoaded(self, job):
node = job.getResult()

View file

@ -1,4 +0,0 @@
# Copyright (c) 2015 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
CuraVersion = "@CURA_VERSION@"