mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 13:34:01 -06:00
Merge branch '2.3' of github.com:Ultimaker/Cura
This commit is contained in:
commit
5577ff03f6
8 changed files with 90 additions and 20 deletions
|
@ -67,6 +67,9 @@ class BuildVolume(SceneNode):
|
|||
self._disallowed_areas = []
|
||||
self._disallowed_area_mesh = None
|
||||
|
||||
self._prime_tower_area = None
|
||||
self._prime_tower_area_mesh = None
|
||||
|
||||
self.setCalculateBoundingBox(False)
|
||||
self._volume_aabb = None
|
||||
|
||||
|
@ -82,6 +85,8 @@ class BuildVolume(SceneNode):
|
|||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
|
||||
self._onActiveExtruderStackChanged()
|
||||
|
||||
self._has_errors = False
|
||||
|
||||
def setWidth(self, width):
|
||||
if width: self._width = width
|
||||
|
||||
|
@ -110,6 +115,10 @@ class BuildVolume(SceneNode):
|
|||
if self._disallowed_area_mesh:
|
||||
renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)
|
||||
|
||||
if self._prime_tower_area_mesh:
|
||||
renderer.queueNode(self, mesh = self._prime_tower_area_mesh, shader = self._shader, transparent=True,
|
||||
backface_cull=True, sort=-8)
|
||||
|
||||
return True
|
||||
|
||||
## Recalculates the build volume & disallowed areas.
|
||||
|
@ -184,6 +193,24 @@ class BuildVolume(SceneNode):
|
|||
else:
|
||||
self._disallowed_area_mesh = None
|
||||
|
||||
if self._prime_tower_area:
|
||||
mb = MeshBuilder()
|
||||
color = Color(1.0, 0.0, 0.0, 0.5)
|
||||
points = self._prime_tower_area.getPoints()
|
||||
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
|
||||
self._clamp(points[0][1], min_d, max_d))
|
||||
previous_point = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
|
||||
self._clamp(points[0][1], min_d, max_d))
|
||||
for point in points:
|
||||
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
|
||||
|
||||
self._prime_tower_area_mesh = mb.build()
|
||||
else:
|
||||
self._prime_tower_area_mesh = None
|
||||
|
||||
self._volume_aabb = AxisAlignedBox(
|
||||
minimum = Vector(min_w, min_h - 1.0, min_d),
|
||||
maximum = Vector(max_w, max_h - self._raft_thickness, max_d))
|
||||
|
@ -291,24 +318,34 @@ class BuildVolume(SceneNode):
|
|||
if rebuild_me:
|
||||
self.rebuild()
|
||||
|
||||
def hasErrors(self):
|
||||
return self._has_errors
|
||||
|
||||
def _updateDisallowedAreas(self):
|
||||
if not self._global_container_stack:
|
||||
return
|
||||
|
||||
self._has_errors = False # Reset.
|
||||
disallowed_areas = copy.deepcopy(
|
||||
self._global_container_stack.getProperty("machine_disallowed_areas", "value"))
|
||||
areas = []
|
||||
|
||||
machine_width = self._global_container_stack.getProperty("machine_width", "value")
|
||||
machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
|
||||
|
||||
self._prime_tower_area = None
|
||||
# Add prime tower location as disallowed area.
|
||||
if self._global_container_stack.getProperty("prime_tower_enable", "value") == True:
|
||||
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
|
||||
prime_tower_x = self._global_container_stack.getProperty("prime_tower_position_x", "value") - machine_width / 2
|
||||
prime_tower_y = - self._global_container_stack.getProperty("prime_tower_position_y", "value") + machine_depth / 2
|
||||
|
||||
disallowed_areas.append([
|
||||
'''disallowed_areas.append([
|
||||
[prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
|
||||
[prime_tower_x, prime_tower_y - prime_tower_size],
|
||||
[prime_tower_x, prime_tower_y],
|
||||
[prime_tower_x - prime_tower_size, prime_tower_y],
|
||||
])'''
|
||||
|
||||
self._prime_tower_area = Polygon([
|
||||
[prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
|
||||
[prime_tower_x, prime_tower_y - prime_tower_size],
|
||||
[prime_tower_x, prime_tower_y],
|
||||
|
@ -344,6 +381,9 @@ class BuildVolume(SceneNode):
|
|||
|
||||
areas.append(poly)
|
||||
|
||||
if self._prime_tower_area:
|
||||
self._prime_tower_area = self._prime_tower_area.getMinkowskiHull(Polygon(approximatedCircleVertices(bed_adhesion_size)))
|
||||
|
||||
# Add the skirt areas around the borders of the build plate.
|
||||
if bed_adhesion_size > 0:
|
||||
half_machine_width = self._global_container_stack.getProperty("machine_width", "value") / 2
|
||||
|
@ -377,6 +417,19 @@ class BuildVolume(SceneNode):
|
|||
[half_machine_width - bed_adhesion_size, -half_machine_depth + bed_adhesion_size]
|
||||
], numpy.float32)))
|
||||
|
||||
# Check if the prime tower area intersects with any of the other areas.
|
||||
# If this is the case, keep the polygon seperate, so it can be drawn in red.
|
||||
# If not, add it back to disallowed area's, so it's rendered as normal.
|
||||
collision = False
|
||||
if self._prime_tower_area:
|
||||
for area in areas:
|
||||
if self._prime_tower_area.intersectsPolygon(area) is not None:
|
||||
collision = True
|
||||
break
|
||||
if not collision:
|
||||
areas.append(self._prime_tower_area)
|
||||
self._prime_tower_area = None
|
||||
self._has_errors = collision
|
||||
self._disallowed_areas = areas
|
||||
|
||||
## Convenience function to calculate the size of the bed adhesion in directions x, y.
|
||||
|
|
|
@ -693,17 +693,17 @@ class CuraApplication(QtApplication):
|
|||
continue # Node that doesnt have a mesh and is not a group.
|
||||
if node.getParent() and node.getParent().callDecoration("isGroup"):
|
||||
continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
|
||||
|
||||
nodes.append(node)
|
||||
|
||||
if nodes:
|
||||
op = GroupedOperation()
|
||||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0)))
|
||||
op.push()
|
||||
|
||||
## Reset all transformations on nodes with mesh data.
|
||||
|
||||
## Reset all transformations on nodes with mesh data.
|
||||
@pyqtSlot()
|
||||
def resetAll(self):
|
||||
Logger.log("i", "Resetting all scene transformations")
|
||||
|
@ -719,15 +719,17 @@ class CuraApplication(QtApplication):
|
|||
|
||||
if nodes:
|
||||
op = GroupedOperation()
|
||||
|
||||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, node.getMeshData().getCenterPosition().y, 0), Quaternion(), Vector(1, 1, 1)))
|
||||
|
||||
center_y = 0
|
||||
if node.callDecoration("isGroup"):
|
||||
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
|
||||
else:
|
||||
center_y = node.getMeshData().getCenterPosition().y
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1)))
|
||||
op.push()
|
||||
|
||||
|
||||
## Reload all mesh data on the screen from file.
|
||||
@pyqtSlot()
|
||||
def reloadAll(self):
|
||||
|
|
|
@ -78,6 +78,10 @@ class StartSliceJob(Job):
|
|||
self.setResult(StartJobResult.SettingError)
|
||||
return
|
||||
|
||||
if Application.getInstance().getBuildVolume().hasErrors():
|
||||
self.setResult(StartJobResult.SettingError)
|
||||
return
|
||||
|
||||
# Don't slice if there is a per object setting with an error value.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
if type(node) is not SceneNode or not node.isSelectable():
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
import configparser
|
||||
|
||||
|
@ -53,10 +53,10 @@ class CuraProfileReader(ProfileReader):
|
|||
parser.read_string(serialized)
|
||||
|
||||
if not "general" in parser:
|
||||
Logger.log('w', "Missing required section 'general'.")
|
||||
Logger.log("w", "Missing required section 'general'.")
|
||||
return None
|
||||
if not "version" in parser["general"]:
|
||||
Logger.log('w', "Missing required 'version' property")
|
||||
Logger.log("w", "Missing required 'version' property")
|
||||
return None
|
||||
|
||||
version = int(parser["general"]["version"])
|
||||
|
|
|
@ -7,6 +7,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
|||
from UM.Application import Application
|
||||
from UM.Preferences import Preferences
|
||||
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
|
||||
|
||||
## This tool allows the user to add & change settings per node in the scene.
|
||||
|
@ -71,11 +72,17 @@ class PerObjectSettingsTool(Tool):
|
|||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
self._multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1
|
||||
|
||||
# Ensure that all extruder data is reset
|
||||
if not self._multi_extrusion:
|
||||
# Ensure that all extruder data is reset
|
||||
root_node = Application.getInstance().getController().getScene().getRoot()
|
||||
for node in DepthFirstIterator(root_node):
|
||||
node.callDecoration("setActiveExtruder", global_container_stack.getId())
|
||||
default_stack_id = global_container_stack.getId()
|
||||
else:
|
||||
default_stack_id = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||
|
||||
root_node = Application.getInstance().getController().getScene().getRoot()
|
||||
for node in DepthFirstIterator(root_node):
|
||||
node.callDecoration("setActiveExtruder", default_stack_id)
|
||||
|
||||
self._updateEnabled()
|
||||
|
||||
def _updateEnabled(self):
|
||||
|
|
|
@ -31,7 +31,7 @@ class UMOUpgradeSelection(MachineAction):
|
|||
if variant:
|
||||
if variant.getId() == "empty_variant":
|
||||
variant_index = global_container_stack.getContainerIndex(variant)
|
||||
self._createVariant(global_container_stack, variant_index)
|
||||
variant = self._createVariant(global_container_stack, variant_index)
|
||||
variant.setProperty("machine_heated_bed", "value", heated_bed)
|
||||
self.heatedBedChanged.emit()
|
||||
|
||||
|
@ -41,4 +41,5 @@ class UMOUpgradeSelection(MachineAction):
|
|||
new_variant.addMetaDataEntry("type", "variant")
|
||||
new_variant.setDefinition(global_container_stack.getBottom())
|
||||
UM.Settings.ContainerRegistry.getInstance().addContainer(new_variant)
|
||||
global_container_stack.replaceContainer(variant_index, new_variant)
|
||||
global_container_stack.replaceContainer(variant_index, new_variant)
|
||||
return new_variant
|
|
@ -10,6 +10,7 @@
|
|||
"manufacturer": "Ultimaker",
|
||||
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
|
||||
"visible": false,
|
||||
"has_materials": true,
|
||||
"preferred_material": "*generic_pla*",
|
||||
"preferred_quality": "*normal*",
|
||||
"machine_extruder_trains":
|
||||
|
@ -3297,6 +3298,7 @@
|
|||
"default_value": 15,
|
||||
"value": "15 if prime_tower_enable else 0",
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
|
||||
"maximum_value_warning": "20",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2backplate.png",
|
||||
"platform_offset": [9, 0, 0],
|
||||
"has_materials": false,
|
||||
"supported_actions":["UpgradeFirmware"]
|
||||
},
|
||||
"overrides": {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue