Merge branch 'master' of github.com:Ultimaker/Cura into feature_intent_per_quality

This commit is contained in:
Jaime van Kessel 2019-07-02 13:52:46 +02:00
commit be1fd2e003
10 changed files with 306 additions and 55 deletions

View File

@ -20,7 +20,6 @@ set(CURA_APP_NAME "cura" CACHE STRING "Short name of Cura, used for configuratio
set(CURA_APP_DISPLAY_NAME "Ultimaker Cura" CACHE STRING "Display name of Cura") set(CURA_APP_DISPLAY_NAME "Ultimaker Cura" CACHE STRING "Display name of Cura")
set(CURA_VERSION "master" CACHE STRING "Version name of Cura") set(CURA_VERSION "master" CACHE STRING "Version name of Cura")
set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'") set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'")
set(CURA_SDK_VERSION "" CACHE STRING "SDK version of Cura")
set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative Cura cloud API root") set(CURA_CLOUD_API_ROOT "" CACHE STRING "Alternative Cura cloud API root")
set(CURA_CLOUD_API_VERSION "" CACHE STRING "Alternative Cura cloud API version") set(CURA_CLOUD_API_VERSION "" CACHE STRING "Alternative Cura cloud API version")

View File

@ -9,7 +9,6 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura"
DEFAULT_CURA_VERSION = "master" DEFAULT_CURA_VERSION = "master"
DEFAULT_CURA_BUILD_TYPE = "" DEFAULT_CURA_BUILD_TYPE = ""
DEFAULT_CURA_DEBUG_MODE = False DEFAULT_CURA_DEBUG_MODE = False
DEFAULT_CURA_SDK_VERSION = "6.1.0"
try: try:
from cura.CuraVersion import CuraAppName # type: ignore from cura.CuraVersion import CuraAppName # type: ignore
@ -42,9 +41,4 @@ try:
except ImportError: except ImportError:
CuraDebugMode = DEFAULT_CURA_DEBUG_MODE CuraDebugMode = DEFAULT_CURA_DEBUG_MODE
try:
from cura.CuraVersion import CuraSDKVersion # type: ignore from cura.CuraVersion import CuraSDKVersion # type: ignore
if CuraSDKVersion == "":
CuraSDKVersion = DEFAULT_CURA_SDK_VERSION
except ImportError:
CuraSDKVersion = DEFAULT_CURA_SDK_VERSION

View File

@ -1,12 +1,18 @@
#Copyright (c) 2019 Ultimaker B.V.
#Cura is released under the terms of the LGPLv3 or higher.
import numpy import numpy
import copy import copy
from typing import Optional, Tuple, TYPE_CHECKING
from UM.Math.Polygon import Polygon from UM.Math.Polygon import Polygon
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
## Polygon representation as an array for use with Arrange ## Polygon representation as an array for use with Arrange
class ShapeArray: class ShapeArray:
def __init__(self, arr, offset_x, offset_y, scale = 1): def __init__(self, arr: numpy.array, offset_x: float, offset_y: float, scale: float = 1) -> None:
self.arr = arr self.arr = arr
self.offset_x = offset_x self.offset_x = offset_x
self.offset_y = offset_y self.offset_y = offset_y
@ -16,7 +22,7 @@ class ShapeArray:
# \param vertices # \param vertices
# \param scale scale the coordinates # \param scale scale the coordinates
@classmethod @classmethod
def fromPolygon(cls, vertices, scale = 1): def fromPolygon(cls, vertices: numpy.array, scale: float = 1) -> "ShapeArray":
# scale # scale
vertices = vertices * scale vertices = vertices * scale
# flip y, x -> x, y # flip y, x -> x, y
@ -42,7 +48,7 @@ class ShapeArray:
# \param min_offset offset for the offset ShapeArray # \param min_offset offset for the offset ShapeArray
# \param scale scale the coordinates # \param scale scale the coordinates
@classmethod @classmethod
def fromNode(cls, node, min_offset, scale = 0.5, include_children = False): def fromNode(cls, node: "SceneNode", min_offset: float, scale: float = 0.5, include_children: bool = False) -> Tuple[Optional["ShapeArray"], Optional["ShapeArray"]]:
transform = node._transformation transform = node._transformation
transform_x = transform._data[0][3] transform_x = transform._data[0][3]
transform_y = transform._data[2][3] transform_y = transform._data[2][3]
@ -88,7 +94,7 @@ class ShapeArray:
# \param shape numpy format shape, [x-size, y-size] # \param shape numpy format shape, [x-size, y-size]
# \param vertices # \param vertices
@classmethod @classmethod
def arrayFromPolygon(cls, shape, vertices): def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> numpy.array:
base_array = numpy.zeros(shape, dtype = numpy.int32) # Initialize your array of zeros base_array = numpy.zeros(shape, dtype = numpy.int32) # Initialize your array of zeros
fill = numpy.ones(base_array.shape) * True # Initialize boolean array defining shape fill fill = numpy.ones(base_array.shape) * True # Initialize boolean array defining shape fill
@ -111,9 +117,9 @@ class ShapeArray:
# \param p2 2-tuple with x, y for point 2 # \param p2 2-tuple with x, y for point 2
# \param base_array boolean array to project the line on # \param base_array boolean array to project the line on
@classmethod @classmethod
def _check(cls, p1, p2, base_array): def _check(cls, p1: numpy.array, p2: numpy.array, base_array: numpy.array) -> bool:
if p1[0] == p2[0] and p1[1] == p2[1]: if p1[0] == p2[0] and p1[1] == p2[1]:
return return False
idxs = numpy.indices(base_array.shape) # Create 3D array of indices idxs = numpy.indices(base_array.shape) # Create 3D array of indices
p1 = p1.astype(float) p1 = p1.astype(float)
@ -132,4 +138,3 @@ class ShapeArray:
max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1] max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1]
sign = numpy.sign(p2[0] - p1[0]) sign = numpy.sign(p2[0] - p1[0])
return idxs[1] * sign <= max_col_idx * sign return idxs[1] * sign <= max_col_idx * sign

