Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNino van Hooff <ninovanhooff@gmail.com>2019-11-01 12:51:21 +0300
committerNino van Hooff <ninovanhooff@gmail.com>2019-11-01 12:51:21 +0300
commit94d291a20c3e5e9bd84d3476cd8844bd9bf8930c (patch)
treed322550e0a12c0661fec06bfa1b1e573b732c94b /plugins
parent888c3f51a5718c80f9b3736aa86e5953e1c4ed8d (diff)
parent71fe01d7f20b76a79ff7b259b97fe13a4afa98c2 (diff)
Merge branch 'master' into CURA-6854_align_layer_label_top_bottom
# Conflicts: # plugins/SimulationView/SimulationViewMainComponent.qml
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ImageReader/ConfigUI.qml46
-rw-r--r--plugins/ImageReader/ImageReader.py25
-rw-r--r--plugins/ImageReader/ImageReaderUI.py11
-rw-r--r--plugins/PreviewStage/PreviewMain.qml23
-rw-r--r--plugins/SimulationView/PathSlider.qml5
-rw-r--r--plugins/SimulationView/SimulationViewMainComponent.qml23
6 files changed, 112 insertions, 21 deletions
diff --git a/plugins/ImageReader/ConfigUI.qml b/plugins/ImageReader/ConfigUI.qml
index 47ba10778c..0429fae4e1 100644
--- a/plugins/ImageReader/ConfigUI.qml
+++ b/plugins/ImageReader/ConfigUI.qml
@@ -146,6 +146,52 @@ UM.Dialog
UM.TooltipArea {
Layout.fillWidth:true
height: childrenRect.height
+ text: catalog.i18nc("@info:tooltip","For lithophanes a simple logarithmic model for translucency is available. For height maps the pixel values correspond to heights linearly.")
+ Row {
+ width: parent.width
+
+ Label {
+ text: "Color Model"
+ width: 150 * screenScaleFactor
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ ComboBox {
+ id: color_model
+ objectName: "ColorModel"
+ model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ]
+ width: 180 * screenScaleFactor
+ onCurrentIndexChanged: { manager.onColorModelChanged(currentIndex) }
+ }
+ }
+ }
+
+ UM.TooltipArea {
+ Layout.fillWidth:true
+ height: childrenRect.height
+ text: catalog.i18nc("@info:tooltip","The percentage of light penetrating a print with a thickness of 1 millimeter. Lowering this value increases the contrast in dark regions and decreases the contrast in light regions of the image.")
+ visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency")
+ Row {
+ width: parent.width
+
+ Label {
+ text: catalog.i18nc("@action:label", "1mm Transmittance (%)")
+ width: 150 * screenScaleFactor
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ TextField {
+ id: transmittance
+ objectName: "Transmittance"
+ focus: true
+ validator: RegExpValidator {regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/}
+ width: 180 * screenScaleFactor
+ onTextChanged: { manager.onTransmittanceChanged(text) }
+ }
+ }
+ }
+
+ UM.TooltipArea {
+ Layout.fillWidth:true
+ height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The amount of smoothing to apply to the image.")
Row {
width: parent.width
diff --git a/plugins/ImageReader/ImageReader.py b/plugins/ImageReader/ImageReader.py
index e720ce4854..d6c2827d16 100644
--- a/plugins/ImageReader/ImageReader.py
+++ b/plugins/ImageReader/ImageReader.py
@@ -3,6 +3,8 @@
import numpy
+import math
+
from PyQt5.QtGui import QImage, qRed, qGreen, qBlue
from PyQt5.QtCore import Qt
@@ -46,9 +48,9 @@ class ImageReader(MeshReader):
def _read(self, file_name):
size = max(self._ui.getWidth(), self._ui.getDepth())
- return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher)
+ return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher, self._ui.use_transparency_model, self._ui.transmittance_1mm)
- def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher):
+ def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher, use_transparency_model, transmittance_1mm):
scene_node = SceneNode()
mesh = MeshBuilder()
@@ -99,12 +101,14 @@ class ImageReader(MeshReader):
for x in range(0, width):
for y in range(0, height):
qrgb = img.pixel(x, y)
- avg = float(qRed(qrgb) + qGreen(qrgb) + qBlue(qrgb)) / (3 * 255)
- height_data[y, x] = avg
+ if use_transparency_model:
+ height_data[y, x] = (0.299 * math.pow(qRed(qrgb) / 255.0, 2.2) + 0.587 * math.pow(qGreen(qrgb) / 255.0, 2.2) + 0.114 * math.pow(qBlue(qrgb) / 255.0, 2.2))
+ else:
+ height_data[y, x] = (0.212655 * qRed(qrgb) + 0.715158 * qGreen(qrgb) + 0.072187 * qBlue(qrgb)) / 255 # fast computation ignoring gamma and degamma
Job.yieldThread()
- if not lighter_is_higher:
+ if lighter_is_higher == use_transparency_model:
height_data = 1 - height_data
for _ in range(0, blur_iterations):
@@ -124,8 +128,15 @@ class ImageReader(MeshReader):
Job.yieldThread()
- height_data *= scale_vector.y
- height_data += base_height
+ if use_transparency_model:
+ divisor = 1.0 / math.log(transmittance_1mm / 100.0) # log-base doesn't matter here. Precompute this value for faster computation of each pixel.
+ min_luminance = (transmittance_1mm / 100.0) ** (peak_height - base_height)
+ for (y, x) in numpy.ndindex(height_data.shape):
+ mapped_luminance = min_luminance + (1.0 - min_luminance) * height_data[y, x]
+ height_data[y, x] = base_height + divisor * math.log(mapped_luminance) # use same base as a couple lines above this
+ else:
+ height_data *= scale_vector.y
+ height_data += base_height
heightmap_face_count = 2 * height_minus_one * width_minus_one
total_face_count = heightmap_face_count + (width_minus_one * 2) * (height_minus_one * 2) + 2
diff --git a/plugins/ImageReader/ImageReaderUI.py b/plugins/ImageReader/ImageReaderUI.py
index 213468a2ab..a61fabb742 100644
--- a/plugins/ImageReader/ImageReaderUI.py
+++ b/plugins/ImageReader/ImageReaderUI.py
@@ -34,6 +34,8 @@ class ImageReaderUI(QObject):
self.peak_height = 2.5
self.smoothing = 1
self.lighter_is_higher = False;
+ self.use_transparency_model = True;
+ self.transmittance_1mm = 50.0; # based on pearl PLA
self._ui_lock = threading.Lock()
self._cancelled = False
@@ -75,6 +77,7 @@ class ImageReaderUI(QObject):
self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height))
self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height))
+ self._ui_view.findChild(QObject, "Transmittance").setProperty("text", str(self.transmittance_1mm))
self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing)
def _createConfigUI(self):
@@ -144,3 +147,11 @@ class ImageReaderUI(QObject):
@pyqtSlot(int)
def onImageColorInvertChanged(self, value):
self.lighter_is_higher = (value == 1)
+
+ @pyqtSlot(int)
+ def onColorModelChanged(self, value):
+ self.use_transparency_model = (value == 0)
+
+ @pyqtSlot(int)
+ def onTransmittanceChanged(self, value):
+ self.transmittance_1mm = value
diff --git a/plugins/PreviewStage/PreviewMain.qml b/plugins/PreviewStage/PreviewMain.qml
index 4ef10e5dbb..2926f0d012 100644
--- a/plugins/PreviewStage/PreviewMain.qml
+++ b/plugins/PreviewStage/PreviewMain.qml
@@ -12,14 +12,18 @@ import Cura 1.0 as Cura
Item
{
+ // An Item whose bounds are guaranteed to be safe for overlays to be placed.
+ // Defaults to parent, ie. the entire available area
+ property var safeArea: parent
+
// Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it
- Item {
- id: safeArea
- visible: false
- anchors.left: parent.left
- anchors.right: actionPanelWidget.left
- anchors.top: parent.top
- anchors.bottom: actionPanelWidget.top
+ Item
+ {
+ id: childSafeArea
+ x: safeArea.x - parent.x
+ y: safeArea.y - parent.y
+ width: actionPanelWidget.x - x
+ height: actionPanelWidget.y - y
}
Loader
@@ -29,9 +33,10 @@ Item
source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : ""
- onLoaded: {
+ onLoaded:
+ {
if (previewMain.item.safeArea !== undefined){
- previewMain.item.safeArea = Qt.binding(function() { return safeArea });
+ previewMain.item.safeArea = Qt.binding(function() { return childSafeArea });
}
}
}
diff --git a/plugins/SimulationView/PathSlider.qml b/plugins/SimulationView/PathSlider.qml
index c7a43c6407..facdbb6a53 100644
--- a/plugins/SimulationView/PathSlider.qml
+++ b/plugins/SimulationView/PathSlider.qml
@@ -56,6 +56,11 @@ Item
return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
}
+ onWidthChanged : {
+ // After a width change, the pixel-position of the handle is out of sync with the property value
+ setHandleValue(handleValue)
+ }
+
// slider track
Rectangle
{
diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml
index 8d32e50654..bfd8799673 100644
--- a/plugins/SimulationView/SimulationViewMainComponent.qml
+++ b/plugins/SimulationView/SimulationViewMainComponent.qml
@@ -18,7 +18,10 @@ Item
property bool isSimulationPlaying: false
- readonly property var layerSliderSafeYMax: safeArea.y + safeArea.height
+ readonly property real layerSliderSafeYMin: safeArea.y
+ readonly property real layerSliderSafeYMax: safeArea.y + safeArea.height
+ readonly property real pathSliderSafeXMin: safeArea.x + playButton.width
+ readonly property real pathSliderSafeXMax: safeArea.x + safeArea.width
visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
@@ -26,13 +29,21 @@ Item
PathSlider
{
id: pathSlider
+
+ readonly property real preferredWidth: UM.Theme.getSize("slider_layerview_size").height // not a typo, should be as long as layerview slider
+ readonly property real margin: UM.Theme.getSize("default_margin").width
+ readonly property real pathSliderSafeWidth: pathSliderSafeXMax - pathSliderSafeXMin
+
height: UM.Theme.getSize("slider_handle").width
- width: UM.Theme.getSize("slider_layerview_size").height
+ width: preferredWidth + margin * 2 < pathSliderSafeWidth ? preferredWidth : pathSliderSafeWidth - margin * 2
+
anchors.bottom: parent.bottom
- anchors.bottomMargin: UM.Theme.getSize("default_margin").height
+ anchors.bottomMargin: margin
anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: -(parent.width - pathSliderSafeXMax - pathSliderSafeXMin) / 2 // center between parent top and layerSliderSafeYMax
+
visible: !UM.SimulationView.compatibilityMode
@@ -184,16 +195,18 @@ Item
{
property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
property double heightMargin: UM.Theme.getSize("default_margin").height * 3 // extra margin to accomodate layer number tooltips
+ property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
+
id: layerSlider
width: UM.Theme.getSize("slider_handle").width
- height: preferredHeight + heightMargin * 2 < layerSliderSafeYMax ? preferredHeight : layerSliderSafeYMax - heightMargin * 2
+ height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
anchors
{
right: parent.right
verticalCenter: parent.verticalCenter
- verticalCenterOffset: -(parent.height - layerSliderSafeYMax) / 2 // center between parent top and layerSliderSafeYMax
+ verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
rightMargin: UM.Theme.getSize("default_margin").width
bottomMargin: heightMargin
topMargin: heightMargin