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_VERSION "master" CACHE STRING "Version name of Cura")
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_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_BUILD_TYPE = ""
DEFAULT_CURA_DEBUG_MODE = False
DEFAULT_CURA_SDK_VERSION = "6.1.0"
try:
from cura.CuraVersion import CuraAppName # type: ignore
@ -42,9 +41,4 @@ try:
except ImportError:
CuraDebugMode = DEFAULT_CURA_DEBUG_MODE
try:
from cura.CuraVersion import CuraSDKVersion # type: ignore
if CuraSDKVersion == "":
CuraSDKVersion = DEFAULT_CURA_SDK_VERSION
except ImportError:
CuraSDKVersion = DEFAULT_CURA_SDK_VERSION
from cura.CuraVersion import CuraSDKVersion # type: ignore

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 copy
from typing import Optional, Tuple, TYPE_CHECKING
from UM.Math.Polygon import Polygon
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
## Polygon representation as an array for use with Arrange
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.offset_x = offset_x
self.offset_y = offset_y
@ -16,7 +22,7 @@ class ShapeArray:
# \param vertices
# \param scale scale the coordinates
@classmethod
def fromPolygon(cls, vertices, scale = 1):
def fromPolygon(cls, vertices: numpy.array, scale: float = 1) -> "ShapeArray":
# scale
vertices = vertices * scale
# flip y, x -> x, y
@ -42,7 +48,7 @@ class ShapeArray:
# \param min_offset offset for the offset ShapeArray
# \param scale scale the coordinates
@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_x = transform._data[0][3]
transform_y = transform._data[2][3]
@ -88,7 +94,7 @@ class ShapeArray:
# \param shape numpy format shape, [x-size, y-size]
# \param vertices
@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
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 base_array boolean array to project the line on
@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]:
return
return False
idxs = numpy.indices(base_array.shape) # Create 3D array of indices
p1 = p1.astype(float)
@ -131,5 +137,4 @@ class ShapeArray:
max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1]
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.
def _computeDisallowedAreasPrinted(self, used_extruders):
result = {}
adhesion_extruder = None #type: ExtruderStack
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()] = []
# 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")
machine_width = self._global_container_stack.getProperty("machine_width", "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_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 = (
extruder.getProperty("brim_line_count", "value") *
extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
extruder.getProperty("initial_layer_line_width_factor", "value")
adhesion_extruder.getProperty("brim_line_count", "value") *
adhesion_extruder.getProperty("skirt_brim_line_width", "value") / 100.0 *
adhesion_extruder.getProperty("initial_layer_line_width_factor", "value")
)
prime_tower_x -= brim_size
prime_tower_y += brim_size

View file

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

View file

@ -986,8 +986,9 @@ class MachineManager(QObject):
self._application.globalContainerStackChanged.emit()
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)
@deprecated("use Cura.MachineManager.activeMachine.extruders instead", "4.2")
def getExtruder(self, position: int) -> Optional[ExtruderStack]:
if self._global_container_stack:
return self._global_container_stack.extruders.get(str(position))

View file

@ -963,20 +963,20 @@
"maximum_value_warning": "2 * machine_nozzle_size",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"initial_layer_line_width_factor":
{
"label": "Initial Layer Line Width",
"description": "Multiplier of the line width on the first layer. Increasing this could improve bed adhesion.",
"type": "float",
"unit": "%",
"default_value": 100.0,
"minimum_value": "0.001",
"maximum_value_warning": "150",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"initial_layer_line_width_factor":
{
"label": "Initial Layer Line Width",
"description": "Multiplier of the line width on the first layer. Increasing this could improve bed adhesion.",
"type": "float",
"unit": "%",
"default_value": 100.0,
"minimum_value": "0.001",
"maximum_value_warning": "150",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
@ -2346,7 +2346,195 @@
"minimum_value_warning": "50",
"maximum_value_warning": "150",
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": true
"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
},
"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":
{
@ -2354,7 +2542,6 @@
"description": "Flow compensation for the first layer: the amount of material extruded on the initial layer is multiplied by this value.",
"unit": "%",
"default_value": 100,
"value": "material_flow",
"type": "float",
"minimum_value": "0.0001",
"minimum_value_warning": "50",
@ -5439,21 +5626,6 @@
"settable_per_mesh": 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":
{
"label": "Wipe Inactive Nozzle on Prime Tower",

View file

@ -24,6 +24,51 @@ Menu
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
{
visible: UM.Preferences.getValue("cura/use_multi_build_plate")

View file

@ -113,6 +113,18 @@ material_bed_temperature_layer_0
material_adhesion_tendency
material_surface_energy
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
retraction_enable
retract_at_layer_change
@ -297,7 +309,6 @@ prime_tower_size
prime_tower_min_volume
prime_tower_position_x
prime_tower_position_y
prime_tower_flow
prime_tower_wipe_enabled
prime_tower_brim_enable
ooze_shield_enabled

View file

@ -1,9 +1,9 @@
from unittest.mock import MagicMock, patch
from UM.Math.AxisAlignedBox import AxisAlignedBox
import pytest
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
import numpy
@ -304,6 +304,25 @@ class TestRebuild:
build_volume.rebuild()
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:
setting_property_dict = {"machine_width": {"value": 50},
"machine_depth": {"value": 100},