View File

@ -787,11 +787,14 @@ class BuildVolume(SceneNode):
# where that extruder may not print. # where that extruder may not print.
def _computeDisallowedAreasPrinted(self, used_extruders): def _computeDisallowedAreasPrinted(self, used_extruders):
result = {} result = {}
adhesion_extruder = None #type: ExtruderStack
for extruder in used_extruders: for extruder in used_extruders:
if int(extruder.getProperty("extruder_nr", "value")) == int(self._global_container_stack.getProperty("adhesion_extruder_nr", "value")):
adhesion_extruder = extruder
result[extruder.getId()] = [] result[extruder.getId()] = []
# Currently, the only normally printed object is the prime tower. # Currently, the only normally printed object is the prime tower.
if self._global_container_stack.getProperty("prime_tower_enable"): if self._global_container_stack.getProperty("prime_tower_enable", "value"):
prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value") prime_tower_size = self._global_container_stack.getProperty("prime_tower_size", "value")
machine_width = self._global_container_stack.getProperty("machine_width", "value") machine_width = self._global_container_stack.getProperty("machine_width", "value")
machine_depth = self._global_container_stack.getProperty("machine_depth", "value") machine_depth = self._global_container_stack.getProperty("machine_depth", "value")
@ -801,11 +804,11 @@ class BuildVolume(SceneNode):
prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left. prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
prime_tower_y = prime_tower_y + machine_depth / 2 prime_tower_y = prime_tower_y + machine_depth / 2
if self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft": if adhesion_extruder is not None and self._global_container_stack.getProperty("prime_tower_brim_enable", "value") and self._global_container_stack.getProperty("adhesion_type", "value") != "raft":
brim_size = ( brim_size = (
extruder.getProperty("brim_line_count", "value") * adhesion_extruder.getProperty("brim_line_count", "value") *
extruder.getProperty("skirt_brim_line_width", "value") / 100.0 * adhesion_extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
extruder.getProperty("initial_layer_line_width_factor", "value") adhesion_extruder.getProperty("initial_layer_line_width_factor", "value")
) )
prime_tower_x -= brim_size prime_tower_x -= brim_size
prime_tower_y += brim_size prime_tower_y += brim_size

View File

@ -6,7 +6,9 @@ CuraAppDisplayName = "@CURA_APP_DISPLAY_NAME@"
CuraVersion = "@CURA_VERSION@" CuraVersion = "@CURA_VERSION@"
CuraBuildType = "@CURA_BUILDTYPE@" CuraBuildType = "@CURA_BUILDTYPE@"
CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False
CuraSDKVersion = "@CURA_SDK_VERSION@"
CuraSDKVersion = "6.1.0"
CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@" CuraCloudAPIRoot = "@CURA_CLOUD_API_ROOT@"
CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@" CuraCloudAPIVersion = "@CURA_CLOUD_API_VERSION@"
CuraCloudAccountAPIRoot = "@CURA_CLOUD_ACCOUNT_API_ROOT@" CuraCloudAccountAPIRoot = "@CURA_CLOUD_ACCOUNT_API_ROOT@"

View File

@ -986,8 +986,9 @@ class MachineManager(QObject):
self._application.globalContainerStackChanged.emit() self._application.globalContainerStackChanged.emit()
self.forceUpdateAllSettings() self.forceUpdateAllSettings()
# Note that this function is deprecated, but the decorators for this don't play well together!
# @deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
@pyqtSlot(int, result = QObject) @pyqtSlot(int, result = QObject)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def getExtruder(self, position: int) -> Optional[ExtruderStack]: def getExtruder(self, position: int) -> Optional[ExtruderStack]:
if self._global_container_stack: if self._global_container_stack:
return self._global_container_stack.extruders.get(str(position)) return self._global_container_stack.extruders.get(str(position))

View File

@ -963,6 +963,8 @@
"maximum_value_warning": "2 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
}
}
}, },
"initial_layer_line_width_factor": "initial_layer_line_width_factor":
{ {
@ -977,8 +979,6 @@
"settable_per_extruder": true "settable_per_extruder": true
} }
} }
}
}
}, },
"shell": "shell":
{ {
@ -2346,15 +2346,202 @@
"minimum_value_warning": "50", "minimum_value_warning": "50",
"maximum_value_warning": "150", "maximum_value_warning": "150",
"enabled": "machine_gcode_flavor != \"UltiGCode\"", "enabled": "machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": true,
"children":
{
"wall_material_flow":
{
"label": "Wall Flow",
"description": "Flow compensation on wall lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"limit_to_extruder": "wall_0_extruder_nr if wall_x_extruder_nr == wall_0_extruder_nr else -1",
"settable_per_mesh": true,
"children":
{
"wall_0_material_flow":
{
"label": "Outer Wall Flow",
"description": "Flow compensation on the outermost wall line.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "wall_material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"limit_to_extruder": "wall_0_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"wall_x_material_flow":
{
"label": "Inner Wall(s) Flow",
"description": "Flow compensation on wall lines for all wall lines except the outermost one.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "wall_material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"limit_to_extruder": "wall_x_extruder_nr",
"settable_per_mesh": true
}
}
},
"skin_material_flow":
{
"label": "Top/Bottom Flow",
"description": "Flow compensation on top/bottom lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "top_layers > 0 or bottom_layers > 0",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
},
"roofing_material_flow":
{
"label": "Top Surface Skin Flow",
"description": "Flow compensation on lines of the areas at the top of the print.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "skin_material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "roofing_layer_count > 0 and top_layers > 0"
},
"infill_material_flow":
{
"label": "Infill Flow",
"description": "Flow compensation on infill lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "infill_sparse_density > 0",
"limit_to_extruder": "infill_extruder_nr",
"settable_per_mesh": true
},
"skirt_brim_material_flow":
{
"label": "Skirt/Brim Flow",
"description": "Flow compensation on skirt or brim lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "resolveOrValue('adhesion_type') == 'skirt' or resolveOrValue('adhesion_type') == 'brim'",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"support_material_flow":
{
"label": "Support Flow",
"description": "Flow compensation on support structure lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"support_interface_material_flow":
{
"label": "Support Interface Flow",
"description": "Flow compensation on lines of support roof or floor.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "support_enable and support_interface_enable",
"limit_to_extruder": "support_interface_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
{
"support_roof_material_flow":
{
"label": "Support Roof Flow",
"description": "Flow compensation on support roof lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_material_flow')",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "support_enable and support_roof_enable",
"limit_to_extruder": "support_roof_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"support_bottom_material_flow":
{
"label": "Support Floor Flow",
"description": "Flow compensation on support floor lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_material_flow')",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "support_enable and support_bottom_enable",
"limit_to_extruder": "support_bottom_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"prime_tower_flow":
{
"label": "Prime Tower Flow",
"description": "Flow compensation on prime tower lines.",
"unit": "%",
"type": "float",
"default_value": 100,
"value": "material_flow",
"minimum_value": "5",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"material_flow_layer_0": "material_flow_layer_0":
{ {
"label": "Initial Layer Flow", "label": "Initial Layer Flow",
"description": "Flow compensation for the first layer: the amount of material extruded on the initial layer is multiplied by this value.", "description": "Flow compensation for the first layer: the amount of material extruded on the initial layer is multiplied by this value.",
"unit": "%", "unit": "%",
"default_value": 100, "default_value": 100,
"value": "material_flow",
"type": "float", "type": "float",
"minimum_value": "0.0001", "minimum_value": "0.0001",
"minimum_value_warning": "50", "minimum_value_warning": "50",
@ -5439,21 +5626,6 @@
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
}, },
"prime_tower_flow":
{
"label": "Prime Tower Flow",
"description": "Flow compensation: the amount of material extruded is multiplied by this value.",
"type": "float",
"unit": "%",
"enabled": "resolveOrValue('prime_tower_enable')",
"default_value": 100,
"value": "material_flow",
"minimum_value": "0.0001",
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"prime_tower_wipe_enabled": "prime_tower_wipe_enabled":
{ {
"label": "Wipe Inactive Nozzle on Prime Tower", "label": "Wipe Inactive Nozzle on Prime Tower",

View File

@ -24,6 +24,51 @@ Menu
MenuItem { action: Cura.Actions.viewRightSideCamera; } MenuItem { action: Cura.Actions.viewRightSideCamera; }
} }
Menu
{
id: cameraViewMenu
property string cameraMode: UM.Preferences.getValue("general/camera_perspective_mode")
Connections
{
target: UM.Preferences
onPreferenceChanged:
{
if (preference !== "general/camera_perspective_mode")
{
return
}
cameraViewMenu.cameraMode = UM.Preferences.getValue("general/camera_perspective_mode")
}
}
title: catalog.i18nc("@action:inmenu menubar:view","Camera view")
MenuItem
{
text: catalog.i18nc("@action:inmenu menubar:view", "Perspective")
checkable: true
checked: cameraViewMenu.cameraMode == "perspective"
onTriggered:
{
UM.Preferences.setValue("general/camera_perspective_mode", "perspective")
checked = cameraViewMenu.cameraMode == "perspective"
}
exclusiveGroup: group
}
MenuItem
{
text: catalog.i18nc("@action:inmenu menubar:view", "Orthographic")
checkable: true
checked: cameraViewMenu.cameraMode == "orthogonal"
onTriggered:
{
UM.Preferences.setValue("general/camera_perspective_mode", "orthogonal")
checked = cameraViewMenu.cameraMode == "orthogonal"
}
exclusiveGroup: group
}
ExclusiveGroup { id: group }
}
MenuSeparator MenuSeparator
{ {
visible: UM.Preferences.getValue("cura/use_multi_build_plate") visible: UM.Preferences.getValue("cura/use_multi_build_plate")

View File

@ -113,6 +113,18 @@ material_bed_temperature_layer_0
material_adhesion_tendency material_adhesion_tendency
material_surface_energy material_surface_energy
material_flow material_flow
wall_material_flow
wall_0_material_flow
wall_x_material_flow
skin_material_flow
roofing_material_flow
infill_material_flow
skirt_brim_material_flow
support_material_flow
support_interface_material_flow
support_roof_material_flow
support_bottom_material_flow
prime_tower_flow
material_flow_layer_0 material_flow_layer_0
retraction_enable retraction_enable
retract_at_layer_change retract_at_layer_change
@ -297,7 +309,6 @@ prime_tower_size
prime_tower_min_volume prime_tower_min_volume
prime_tower_position_x prime_tower_position_x
prime_tower_position_y prime_tower_position_y
prime_tower_flow
prime_tower_wipe_enabled prime_tower_wipe_enabled
prime_tower_brim_enable prime_tower_brim_enable
ooze_shield_enabled ooze_shield_enabled

View File

@ -1,9 +1,9 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from UM.Math.AxisAlignedBox import AxisAlignedBox
import pytest import pytest
from UM.Math.Polygon import Polygon from UM.Math.Polygon import Polygon
from UM.Settings.SettingInstance import InstanceState from UM.Math.Vector import Vector
from cura.BuildVolume import BuildVolume, PRIME_CLEARANCE from cura.BuildVolume import BuildVolume, PRIME_CLEARANCE
import numpy import numpy
@ -304,6 +304,25 @@ class TestRebuild:
build_volume.rebuild() build_volume.rebuild()
assert build_volume.getMeshData() is None assert build_volume.getMeshData() is None
def test_updateBoundingBox(self, build_volume: BuildVolume):
build_volume.setWidth(10)
build_volume.setHeight(10)
build_volume.setDepth(10)
mocked_global_stack = MagicMock()
build_volume._global_container_stack = mocked_global_stack
build_volume.getEdgeDisallowedSize = MagicMock(return_value = 0)
build_volume.updateNodeBoundaryCheck = MagicMock()
# Fake the the "engine is created callback"
build_volume._onEngineCreated()
build_volume.rebuild()
bounding_box = build_volume.getBoundingBox()
assert bounding_box.minimum == Vector(-5.0, -1.0, -5.0)
assert bounding_box.maximum == Vector(5.0, 10.0, 5.0)
class TestUpdateMachineSizeProperties: class TestUpdateMachineSizeProperties:
setting_property_dict = {"machine_width": {"value": 50}, setting_property_dict = {"machine_width": {"value": 50},
"machine_depth": {"value": 100}, "machine_depth": {"value": 100},