mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-17 22:26:41 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
8ca6b87e17
@ -6,6 +6,9 @@ include(GNUInstallDirs)
|
|||||||
|
|
||||||
set(URANIUM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/../uranium/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository")
|
set(URANIUM_SCRIPTS_DIR "${CMAKE_SOURCE_DIR}/../uranium/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository")
|
||||||
|
|
||||||
|
set(CURA_VERSION "master" CACHE STRING "Version name of Cura")
|
||||||
|
configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY)
|
||||||
|
|
||||||
if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
|
if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
|
||||||
# Extract Strings
|
# Extract Strings
|
||||||
add_custom_target(extract-messages ${URANIUM_SCRIPTS_DIR}/extract-messages ${CMAKE_SOURCE_DIR} cura)
|
add_custom_target(extract-messages ${URANIUM_SCRIPTS_DIR}/extract-messages ${CMAKE_SOURCE_DIR} cura)
|
||||||
@ -60,10 +63,12 @@ install(DIRECTORY resources DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
|
|||||||
install(DIRECTORY plugins DESTINATION lib/cura)
|
install(DIRECTORY plugins DESTINATION lib/cura)
|
||||||
install(FILES cura_app.py DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
install(FILES cura_app.py DESTINATION ${CMAKE_INSTALL_BINDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||||
if(NOT APPLE AND NOT WIN32)
|
if(NOT APPLE AND NOT WIN32)
|
||||||
install(DIRECTORY cura DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages)
|
install(DIRECTORY cura DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages FILES_MATCHING PATTERN *.py)
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py DESTINATION lib/python${PYTHON_VERSION_MAJOR}/dist-packages/cura)
|
||||||
install(FILES cura.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
install(FILES cura.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||||
else()
|
else()
|
||||||
install(DIRECTORY cura DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
|
install(DIRECTORY cura DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages FILES_MATCHING PATTERN *.py)
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/CuraVersion.py DESTINATION lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages/cura)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CPackConfig.cmake)
|
include(CPackConfig.cmake)
|
||||||
|
@ -34,10 +34,14 @@ class BuildVolume(SceneNode):
|
|||||||
|
|
||||||
self.setCalculateBoundingBox(False)
|
self.setCalculateBoundingBox(False)
|
||||||
|
|
||||||
|
self._active_profile = None
|
||||||
self._active_instance = None
|
self._active_instance = None
|
||||||
Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveInstanceChanged)
|
Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onActiveInstanceChanged)
|
||||||
self._onActiveInstanceChanged()
|
self._onActiveInstanceChanged()
|
||||||
|
|
||||||
|
Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged)
|
||||||
|
self._onActiveProfileChanged()
|
||||||
|
|
||||||
def setWidth(self, width):
|
def setWidth(self, width):
|
||||||
if width: self._width = width
|
if width: self._width = width
|
||||||
|
|
||||||
@ -72,7 +76,7 @@ class BuildVolume(SceneNode):
|
|||||||
renderer.queueNode(self, material = self._material, mode = Renderer.RenderLines)
|
renderer.queueNode(self, material = self._material, mode = Renderer.RenderLines)
|
||||||
renderer.queueNode(self, mesh = self._grid_mesh, material = self._grid_material, force_single_sided = True)
|
renderer.queueNode(self, mesh = self._grid_mesh, material = self._grid_material, force_single_sided = True)
|
||||||
if self._disallowed_area_mesh:
|
if self._disallowed_area_mesh:
|
||||||
renderer.queueNode(self, mesh = self._disallowed_area_mesh, material = self._material)
|
renderer.queueNode(self, mesh = self._disallowed_area_mesh, material = self._material, transparent = True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def rebuild(self):
|
def rebuild(self):
|
||||||
@ -117,18 +121,20 @@ class BuildVolume(SceneNode):
|
|||||||
v = self._grid_mesh.getVertex(n)
|
v = self._grid_mesh.getVertex(n)
|
||||||
self._grid_mesh.setVertexUVCoordinates(n, v[0], v[2])
|
self._grid_mesh.setVertexUVCoordinates(n, v[0], v[2])
|
||||||
|
|
||||||
|
disallowed_area_height = 0.2
|
||||||
disallowed_area_size = 0
|
disallowed_area_size = 0
|
||||||
if self._disallowed_areas:
|
if self._disallowed_areas:
|
||||||
mb = MeshBuilder()
|
mb = MeshBuilder()
|
||||||
|
color = Color(0.0, 0.0, 0.0, 0.15)
|
||||||
for polygon in self._disallowed_areas:
|
for polygon in self._disallowed_areas:
|
||||||
points = polygon.getPoints()
|
points = polygon.getPoints()
|
||||||
mb.addQuad(
|
first = Vector(self._clamp(points[0][0], minW, maxW), disallowed_area_height, self._clamp(points[0][1], minD, maxD))
|
||||||
Vector(points[0, 0], 0.1, points[0, 1]),
|
previous_point = Vector(self._clamp(points[0][0], minW, maxW), disallowed_area_height, self._clamp(points[0][1], minD, maxD))
|
||||||
Vector(points[1, 0], 0.1, points[1, 1]),
|
for point in points:
|
||||||
Vector(points[2, 0], 0.1, points[2, 1]),
|
new_point = Vector(self._clamp(point[0], minW, maxW), disallowed_area_height, self._clamp(point[1], minD, maxD))
|
||||||
Vector(points[3, 0], 0.1, points[3, 1]),
|
mb.addFace(first, previous_point, new_point, color = color)
|
||||||
color = Color(174, 174, 174, 255)
|
previous_point = new_point
|
||||||
)
|
|
||||||
# Find the largest disallowed area to exclude it from the maximum scale bounds
|
# Find the largest disallowed area to exclude it from the maximum scale bounds
|
||||||
size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
|
size = abs(numpy.max(points[:, 1]) - numpy.min(points[:, 1]))
|
||||||
disallowed_area_size = max(size, disallowed_area_size)
|
disallowed_area_size = max(size, disallowed_area_size)
|
||||||
@ -141,16 +147,9 @@ class BuildVolume(SceneNode):
|
|||||||
|
|
||||||
skirt_size = 0.0
|
skirt_size = 0.0
|
||||||
|
|
||||||
#profile = Application.getInstance().getMachineManager().getActiveProfile()
|
profile = Application.getInstance().getMachineManager().getActiveProfile()
|
||||||
#if profile:
|
if profile:
|
||||||
#if profile.getSettingValue("adhesion_type") == "skirt":
|
skirt_size = self._getSkirtSize(profile)
|
||||||
#skirt_size = profile.getSettingValue("skirt_line_count") * profile.getSettingValue("skirt_line_width") + profile.getSettingValue("skirt_gap")
|
|
||||||
#elif profile.getSettingValue("adhesion_type") == "brim":
|
|
||||||
#skirt_size = profile.getSettingValue("brim_line_count") * profile.getSettingValue("skirt_line_width")
|
|
||||||
#else:
|
|
||||||
#skirt_size = profile.getSettingValue("skirt_line_width")
|
|
||||||
|
|
||||||
#skirt_size += profile.getSettingValue("skirt_line_width")
|
|
||||||
|
|
||||||
scale_to_max_bounds = AxisAlignedBox(
|
scale_to_max_bounds = AxisAlignedBox(
|
||||||
minimum = Vector(minW + skirt_size, minH, minD + skirt_size + disallowed_area_size),
|
minimum = Vector(minW + skirt_size, minH, minD + skirt_size + disallowed_area_size),
|
||||||
@ -167,12 +166,108 @@ class BuildVolume(SceneNode):
|
|||||||
self._height = self._active_instance.getMachineSettingValue("machine_height")
|
self._height = self._active_instance.getMachineSettingValue("machine_height")
|
||||||
self._depth = self._active_instance.getMachineSettingValue("machine_depth")
|
self._depth = self._active_instance.getMachineSettingValue("machine_depth")
|
||||||
|
|
||||||
disallowed_areas = self._active_instance.getMachineSettingValue("machine_disallowed_areas")
|
self._updateDisallowedAreas()
|
||||||
areas = []
|
|
||||||
if disallowed_areas:
|
|
||||||
for area in disallowed_areas:
|
|
||||||
areas.append(Polygon(numpy.array(area, numpy.float32)))
|
|
||||||
|
|
||||||
self._disallowed_areas = areas
|
|
||||||
|
|
||||||
self.rebuild()
|
self.rebuild()
|
||||||
|
|
||||||
|
def _onActiveProfileChanged(self):
|
||||||
|
if self._active_profile:
|
||||||
|
self._active_profile.settingValueChanged.disconnect(self._onSettingValueChanged)
|
||||||
|
|
||||||
|
self._active_profile = Application.getInstance().getMachineManager().getActiveProfile()
|
||||||
|
if self._active_profile:
|
||||||
|
self._active_profile.settingValueChanged.connect(self._onSettingValueChanged)
|
||||||
|
self._updateDisallowedAreas()
|
||||||
|
self.rebuild()
|
||||||
|
|
||||||
|
def _onSettingValueChanged(self, setting):
|
||||||
|
if setting in self._skirt_settings:
|
||||||
|
self._updateDisallowedAreas()
|
||||||
|
self.rebuild()
|
||||||
|
|
||||||
|
def _updateDisallowedAreas(self):
|
||||||
|
if not self._active_instance or not self._active_profile:
|
||||||
|
return
|
||||||
|
|
||||||
|
disallowed_areas = self._active_instance.getMachineSettingValue("machine_disallowed_areas")
|
||||||
|
areas = []
|
||||||
|
|
||||||
|
skirt_size = 0.0
|
||||||
|
if self._active_profile:
|
||||||
|
skirt_size = self._getSkirtSize(self._active_profile)
|
||||||
|
|
||||||
|
if disallowed_areas:
|
||||||
|
for area in disallowed_areas:
|
||||||
|
poly = Polygon(numpy.array(area, numpy.float32))
|
||||||
|
poly = poly.getMinkowskiHull(Polygon(numpy.array([
|
||||||
|
[-skirt_size, 0],
|
||||||
|
[-skirt_size * 0.707, skirt_size * 0.707],
|
||||||
|
[0, skirt_size],
|
||||||
|
[skirt_size * 0.707, skirt_size * 0.707],
|
||||||
|
[skirt_size, 0],
|
||||||
|
[skirt_size * 0.707, -skirt_size * 0.707],
|
||||||
|
[0, -skirt_size],
|
||||||
|
[-skirt_size * 0.707, -skirt_size * 0.707]
|
||||||
|
], numpy.float32)))
|
||||||
|
|
||||||
|
areas.append(poly)
|
||||||
|
|
||||||
|
if skirt_size > 0:
|
||||||
|
half_machine_width = self._active_instance.getMachineSettingValue("machine_width") / 2
|
||||||
|
half_machine_depth = self._active_instance.getMachineSettingValue("machine_depth") / 2
|
||||||
|
|
||||||
|
areas.append(Polygon(numpy.array([
|
||||||
|
[-half_machine_width, -half_machine_depth],
|
||||||
|
[-half_machine_width, half_machine_depth],
|
||||||
|
[-half_machine_width + skirt_size, half_machine_depth - skirt_size],
|
||||||
|
[-half_machine_width + skirt_size, -half_machine_depth + skirt_size]
|
||||||
|
], numpy.float32)))
|
||||||
|
|
||||||
|
areas.append(Polygon(numpy.array([
|
||||||
|
[half_machine_width, half_machine_depth],
|
||||||
|
[half_machine_width, -half_machine_depth],
|
||||||
|
[half_machine_width - skirt_size, -half_machine_depth + skirt_size],
|
||||||
|
[half_machine_width - skirt_size, half_machine_depth - skirt_size]
|
||||||
|
], numpy.float32)))
|
||||||
|
|
||||||
|
areas.append(Polygon(numpy.array([
|
||||||
|
[-half_machine_width, half_machine_depth],
|
||||||
|
[half_machine_width, half_machine_depth],
|
||||||
|
[half_machine_width - skirt_size, half_machine_depth - skirt_size],
|
||||||
|
[-half_machine_width + skirt_size, half_machine_depth - skirt_size]
|
||||||
|
], numpy.float32)))
|
||||||
|
|
||||||
|
areas.append(Polygon(numpy.array([
|
||||||
|
[half_machine_width, -half_machine_depth],
|
||||||
|
[-half_machine_width, -half_machine_depth],
|
||||||
|
[-half_machine_width + skirt_size, -half_machine_depth + skirt_size],
|
||||||
|
[half_machine_width - skirt_size, -half_machine_depth + skirt_size]
|
||||||
|
], numpy.float32)))
|
||||||
|
|
||||||
|
self._disallowed_areas = areas
|
||||||
|
|
||||||
|
def _getSkirtSize(self, profile):
|
||||||
|
skirt_size = 0.0
|
||||||
|
|
||||||
|
adhesion_type = profile.getSettingValue("adhesion_type")
|
||||||
|
if adhesion_type == "skirt":
|
||||||
|
skirt_distance = profile.getSettingValue("skirt_gap")
|
||||||
|
skirt_line_count = profile.getSettingValue("skirt_line_count")
|
||||||
|
skirt_size = skirt_distance + (skirt_line_count * profile.getSettingValue("skirt_line_width"))
|
||||||
|
elif adhesion_type == "brim":
|
||||||
|
brim_line_count = profile.getSettingValue("brim_line_count")
|
||||||
|
skirt_size = brim_line_count * profile.getSettingValue("skirt_line_width")
|
||||||
|
elif adhesion_type == "raft":
|
||||||
|
skirt_size = profile.getSettingValue("raft_margin")
|
||||||
|
|
||||||
|
if profile.getSettingValue("draft_shield_enabled"):
|
||||||
|
skirt_size += profile.getSettingValue("draft_shield_dist")
|
||||||
|
|
||||||
|
skirt_size += profile.getSettingValue("xy_offset")
|
||||||
|
|
||||||
|
return skirt_size
|
||||||
|
|
||||||
|
def _clamp(self, value, min_value, max_value):
|
||||||
|
return max(min(value, max_value), min_value)
|
||||||
|
|
||||||
|
_skirt_settings = ["adhesion_type", "skirt_gap", "skirt_line_count", "skirt_line_width", "brim_line_count", "raft_margin", "draft_shield_enabled", "draft_shield_dist", "xy_offset"]
|
||||||
|
@ -31,6 +31,8 @@ class ConvexHullJob(Job):
|
|||||||
self._node.callDecoration("setConvexHullJob", None)
|
self._node.callDecoration("setConvexHullJob", None)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not self._node.getMeshData():
|
if not self._node.getMeshData():
|
||||||
return
|
return
|
||||||
|
@ -58,6 +58,11 @@ import numpy
|
|||||||
import copy
|
import copy
|
||||||
numpy.seterr(all="ignore")
|
numpy.seterr(all="ignore")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cura.CuraVersion import CuraVersion
|
||||||
|
except ImportError:
|
||||||
|
CuraVersion = "master"
|
||||||
|
|
||||||
class CuraApplication(QtApplication):
|
class CuraApplication(QtApplication):
|
||||||
class ResourceTypes:
|
class ResourceTypes:
|
||||||
QmlFiles = Resources.UserType + 1
|
QmlFiles = Resources.UserType + 1
|
||||||
@ -69,7 +74,7 @@ class CuraApplication(QtApplication):
|
|||||||
if not hasattr(sys, "frozen"):
|
if not hasattr(sys, "frozen"):
|
||||||
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), ".."))
|
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), ".."))
|
||||||
|
|
||||||
super().__init__(name = "cura", version = "master")
|
super().__init__(name = "cura", version = CuraVersion)
|
||||||
|
|
||||||
self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))
|
self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))
|
||||||
|
|
||||||
@ -136,6 +141,9 @@ class CuraApplication(QtApplication):
|
|||||||
parser.add_argument("--debug", dest="debug-mode", action="store_true", default=False, help="Enable detailed crash reports.")
|
parser.add_argument("--debug", dest="debug-mode", action="store_true", default=False, help="Enable detailed crash reports.")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
if not "PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION" in os.environ or os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] != "cpp":
|
||||||
|
Logger.log("w", "Using Python implementation of Protobuf, expect bad performance!")
|
||||||
|
|
||||||
self._i18n_catalog = i18nCatalog("cura");
|
self._i18n_catalog = i18nCatalog("cura");
|
||||||
|
|
||||||
i18nCatalog.setTagReplacements({
|
i18nCatalog.setTagReplacements({
|
||||||
@ -168,7 +176,7 @@ class CuraApplication(QtApplication):
|
|||||||
self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume)
|
self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume)
|
||||||
|
|
||||||
camera = Camera("3d", root)
|
camera = Camera("3d", root)
|
||||||
camera.setPosition(Vector(0, 250, 900))
|
camera.setPosition(Vector(-80, 250, 700))
|
||||||
camera.setPerspective(True)
|
camera.setPerspective(True)
|
||||||
camera.lookAt(Vector(0, 0, 0))
|
camera.lookAt(Vector(0, 0, 0))
|
||||||
controller.getScene().setActiveCamera("3d")
|
controller.getScene().setActiveCamera("3d")
|
||||||
|
4
cura/CuraVersion.py.in
Normal file
4
cura/CuraVersion.py.in
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Copyright (c) 2015 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
CuraVersion = "@CURA_VERSION@"
|
@ -63,6 +63,7 @@ class LayerData(MeshData):
|
|||||||
offset = data.build(offset, vertices, colors, indices)
|
offset = data.build(offset, vertices, colors, indices)
|
||||||
self._element_counts[layer] = data.elementCount
|
self._element_counts[layer] = data.elementCount
|
||||||
|
|
||||||
|
self.clear()
|
||||||
self.addVertices(vertices)
|
self.addVertices(vertices)
|
||||||
self.addColors(colors)
|
self.addColors(colors)
|
||||||
self.addIndices(indices.flatten())
|
self.addIndices(indices.flatten())
|
||||||
@ -200,18 +201,14 @@ class Polygon():
|
|||||||
|
|
||||||
def build(self, offset, vertices, colors, indices):
|
def build(self, offset, vertices, colors, indices):
|
||||||
self._begin = offset
|
self._begin = offset
|
||||||
|
self._end = self._begin + len(self._data) - 1
|
||||||
|
|
||||||
color = self.getColor()
|
color = self.getColor()
|
||||||
color.setValues(color.r * 0.5, color.g * 0.5, color.b * 0.5, color.a)
|
color.setValues(color.r * 0.5, color.g * 0.5, color.b * 0.5, color.a)
|
||||||
|
color = numpy.array([color.r, color.g, color.b, color.a], numpy.float32)
|
||||||
|
|
||||||
for i in range(len(self._data)):
|
vertices[self._begin:self._end + 1, :] = self._data[:, :]
|
||||||
vertices[offset + i, :] = self._data[i, :]
|
colors[self._begin:self._end + 1, :] = color
|
||||||
colors[offset + i, 0] = color.r
|
|
||||||
colors[offset + i, 1] = color.g
|
|
||||||
colors[offset + i, 2] = color.b
|
|
||||||
colors[offset + i, 3] = color.a
|
|
||||||
|
|
||||||
self._end = self._begin + len(self._data) - 1
|
|
||||||
|
|
||||||
for i in range(self._begin, self._end):
|
for i in range(self._begin, self._end):
|
||||||
indices[i, 0] = i
|
indices[i, 0] = i
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
def exceptHook(type, value, traceback):
|
def exceptHook(type, value, traceback):
|
||||||
import cura.CrashHandler
|
import cura.CrashHandler
|
||||||
@ -11,6 +12,13 @@ def exceptHook(type, value, traceback):
|
|||||||
|
|
||||||
sys.excepthook = exceptHook
|
sys.excepthook = exceptHook
|
||||||
|
|
||||||
|
try:
|
||||||
|
from google.protobuf.pyext import _message
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "cpp"
|
||||||
|
|
||||||
import cura.CuraApplication
|
import cura.CuraApplication
|
||||||
|
|
||||||
if sys.platform == "win32" and hasattr(sys, "frozen"):
|
if sys.platform == "win32" and hasattr(sys, "frozen"):
|
||||||
|
@ -10,6 +10,7 @@ from UM.Scene.SceneNode import SceneNode
|
|||||||
from UM.Scene.GroupDecorator import GroupDecorator
|
from UM.Scene.GroupDecorator import GroupDecorator
|
||||||
from UM.Math.Quaternion import Quaternion
|
from UM.Math.Quaternion import Quaternion
|
||||||
|
|
||||||
|
from UM.Job import Job
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
@ -53,6 +54,7 @@ class ThreeMFReader(MeshReader):
|
|||||||
#for vertex in object.mesh.vertices.vertex:
|
#for vertex in object.mesh.vertices.vertex:
|
||||||
for vertex in object.findall(".//3mf:vertex", self._namespaces):
|
for vertex in object.findall(".//3mf:vertex", self._namespaces):
|
||||||
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
|
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
triangles = object.findall(".//3mf:triangle", self._namespaces)
|
triangles = object.findall(".//3mf:triangle", self._namespaces)
|
||||||
|
|
||||||
@ -64,6 +66,8 @@ class ThreeMFReader(MeshReader):
|
|||||||
v2 = int(triangle.get("v2"))
|
v2 = int(triangle.get("v2"))
|
||||||
v3 = int(triangle.get("v3"))
|
v3 = int(triangle.get("v3"))
|
||||||
mesh.addFace(vertex_list[v1][0],vertex_list[v1][1],vertex_list[v1][2],vertex_list[v2][0],vertex_list[v2][1],vertex_list[v2][2],vertex_list[v3][0],vertex_list[v3][1],vertex_list[v3][2])
|
mesh.addFace(vertex_list[v1][0],vertex_list[v1][1],vertex_list[v1][2],vertex_list[v2][0],vertex_list[v2][1],vertex_list[v2][2],vertex_list[v3][0],vertex_list[v3][1],vertex_list[v3][2])
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
#TODO: We currently do not check for normals and simply recalculate them.
|
#TODO: We currently do not check for normals and simply recalculate them.
|
||||||
mesh.calculateNormals()
|
mesh.calculateNormals()
|
||||||
node.setMeshData(mesh)
|
node.setMeshData(mesh)
|
||||||
@ -116,6 +120,8 @@ class ThreeMFReader(MeshReader):
|
|||||||
#node.rotate(rotation)
|
#node.rotate(rotation)
|
||||||
result.addChild(node)
|
result.addChild(node)
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
#If there is more then one object, group them.
|
#If there is more then one object, group them.
|
||||||
try:
|
try:
|
||||||
if len(objects) > 1:
|
if len(objects) > 1:
|
||||||
|
@ -17,6 +17,7 @@ from cura.OneAtATimeIterator import OneAtATimeIterator
|
|||||||
from . import Cura_pb2
|
from . import Cura_pb2
|
||||||
from . import ProcessSlicedObjectListJob
|
from . import ProcessSlicedObjectListJob
|
||||||
from . import ProcessGCodeJob
|
from . import ProcessGCodeJob
|
||||||
|
from . import StartSliceJob
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -49,6 +50,7 @@ class CuraEngineBackend(Backend):
|
|||||||
self._onActiveViewChanged()
|
self._onActiveViewChanged()
|
||||||
self._stored_layer_data = None
|
self._stored_layer_data = None
|
||||||
|
|
||||||
|
Application.getInstance().getMachineManager().activeMachineInstanceChanged.connect(self._onChanged)
|
||||||
|
|
||||||
self._profile = None
|
self._profile = None
|
||||||
Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged)
|
Application.getInstance().getMachineManager().activeProfileChanged.connect(self._onActiveProfileChanged)
|
||||||
@ -67,12 +69,8 @@ class CuraEngineBackend(Backend):
|
|||||||
|
|
||||||
self._slicing = False
|
self._slicing = False
|
||||||
self._restart = False
|
self._restart = False
|
||||||
|
|
||||||
self._save_gcode = True
|
|
||||||
self._save_polygons = True
|
|
||||||
self._report_progress = True
|
|
||||||
|
|
||||||
self._enabled = True
|
self._enabled = True
|
||||||
|
self._always_restart = True
|
||||||
|
|
||||||
self._message = None
|
self._message = None
|
||||||
|
|
||||||
@ -103,24 +101,12 @@ class CuraEngineBackend(Backend):
|
|||||||
## Emitted whne the slicing process is aborted forcefully.
|
## Emitted whne the slicing process is aborted forcefully.
|
||||||
slicingCancelled = Signal()
|
slicingCancelled = Signal()
|
||||||
|
|
||||||
## Perform a slice of the scene with the given set of settings.
|
## Perform a slice of the scene.
|
||||||
#
|
def slice(self):
|
||||||
# \param kwargs Keyword arguments.
|
|
||||||
# Valid values are:
|
|
||||||
# - settings: The settings to use for the slice. The default is the active machine.
|
|
||||||
# - save_gcode: True if the generated gcode should be saved, False if not. True by default.
|
|
||||||
# - save_polygons: True if the generated polygon data should be saved, False if not. True by default.
|
|
||||||
# - force_restart: True if the slicing process should be forcefully restarted if it is already slicing.
|
|
||||||
# If False, this method will do nothing when already slicing. True by default.
|
|
||||||
# - report_progress: True if the slicing progress should be reported, False if not. Default is True.
|
|
||||||
def slice(self, **kwargs):
|
|
||||||
if not self._enabled:
|
if not self._enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._slicing:
|
if self._slicing:
|
||||||
if not kwargs.get("force_restart", True):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._slicing = False
|
self._slicing = False
|
||||||
self._restart = True
|
self._restart = True
|
||||||
if self._process is not None:
|
if self._process is not None:
|
||||||
@ -129,42 +115,16 @@ class CuraEngineBackend(Backend):
|
|||||||
self._process.terminate()
|
self._process.terminate()
|
||||||
except: # terminating a process that is already terminating causes an exception, silently ignore this.
|
except: # terminating a process that is already terminating causes an exception, silently ignore this.
|
||||||
pass
|
pass
|
||||||
self.slicingCancelled.emit()
|
|
||||||
return
|
|
||||||
|
|
||||||
Logger.log("d", "Preparing to send slice data to engine.")
|
|
||||||
object_groups = []
|
|
||||||
if self._profile.getSettingValue("print_sequence") == "one_at_a_time":
|
|
||||||
for node in OneAtATimeIterator(self._scene.getRoot()):
|
|
||||||
temp_list = []
|
|
||||||
children = node.getAllChildren()
|
|
||||||
children.append(node)
|
|
||||||
for child_node in children:
|
|
||||||
if type(child_node) is SceneNode and child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
|
|
||||||
temp_list.append(child_node)
|
|
||||||
object_groups.append(temp_list)
|
|
||||||
else:
|
|
||||||
temp_list = []
|
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
|
||||||
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
|
||||||
if not getattr(node, "_outside_buildarea", False):
|
|
||||||
temp_list.append(node)
|
|
||||||
if len(temp_list) == 0:
|
|
||||||
self.processingProgress.emit(0.0)
|
|
||||||
return
|
|
||||||
object_groups.append(temp_list)
|
|
||||||
#for node in DepthFirstIterator(self._scene.getRoot()):
|
|
||||||
# if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
|
||||||
# if not getattr(node, "_outside_buildarea", False):
|
|
||||||
# objects.append(node)
|
|
||||||
|
|
||||||
if len(object_groups) == 0:
|
|
||||||
if self._message:
|
if self._message:
|
||||||
self._message.hide()
|
self._message.hide()
|
||||||
self._message = None
|
self._message = None
|
||||||
return #No point in slicing an empty build plate
|
|
||||||
|
|
||||||
if kwargs.get("profile", self._profile).hasErrorValue():
|
self.slicingCancelled.emit()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._profile.hasErrorValue():
|
||||||
Logger.log('w', "Profile has error values. Aborting slicing")
|
Logger.log('w', "Profile has error values. Aborting slicing")
|
||||||
if self._message:
|
if self._message:
|
||||||
self._message.hide()
|
self._message.hide()
|
||||||
@ -172,62 +132,27 @@ class CuraEngineBackend(Backend):
|
|||||||
self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors."))
|
self._message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors."))
|
||||||
self._message.show()
|
self._message.show()
|
||||||
return #No slicing if we have error values since those are by definition illegal values.
|
return #No slicing if we have error values since those are by definition illegal values.
|
||||||
# Remove existing layer data (if any)
|
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
self.processingProgress.emit(0.0)
|
||||||
if type(node) is SceneNode and node.getMeshData():
|
if not self._message:
|
||||||
if node.callDecoration("getLayerData"):
|
self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1)
|
||||||
Application.getInstance().getController().getScene().getRoot().removeChild(node)
|
self._message.show()
|
||||||
break
|
else:
|
||||||
Application.getInstance().getController().getScene().gcode_list = None
|
self._message.setProgress(-1)
|
||||||
|
|
||||||
|
self._scene.gcode_list = []
|
||||||
self._slicing = True
|
self._slicing = True
|
||||||
self.slicingStarted.emit()
|
|
||||||
|
|
||||||
self._report_progress = kwargs.get("report_progress", True)
|
job = StartSliceJob.StartSliceJob(self._profile, self._socket)
|
||||||
if self._report_progress:
|
job.start()
|
||||||
self.processingProgress.emit(0.0)
|
job.finished.connect(self._onStartSliceCompleted)
|
||||||
if not self._message:
|
|
||||||
self._message = Message(catalog.i18nc("@info:status", "Slicing..."), 0, False, -1)
|
|
||||||
self._message.show()
|
|
||||||
else:
|
|
||||||
self._message.setProgress(-1)
|
|
||||||
|
|
||||||
self._sendSettings(kwargs.get("profile", self._profile))
|
def _onStartSliceCompleted(self, job):
|
||||||
|
if job.getError() or job.getResult() != True:
|
||||||
self._scene.acquireLock()
|
if self._message:
|
||||||
|
self._message.hide()
|
||||||
# Set the gcode as an empty list. This will be filled with strings by GCodeLayer messages.
|
self._message = None
|
||||||
# This is done so the gcode can be fragmented in memory and does not need a continues memory space.
|
return
|
||||||
# (AKA. This prevents MemoryErrors)
|
|
||||||
self._save_gcode = kwargs.get("save_gcode", True)
|
|
||||||
if self._save_gcode:
|
|
||||||
setattr(self._scene, "gcode_list", [])
|
|
||||||
|
|
||||||
self._save_polygons = kwargs.get("save_polygons", True)
|
|
||||||
|
|
||||||
slice_message = Cura_pb2.Slice()
|
|
||||||
|
|
||||||
for group in object_groups:
|
|
||||||
group_message = slice_message.object_lists.add()
|
|
||||||
for object in group:
|
|
||||||
mesh_data = object.getMeshData().getTransformed(object.getWorldTransformation())
|
|
||||||
|
|
||||||
obj = group_message.objects.add()
|
|
||||||
obj.id = id(object)
|
|
||||||
|
|
||||||
verts = numpy.array(mesh_data.getVertices())
|
|
||||||
verts[:,[1,2]] = verts[:,[2,1]]
|
|
||||||
verts[:,1] *= -1
|
|
||||||
obj.vertices = verts.tostring()
|
|
||||||
|
|
||||||
self._handlePerObjectSettings(object, obj)
|
|
||||||
|
|
||||||
# Hack to add per-object settings also to the "MeshGroup" in CuraEngine
|
|
||||||
# We really should come up with a better solution for this.
|
|
||||||
self._handlePerObjectSettings(group[0], group_message)
|
|
||||||
|
|
||||||
self._scene.releaseLock()
|
|
||||||
Logger.log("d", "Sending data to engine for slicing.")
|
|
||||||
self._socket.sendMessage(slice_message)
|
|
||||||
|
|
||||||
def _onSceneChanged(self, source):
|
def _onSceneChanged(self, source):
|
||||||
if type(source) is not SceneNode:
|
if type(source) is not SceneNode:
|
||||||
@ -257,41 +182,42 @@ class CuraEngineBackend(Backend):
|
|||||||
self._onChanged()
|
self._onChanged()
|
||||||
|
|
||||||
def _onSlicedObjectListMessage(self, message):
|
def _onSlicedObjectListMessage(self, message):
|
||||||
if self._save_polygons:
|
if self._layer_view_active:
|
||||||
if self._layer_view_active:
|
job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message)
|
||||||
job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message)
|
job.start()
|
||||||
job.start()
|
else :
|
||||||
else :
|
self._stored_layer_data = message
|
||||||
self._stored_layer_data = message
|
|
||||||
|
|
||||||
def _onProgressMessage(self, message):
|
def _onProgressMessage(self, message):
|
||||||
if message.amount >= 0.99:
|
|
||||||
self._slicing = False
|
|
||||||
|
|
||||||
if self._message:
|
|
||||||
self._message.setProgress(100)
|
|
||||||
self._message.hide()
|
|
||||||
self._message = None
|
|
||||||
|
|
||||||
if self._message:
|
if self._message:
|
||||||
self._message.setProgress(round(message.amount * 100))
|
self._message.setProgress(round(message.amount * 100))
|
||||||
|
|
||||||
if self._report_progress:
|
self.processingProgress.emit(message.amount)
|
||||||
self.processingProgress.emit(message.amount)
|
|
||||||
|
|
||||||
def _onGCodeLayerMessage(self, message):
|
def _onGCodeLayerMessage(self, message):
|
||||||
if self._save_gcode:
|
self._scene.gcode_list.append(message.data.decode("utf-8", "replace"))
|
||||||
job = ProcessGCodeJob.ProcessGCodeLayerJob(message)
|
|
||||||
job.start()
|
|
||||||
|
|
||||||
def _onGCodePrefixMessage(self, message):
|
def _onGCodePrefixMessage(self, message):
|
||||||
if self._save_gcode:
|
self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace"))
|
||||||
self._scene.gcode_list.insert(0, message.data.decode("utf-8", "replace"))
|
|
||||||
|
|
||||||
def _onObjectPrintTimeMessage(self, message):
|
def _onObjectPrintTimeMessage(self, message):
|
||||||
self.printDurationMessage.emit(message.time, message.material_amount)
|
self.printDurationMessage.emit(message.time, message.material_amount)
|
||||||
self.processingProgress.emit(1.0)
|
self.processingProgress.emit(1.0)
|
||||||
|
|
||||||
|
self._slicing = False
|
||||||
|
|
||||||
|
if self._message:
|
||||||
|
self._message.setProgress(100)
|
||||||
|
self._message.hide()
|
||||||
|
self._message = None
|
||||||
|
|
||||||
|
if self._always_restart:
|
||||||
|
try:
|
||||||
|
self._process.terminate()
|
||||||
|
self._createSocket()
|
||||||
|
except: # terminating a process that is already terminating causes an exception, silently ignore this.
|
||||||
|
pass
|
||||||
|
|
||||||
def _createSocket(self):
|
def _createSocket(self):
|
||||||
super()._createSocket()
|
super()._createSocket()
|
||||||
|
|
||||||
@ -313,15 +239,6 @@ class CuraEngineBackend(Backend):
|
|||||||
|
|
||||||
self._change_timer.start()
|
self._change_timer.start()
|
||||||
|
|
||||||
def _sendSettings(self, profile):
|
|
||||||
msg = Cura_pb2.SettingList()
|
|
||||||
for key, value in profile.getAllSettingValues(include_machine = True).items():
|
|
||||||
s = msg.settings.add()
|
|
||||||
s.name = key
|
|
||||||
s.value = str(value).encode("utf-8")
|
|
||||||
|
|
||||||
self._socket.sendMessage(msg)
|
|
||||||
|
|
||||||
def _onBackendConnected(self):
|
def _onBackendConnected(self):
|
||||||
if self._restart:
|
if self._restart:
|
||||||
self._onChanged()
|
self._onChanged()
|
||||||
@ -346,22 +263,6 @@ class CuraEngineBackend(Backend):
|
|||||||
else:
|
else:
|
||||||
self._layer_view_active = False
|
self._layer_view_active = False
|
||||||
|
|
||||||
def _handlePerObjectSettings(self, node, message):
|
|
||||||
profile = node.callDecoration("getProfile")
|
|
||||||
if profile:
|
|
||||||
for key, value in profile.getChangedSettingValues().items():
|
|
||||||
setting = message.settings.add()
|
|
||||||
setting.name = key
|
|
||||||
setting.value = str(value).encode()
|
|
||||||
|
|
||||||
object_settings = node.callDecoration("getAllSettingValues")
|
|
||||||
if not object_settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
for key, value in object_settings.items():
|
|
||||||
setting = message.settings.add()
|
|
||||||
setting.name = key
|
|
||||||
setting.value = str(value).encode()
|
|
||||||
|
|
||||||
def _onInstanceChanged(self):
|
def _onInstanceChanged(self):
|
||||||
self._slicing = False
|
self._slicing = False
|
||||||
|
@ -38,10 +38,10 @@ class ProcessSlicedObjectListJob(Job):
|
|||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if type(node) is SceneNode and node.getMeshData():
|
if type(node) is SceneNode and node.getMeshData():
|
||||||
if node.callDecoration("getLayerData"):
|
if node.callDecoration("getLayerData"):
|
||||||
#if hasattr(node.getMeshData(), "layerData"):
|
|
||||||
self._scene.getRoot().removeChild(node)
|
self._scene.getRoot().removeChild(node)
|
||||||
else:
|
else:
|
||||||
objectIdMap[id(node)] = node
|
objectIdMap[id(node)] = node
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
settings = Application.getInstance().getMachineManager().getActiveProfile()
|
settings = Application.getInstance().getMachineManager().getActiveProfile()
|
||||||
layerHeight = settings.getSettingValue("layer_height")
|
layerHeight = settings.getSettingValue("layer_height")
|
||||||
@ -54,6 +54,12 @@ class ProcessSlicedObjectListJob(Job):
|
|||||||
|
|
||||||
mesh = MeshData()
|
mesh = MeshData()
|
||||||
layer_data = LayerData.LayerData()
|
layer_data = LayerData.LayerData()
|
||||||
|
|
||||||
|
layer_count = 0
|
||||||
|
for object in self._message.objects:
|
||||||
|
layer_count += len(object.layers)
|
||||||
|
|
||||||
|
current_layer = 0
|
||||||
for object in self._message.objects:
|
for object in self._message.objects:
|
||||||
try:
|
try:
|
||||||
node = objectIdMap[object.id]
|
node = objectIdMap[object.id]
|
||||||
@ -73,15 +79,23 @@ class ProcessSlicedObjectListJob(Job):
|
|||||||
|
|
||||||
points[:,2] *= -1
|
points[:,2] *= -1
|
||||||
|
|
||||||
points -= numpy.array(center)
|
points -= center
|
||||||
|
|
||||||
layer_data.addPolygon(layer.id, polygon.type, points, polygon.line_width)
|
layer_data.addPolygon(layer.id, polygon.type, points, polygon.line_width)
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
|
current_layer += 1
|
||||||
|
progress = (current_layer / layer_count) * 100
|
||||||
|
# TODO: Rebuild the layer data mesh once the layer has been processed.
|
||||||
|
# This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh.
|
||||||
|
|
||||||
|
if self._progress:
|
||||||
|
self._progress.setProgress(progress)
|
||||||
|
|
||||||
# We are done processing all the layers we got from the engine, now create a mesh out of the data
|
# We are done processing all the layers we got from the engine, now create a mesh out of the data
|
||||||
layer_data.build()
|
layer_data.build()
|
||||||
|
|
||||||
|
|
||||||
#Add layerdata decorator to scene node to indicate that the node has layerdata
|
#Add layerdata decorator to scene node to indicate that the node has layerdata
|
||||||
decorator = LayerDataDecorator.LayerDataDecorator()
|
decorator = LayerDataDecorator.LayerDataDecorator()
|
||||||
decorator.setLayerData(layer_data)
|
decorator.setLayerData(layer_data)
|
||||||
@ -90,6 +104,9 @@ class ProcessSlicedObjectListJob(Job):
|
|||||||
new_node.setMeshData(mesh)
|
new_node.setMeshData(mesh)
|
||||||
new_node.setParent(self._scene.getRoot())
|
new_node.setParent(self._scene.getRoot())
|
||||||
|
|
||||||
|
if self._progress:
|
||||||
|
self._progress.setProgress(100)
|
||||||
|
|
||||||
view = Application.getInstance().getController().getActiveView()
|
view = Application.getInstance().getController().getActiveView()
|
||||||
if view.getPluginId() == "LayerView":
|
if view.getPluginId() == "LayerView":
|
||||||
view.resetLayerData()
|
view.resetLayerData()
|
||||||
|
121
plugins/CuraEngineBackend/StartSliceJob.py
Normal file
121
plugins/CuraEngineBackend/StartSliceJob.py
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Copyright (c) 2015 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
from UM.Job import Job
|
||||||
|
from UM.Application import Application
|
||||||
|
from UM.Logger import Logger
|
||||||
|
|
||||||
|
from UM.Scene.SceneNode import SceneNode
|
||||||
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
|
|
||||||
|
from cura.OneAtATimeIterator import OneAtATimeIterator
|
||||||
|
|
||||||
|
from . import Cura_pb2
|
||||||
|
|
||||||
|
## Job class that handles sending the current scene data to CuraEngine
|
||||||
|
class StartSliceJob(Job):
|
||||||
|
def __init__(self, profile, socket):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self._scene = Application.getInstance().getController().getScene()
|
||||||
|
self._profile = profile
|
||||||
|
self._socket = socket
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self._scene.acquireLock()
|
||||||
|
|
||||||
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
if node.callDecoration("getLayerData"):
|
||||||
|
node.getParent().removeChild(node)
|
||||||
|
break
|
||||||
|
|
||||||
|
object_groups = []
|
||||||
|
if self._profile.getSettingValue("print_sequence") == "one_at_a_time":
|
||||||
|
for node in OneAtATimeIterator(self._scene.getRoot()):
|
||||||
|
temp_list = []
|
||||||
|
|
||||||
|
if getattr(node, "_outside_buildarea", False):
|
||||||
|
continue
|
||||||
|
|
||||||
|
children = node.getAllChildren()
|
||||||
|
children.append(node)
|
||||||
|
for child_node in children:
|
||||||
|
if type(child_node) is SceneNode and child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
|
||||||
|
temp_list.append(child_node)
|
||||||
|
|
||||||
|
if temp_list:
|
||||||
|
object_groups.append(temp_list)
|
||||||
|
Job.yieldThread()
|
||||||
|
else:
|
||||||
|
temp_list = []
|
||||||
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
|
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||||
|
if not getattr(node, "_outside_buildarea", False):
|
||||||
|
temp_list.append(node)
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
|
if temp_list:
|
||||||
|
object_groups.append(temp_list)
|
||||||
|
|
||||||
|
self._scene.releaseLock()
|
||||||
|
|
||||||
|
if not object_groups:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._sendSettings(self._profile)
|
||||||
|
|
||||||
|
slice_message = Cura_pb2.Slice()
|
||||||
|
|
||||||
|
for group in object_groups:
|
||||||
|
group_message = slice_message.object_lists.add()
|
||||||
|
for object in group:
|
||||||
|
mesh_data = object.getMeshData().getTransformed(object.getWorldTransformation())
|
||||||
|
|
||||||
|
obj = group_message.objects.add()
|
||||||
|
obj.id = id(object)
|
||||||
|
|
||||||
|
verts = numpy.array(mesh_data.getVertices())
|
||||||
|
verts[:,[1,2]] = verts[:,[2,1]]
|
||||||
|
verts[:,1] *= -1
|
||||||
|
obj.vertices = verts.tostring()
|
||||||
|
|
||||||
|
self._handlePerObjectSettings(object, obj)
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
|
Logger.log("d", "Sending data to engine for slicing.")
|
||||||
|
self._socket.sendMessage(slice_message)
|
||||||
|
|
||||||
|
self.setResult(True)
|
||||||
|
|
||||||
|
def _sendSettings(self, profile):
|
||||||
|
msg = Cura_pb2.SettingList()
|
||||||
|
for key, value in profile.getAllSettingValues(include_machine = True).items():
|
||||||
|
s = msg.settings.add()
|
||||||
|
s.name = key
|
||||||
|
s.value = str(value).encode("utf-8")
|
||||||
|
|
||||||
|
self._socket.sendMessage(msg)
|
||||||
|
|
||||||
|
def _handlePerObjectSettings(self, node, message):
|
||||||
|
profile = node.callDecoration("getProfile")
|
||||||
|
if profile:
|
||||||
|
for key, value in profile.getAllSettingValues().items():
|
||||||
|
setting = message.settings.add()
|
||||||
|
setting.name = key
|
||||||
|
setting.value = str(value).encode()
|
||||||
|
|
||||||
|
Job.yieldThread()
|
||||||
|
|
||||||
|
object_settings = node.callDecoration("getAllSettingValues")
|
||||||
|
if not object_settings:
|
||||||
|
return
|
||||||
|
|
||||||
|
for key, value in object_settings.items():
|
||||||
|
setting = message.settings.add()
|
||||||
|
setting.name = key
|
||||||
|
setting.value = str(value).encode()
|
||||||
|
|
||||||
|
Job.yieldThread()
|
@ -41,6 +41,33 @@ Item {
|
|||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: closeButton;
|
||||||
|
width: UM.Theme.sizes.message_close.width;
|
||||||
|
height: UM.Theme.sizes.message_close.height;
|
||||||
|
anchors {
|
||||||
|
right: parent.right;
|
||||||
|
rightMargin: UM.Theme.sizes.default_margin.width / 2;
|
||||||
|
top: parent.top;
|
||||||
|
topMargin: UM.Theme.sizes.default_margin.width / 2;
|
||||||
|
}
|
||||||
|
UM.RecolorImage {
|
||||||
|
anchors.fill: parent;
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: width
|
||||||
|
color: UM.Theme.colors.message_dismiss
|
||||||
|
source: UM.Theme.icons.cross2;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: settingsPanel.opacity = 0
|
||||||
|
|
||||||
|
style: ButtonStyle {
|
||||||
|
background: Rectangle {
|
||||||
|
color: UM.Theme.colors.message_background
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: items
|
id: items
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
@ -58,7 +85,6 @@ Item {
|
|||||||
|
|
||||||
name: catalog.i18nc("@label", "Profile")
|
name: catalog.i18nc("@label", "Profile")
|
||||||
type: "enum"
|
type: "enum"
|
||||||
perObjectSetting: true
|
|
||||||
|
|
||||||
style: UM.Theme.styles.setting_item;
|
style: UM.Theme.styles.setting_item;
|
||||||
|
|
||||||
@ -88,8 +114,6 @@ Item {
|
|||||||
description: model.description;
|
description: model.description;
|
||||||
unit: model.unit;
|
unit: model.unit;
|
||||||
valid: model.valid;
|
valid: model.valid;
|
||||||
perObjectSetting: true
|
|
||||||
dismissable: true
|
|
||||||
options: model.options
|
options: model.options
|
||||||
|
|
||||||
style: UM.Theme.styles.setting_item;
|
style: UM.Theme.styles.setting_item;
|
||||||
@ -98,18 +122,36 @@ Item {
|
|||||||
settings.model.setSettingValue(model.key, value)
|
settings.model.setSettingValue(model.key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button {
|
Button
|
||||||
// anchors.left: parent.right;
|
{
|
||||||
// text: "x";
|
anchors.left: parent.horizontalCenter;
|
||||||
//
|
anchors.leftMargin: UM.Theme.sizes.default_margin.width;
|
||||||
// width: UM.Theme.sizes.setting.height;
|
|
||||||
// height: UM.Theme.sizes.setting.height;
|
width: UM.Theme.sizes.setting.height;
|
||||||
//
|
height: UM.Theme.sizes.setting.height;
|
||||||
// opacity: parent.hovered || hovered ? 1 : 0;
|
|
||||||
// onClicked: UM.ActiveTool.properties.Model.removeSettingOverride(UM.ActiveTool.properties.Model.getItem(base.currentIndex).id, model.key)
|
opacity: parent.hovered || hovered ? 1 : 0;
|
||||||
//
|
onClicked: UM.ActiveTool.properties.Model.removeSettingOverride(UM.ActiveTool.properties.Model.getItem(base.currentIndex).id, model.key)
|
||||||
// style: ButtonStyle { }
|
|
||||||
// }
|
style: ButtonStyle
|
||||||
|
{
|
||||||
|
background: Rectangle
|
||||||
|
{
|
||||||
|
color: control.hovered ? control.parent.style.controlHighlightColor : control.parent.style.controlColor;
|
||||||
|
UM.RecolorImage
|
||||||
|
{
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width/2
|
||||||
|
height: parent.height/2
|
||||||
|
sourceSize.width: width
|
||||||
|
sourceSize.height: width
|
||||||
|
color: UM.Theme.colors.setting_control_revert
|
||||||
|
source: UM.Theme.icons.cross1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +214,19 @@ Item {
|
|||||||
|
|
||||||
checkable: true;
|
checkable: true;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
base.currentIndex = index;
|
if(settingsPanel.opacity < 0.5) //Per-object panel is not currently displayed.
|
||||||
|
{
|
||||||
|
base.currentIndex = index;
|
||||||
|
|
||||||
settingsPanel.anchors.left = right;
|
settingsPanel.anchors.left = right;
|
||||||
settingsPanel.anchors.top = top;
|
settingsPanel.anchors.top = top;
|
||||||
|
|
||||||
settingsPanel.opacity = 1;
|
settingsPanel.opacity = 1;
|
||||||
|
}
|
||||||
|
else //Per-object panel is already displayed. Deactivate it (same behaviour as the close button).
|
||||||
|
{
|
||||||
|
settingsPanel.opacity = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
style: ButtonStyle
|
style: ButtonStyle
|
||||||
|
@ -44,9 +44,7 @@ class SettingOverrideModel(ListModel):
|
|||||||
if not self._decorator:
|
if not self._decorator:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._ignore_setting_change = key
|
|
||||||
self._decorator.setSettingValue(key, value)
|
self._decorator.setSettingValue(key, value)
|
||||||
self._ignore_setting_change = None
|
|
||||||
|
|
||||||
def _onDecoratorsChanged(self, node):
|
def _onDecoratorsChanged(self, node):
|
||||||
if not self._node.getDecorator(SettingOverrideDecorator):
|
if not self._node.getDecorator(SettingOverrideDecorator):
|
||||||
@ -97,6 +95,6 @@ class SettingOverrideModel(ListModel):
|
|||||||
def _onSettingValueChanged(self, setting):
|
def _onSettingValueChanged(self, setting):
|
||||||
index = self.find("key", setting.getKey())
|
index = self.find("key", setting.getKey())
|
||||||
value = self._decorator.getSettingValue(setting.getKey())
|
value = self._decorator.getSettingValue(setting.getKey())
|
||||||
if index != -1 and self._ignore_setting_change != setting.getKey():
|
if index != -1:
|
||||||
self.setProperty(index, "value", str(value))
|
self.setProperty(index, "value", str(value))
|
||||||
self.setProperty(index, "valid", setting.validate(value))
|
self.setProperty(index, "valid", setting.validate(value))
|
||||||
|
@ -52,6 +52,8 @@ class RemovableDriveOutputDevice(OutputDevice):
|
|||||||
message = Message(catalog.i18nc("@info:progress", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1)
|
message = Message(catalog.i18nc("@info:progress", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1)
|
||||||
message.show()
|
message.show()
|
||||||
|
|
||||||
|
self.writeStarted.emit(self)
|
||||||
|
|
||||||
job._message = message
|
job._message = message
|
||||||
job.start()
|
job.start()
|
||||||
except PermissionError as e:
|
except PermissionError as e:
|
||||||
|
@ -45,7 +45,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._connect_thread.daemon = True
|
self._connect_thread.daemon = True
|
||||||
|
|
||||||
self._end_stop_thread = threading.Thread(target = self._pollEndStop)
|
self._end_stop_thread = threading.Thread(target = self._pollEndStop)
|
||||||
self._end_stop_thread.deamon = True
|
self._end_stop_thread.daemon = True
|
||||||
self._poll_endstop = -1
|
self._poll_endstop = -1
|
||||||
|
|
||||||
# Printer is connected
|
# Printer is connected
|
||||||
@ -65,6 +65,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
self._update_firmware_thread = threading.Thread(target= self._updateFirmware)
|
self._update_firmware_thread = threading.Thread(target= self._updateFirmware)
|
||||||
self._update_firmware_thread.daemon = True
|
self._update_firmware_thread.daemon = True
|
||||||
|
self.firmwareUpdateComplete.connect(self._onFirmwareUpdateComplete)
|
||||||
|
|
||||||
self._heatup_wait_start_time = time.time()
|
self._heatup_wait_start_time = time.time()
|
||||||
|
|
||||||
@ -197,6 +198,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
## Private fuction (threaded) that actually uploads the firmware.
|
## Private fuction (threaded) that actually uploads the firmware.
|
||||||
def _updateFirmware(self):
|
def _updateFirmware(self):
|
||||||
|
self.setProgress(0, 100)
|
||||||
|
|
||||||
if self._is_connecting or self._is_connected:
|
if self._is_connecting or self._is_connected:
|
||||||
self.close()
|
self.close()
|
||||||
hex_file = intelHex.readHex(self._firmware_file_name)
|
hex_file = intelHex.readHex(self._firmware_file_name)
|
||||||
@ -207,7 +210,11 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
programmer = stk500v2.Stk500v2()
|
programmer = stk500v2.Stk500v2()
|
||||||
programmer.progressCallback = self.setProgress
|
programmer.progressCallback = self.setProgress
|
||||||
programmer.connect(self._serial_port)
|
|
||||||
|
try:
|
||||||
|
programmer.connect(self._serial_port)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
time.sleep(1) # Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases.
|
time.sleep(1) # Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases.
|
||||||
|
|
||||||
@ -336,8 +343,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._connect_thread = threading.Thread(target=self._connect)
|
self._connect_thread = threading.Thread(target=self._connect)
|
||||||
self._connect_thread.daemon = True
|
self._connect_thread.daemon = True
|
||||||
|
|
||||||
|
self.setIsConnected(False)
|
||||||
if self._serial is not None:
|
if self._serial is not None:
|
||||||
self.setIsConnected(False)
|
|
||||||
try:
|
try:
|
||||||
self._listen_thread.join()
|
self._listen_thread.join()
|
||||||
except:
|
except:
|
||||||
|
@ -11,6 +11,7 @@ from UM.Logger import Logger
|
|||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
from UM.Message import Message
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
@ -95,6 +96,10 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def updateAllFirmware(self):
|
def updateAllFirmware(self):
|
||||||
|
if not self._printer_connections:
|
||||||
|
Message("Cannot update firmware, there were no connected printers found.").show()
|
||||||
|
return
|
||||||
|
|
||||||
self.spawnFirmwareInterface("")
|
self.spawnFirmwareInterface("")
|
||||||
for printer_connection in self._printer_connections:
|
for printer_connection in self._printer_connections:
|
||||||
try:
|
try:
|
||||||
@ -159,6 +164,16 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
continue
|
continue
|
||||||
self._serial_port_list = list(serial_ports)
|
self._serial_port_list = list(serial_ports)
|
||||||
|
|
||||||
|
connections_to_remove = []
|
||||||
|
for port, connection in self._printer_connections.items():
|
||||||
|
if port not in self._serial_port_list:
|
||||||
|
connection.close()
|
||||||
|
connections_to_remove.append(port)
|
||||||
|
|
||||||
|
for port in connections_to_remove:
|
||||||
|
del self._printer_connections[port]
|
||||||
|
|
||||||
|
|
||||||
## Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
## Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
||||||
def addConnection(self, serial_port):
|
def addConnection(self, serial_port):
|
||||||
connection = PrinterConnection.PrinterConnection(serial_port)
|
connection = PrinterConnection.PrinterConnection(serial_port)
|
||||||
|
@ -58,7 +58,7 @@ class IspBase():
|
|||||||
raise IspError("Called undefined verifyFlash")
|
raise IspError("Called undefined verifyFlash")
|
||||||
|
|
||||||
|
|
||||||
class IspError(BaseException):
|
class IspError(Exception):
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default": 0.1,
|
"default": 0.1,
|
||||||
"min_value": "0.0001",
|
"min_value": "0.001",
|
||||||
"min_value_warning": "0.04",
|
"min_value_warning": "0.04",
|
||||||
"max_value_warning": "0.32"
|
"max_value_warning": "0.32"
|
||||||
},
|
},
|
||||||
@ -150,7 +150,7 @@
|
|||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default": 0.3,
|
"default": 0.3,
|
||||||
"min_value": "0.0001",
|
"min_value": "0.001",
|
||||||
"min_value_warning": "0.04",
|
"min_value_warning": "0.04",
|
||||||
"max_value_warning": "0.32",
|
"max_value_warning": "0.32",
|
||||||
"visible": false
|
"visible": false
|
||||||
@ -825,7 +825,8 @@
|
|||||||
"type": "float",
|
"type": "float",
|
||||||
"min_value": "0.1",
|
"min_value": "0.1",
|
||||||
"max_value_warning": "300",
|
"max_value_warning": "300",
|
||||||
"default": 150
|
"default": 150,
|
||||||
|
"inherit_function": "speed_print if magic_spiralize else 150"
|
||||||
},
|
},
|
||||||
"speed_layer_0": {
|
"speed_layer_0": {
|
||||||
"label": "Bottom Layer Speed",
|
"label": "Bottom Layer Speed",
|
||||||
|
@ -567,7 +567,7 @@ UM.MainWindow
|
|||||||
|
|
||||||
addMachine.onTriggered: addMachineWizard.visible = true;
|
addMachine.onTriggered: addMachineWizard.visible = true;
|
||||||
|
|
||||||
preferences.onTriggered: { preferences.visible = true; }
|
preferences.onTriggered: { preferences.visible = true; preferences.setPage(0); }
|
||||||
configureMachines.onTriggered: { preferences.visible = true; preferences.setPage(3); }
|
configureMachines.onTriggered: { preferences.visible = true; preferences.setPage(3); }
|
||||||
manageProfiles.onTriggered: { preferences.visible = true; preferences.setPage(4); }
|
manageProfiles.onTriggered: { preferences.visible = true; preferences.setPage(4); }
|
||||||
|
|
||||||
|
@ -13,6 +13,18 @@ UM.PreferencesPage
|
|||||||
//: General configuration page title
|
//: General configuration page title
|
||||||
title: catalog.i18nc("@title:tab","General");
|
title: catalog.i18nc("@title:tab","General");
|
||||||
|
|
||||||
|
function setDefaultLanguage(languageCode)
|
||||||
|
{
|
||||||
|
//loops trough the languageList and sets the language using the languageCode
|
||||||
|
for(var i = 0; i < languageList.count; i++)
|
||||||
|
{
|
||||||
|
if (languageComboBox.model.get(i).code == languageCode)
|
||||||
|
{
|
||||||
|
languageComboBox.currentIndex = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reset()
|
function reset()
|
||||||
{
|
{
|
||||||
UM.Preferences.resetPreference("general/language")
|
UM.Preferences.resetPreference("general/language")
|
||||||
@ -22,7 +34,8 @@ UM.PreferencesPage
|
|||||||
pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free"))
|
pushFreeCheckbox.checked = boolCheck(UM.Preferences.getValue("physics/automatic_push_free"))
|
||||||
sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info"))
|
sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info"))
|
||||||
scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit"))
|
scaleToFitCheckbox.checked = boolCheck(UM.Preferences.getValue("mesh/scale_to_fit"))
|
||||||
languageComboBox.currentIndex = 0
|
var defaultLanguage = UM.Preferences.getValue("general/language")
|
||||||
|
setDefaultLanguage(defaultLanguage)
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout
|
GridLayout
|
||||||
|
@ -7,8 +7,6 @@ import QtQuick.Window 2.1
|
|||||||
import QtQuick.Controls.Styles 1.1
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
import Cura 1.0 as Cura
|
|
||||||
import ".."
|
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
@ -18,18 +16,69 @@ Item
|
|||||||
|
|
||||||
property variant wizard: null;
|
property variant wizard: null;
|
||||||
|
|
||||||
|
property bool visibility: base.wizard.visible
|
||||||
|
onVisibilityChanged:
|
||||||
|
{
|
||||||
|
machineName.text = getMachineName()
|
||||||
|
errorMessage.show = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function editMachineName(word)
|
||||||
|
{
|
||||||
|
//Adds '#2' at the end or increases the number by 1 if the word ends with '#' and 1 or more digits
|
||||||
|
var regEx = /[#][\d]+$///ends with '#' and then 1 or more digit
|
||||||
|
var result = word.match(regEx)
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result = result[0].split('')
|
||||||
|
|
||||||
|
var numberString = ''
|
||||||
|
for (var i = 1; i < result.length; i++){//starting at 1, makes it ignore the '#'
|
||||||
|
numberString += result[i]
|
||||||
|
}
|
||||||
|
var newNumber = Number(numberString) + 1
|
||||||
|
|
||||||
|
var newWord = word.replace(/[\d]+$/, newNumber)//replaces the last digits in the string by the same number + 1
|
||||||
|
return newWord
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return word + ' #2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMachineName()
|
||||||
|
{
|
||||||
|
var name = machineList.model.getItem(machineList.currentIndex).name
|
||||||
|
|
||||||
|
//if the automatically assigned name is not unique, the editMachineName function keeps editing it untill it is.
|
||||||
|
while (UM.MachineManager.checkInstanceExists(name) != false)
|
||||||
|
{
|
||||||
|
name = editMachineName(name)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
Connections
|
Connections
|
||||||
{
|
{
|
||||||
target: base.wizard
|
target: base.wizard
|
||||||
onNextClicked: //You can add functions here that get triggered when the final button is clicked in the wizard-element
|
onNextClicked: //You can add functions here that get triggered when the final button is clicked in the wizard-element
|
||||||
{
|
{
|
||||||
var old_page_count = base.wizard.getPageCount()
|
var name = machineName.text
|
||||||
// Delete old pages (if any)
|
if (UM.MachineManager.checkInstanceExists(name) != false)
|
||||||
for (var i = old_page_count - 1; i > 0; i--)
|
|
||||||
{
|
{
|
||||||
base.wizard.removePage(i)
|
errorMessage.show = true
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var old_page_count = base.wizard.getPageCount()
|
||||||
|
// Delete old pages (if any)
|
||||||
|
for (var i = old_page_count - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
base.wizard.removePage(i)
|
||||||
|
}
|
||||||
|
saveMachine()
|
||||||
}
|
}
|
||||||
saveMachine()
|
|
||||||
}
|
}
|
||||||
onBackClicked:
|
onBackClicked:
|
||||||
{
|
{
|
||||||
@ -63,7 +112,8 @@ Item
|
|||||||
{
|
{
|
||||||
id: machinesHolder
|
id: machinesHolder
|
||||||
|
|
||||||
anchors{
|
anchors
|
||||||
|
{
|
||||||
left: parent.left;
|
left: parent.left;
|
||||||
top: subTitle.bottom;
|
top: subTitle.bottom;
|
||||||
right: parent.right;
|
right: parent.right;
|
||||||
@ -110,6 +160,7 @@ Item
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
base.activeManufacturer = section;
|
base.activeManufacturer = section;
|
||||||
machineList.currentIndex = machineList.model.find("manufacturer", section)
|
machineList.currentIndex = machineList.model.find("manufacturer", section)
|
||||||
|
machineName.text = getMachineName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +179,10 @@ Item
|
|||||||
|
|
||||||
text: model.name
|
text: model.name
|
||||||
|
|
||||||
onClicked: ListView.view.currentIndex = index;
|
onClicked: {
|
||||||
|
ListView.view.currentIndex = index;
|
||||||
|
machineName.text = getMachineName()
|
||||||
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
@ -169,11 +223,33 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item
|
|
||||||
|
|
||||||
|
Column
|
||||||
{
|
{
|
||||||
id: machineNameHolder
|
id: machineNameHolder
|
||||||
height: childrenRect.height
|
|
||||||
anchors.bottom: parent.bottom;
|
anchors.bottom: parent.bottom;
|
||||||
|
//height: insertNameLabel.lineHeight * (2 + errorMessage.lineCount)
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
height: errorMessage.lineHeight
|
||||||
|
anchors.bottom: insertNameLabel.top
|
||||||
|
anchors.bottomMargin: insertNameLabel.height * errorMessage.lineCount
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: errorMessage
|
||||||
|
property bool show: false
|
||||||
|
width: base.width
|
||||||
|
height: errorMessage.show ? errorMessage.lineHeight : 0
|
||||||
|
visible: errorMessage.show
|
||||||
|
text: catalog.i18nc("@label", "This printer name has already been used. Please choose a different printer name.");
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Behavior on height {NumberAnimation {duration: 75; }}
|
||||||
|
color: UM.Theme.colors.error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: insertNameLabel
|
id: insertNameLabel
|
||||||
@ -182,8 +258,7 @@ Item
|
|||||||
TextField
|
TextField
|
||||||
{
|
{
|
||||||
id: machineName;
|
id: machineName;
|
||||||
anchors.top: insertNameLabel.bottom
|
text: getMachineName()
|
||||||
text: machineList.model.getItem(machineList.currentIndex).name
|
|
||||||
implicitWidth: UM.Theme.sizes.standard_list_input.width
|
implicitWidth: UM.Theme.sizes.standard_list_input.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,6 +293,9 @@ Item
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(base.wizard.lastPage == true){
|
||||||
|
base.wizard.visible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import QtQuick.Layouts 1.1
|
|||||||
import QtQuick.Window 2.1
|
import QtQuick.Window 2.1
|
||||||
|
|
||||||
import UM 1.1 as UM
|
import UM 1.1 as UM
|
||||||
|
import Cura 1.0 as Cura
|
||||||
|
import ".."
|
||||||
|
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
@ -15,11 +17,22 @@ Item
|
|||||||
property bool three_point_leveling: true
|
property bool three_point_leveling: true
|
||||||
property int platform_width: UM.MachineManager.getSettingValue("machine_width")
|
property int platform_width: UM.MachineManager.getSettingValue("machine_width")
|
||||||
property int platform_height: UM.MachineManager.getSettingValue("machine_depth")
|
property int platform_height: UM.MachineManager.getSettingValue("machine_depth")
|
||||||
property bool alreadyTested: base.addOriginalProgress.bedLeveling
|
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||||
Component.onCompleted: printer_connection.homeHead()
|
Component.onCompleted: printer_connection.homeHead()
|
||||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||||
|
property variant wizard: null;
|
||||||
|
|
||||||
|
Connections
|
||||||
|
{
|
||||||
|
target: wizardPage.wizard
|
||||||
|
onNextClicked: //You can add functions here that get triggered when the final button is clicked in the wizard-element
|
||||||
|
{
|
||||||
|
if(wizardPage.wizard.lastPage == true){
|
||||||
|
wizardPage.wizard.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
@ -61,7 +74,6 @@ Item
|
|||||||
id: bedlevelingButton
|
id: bedlevelingButton
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
enabled: !alreadyTested
|
|
||||||
text: catalog.i18nc("@action:button","Move to Next Position");
|
text: catalog.i18nc("@action:button","Move to Next Position");
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
@ -79,7 +91,6 @@ Item
|
|||||||
}
|
}
|
||||||
wizardPage.leveling_state++
|
wizardPage.leveling_state++
|
||||||
if (wizardPage.leveling_state >= 3){
|
if (wizardPage.leveling_state >= 3){
|
||||||
base.addOriginalProgress.bedLeveling = true
|
|
||||||
resultText.visible = true
|
resultText.visible = true
|
||||||
skipBedlevelingButton.enabled = false
|
skipBedlevelingButton.enabled = false
|
||||||
bedlevelingButton.enabled = false
|
bedlevelingButton.enabled = false
|
||||||
@ -91,7 +102,6 @@ Item
|
|||||||
Button
|
Button
|
||||||
{
|
{
|
||||||
id: skipBedlevelingButton
|
id: skipBedlevelingButton
|
||||||
enabled: !alreadyTested
|
|
||||||
anchors.top: parent.width < wizardPage.width ? parent.top : bedlevelingButton.bottom
|
anchors.top: parent.width < wizardPage.width ? parent.top : bedlevelingButton.bottom
|
||||||
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.sizes.default_margin.height/2
|
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.sizes.default_margin.height/2
|
||||||
anchors.left: parent.width < wizardPage.width ? bedlevelingButton.right : parent.left
|
anchors.left: parent.width < wizardPage.width ? bedlevelingButton.right : parent.left
|
||||||
@ -104,13 +114,13 @@ Item
|
|||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: resultText
|
id: resultText
|
||||||
visible: alreadyTested
|
visible: false
|
||||||
anchors.top: bedlevelingWrapper.bottom
|
anchors.top: bedlevelingWrapper.bottom
|
||||||
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: catalog.i18nc("@label", "Everythink is in order! You're done with bedeleveling.")
|
text: catalog.i18nc("@label", "Everything is in order! You're done with bedleveling.")
|
||||||
}
|
}
|
||||||
|
|
||||||
function threePointLeveling(width, height)
|
function threePointLeveling(width, height)
|
||||||
|
@ -17,11 +17,8 @@ Item
|
|||||||
|
|
||||||
Component.onDestruction:
|
Component.onDestruction:
|
||||||
{
|
{
|
||||||
base.addOriginalProgress.upgrades[0] = extruderCheckBox.checked
|
|
||||||
base.addOriginalProgress.upgrades[1] = heatedBedCheckBox1.checked
|
|
||||||
base.addOriginalProgress.upgrades[2] = heatedBedCheckBox2.checked
|
|
||||||
if (extruderCheckBox.checked == true){
|
if (extruderCheckBox.checked == true){
|
||||||
UM.MachineManager.setMachineSettingValue("machine_extruder_drive_upgrade", true);
|
UM.MachineManager.setMachineSettingValue("machine_extruder_drive_upgrade", true)
|
||||||
}
|
}
|
||||||
if (heatedBedCheckBox1.checked == true || heatedBedCheckBox2.checked == true){
|
if (heatedBedCheckBox1.checked == true || heatedBedCheckBox2.checked == true){
|
||||||
UM.MachineManager.setMachineSettingValue("machine_heated_bed", true)
|
UM.MachineManager.setMachineSettingValue("machine_heated_bed", true)
|
||||||
@ -58,14 +55,14 @@ Item
|
|||||||
{
|
{
|
||||||
id: extruderCheckBox
|
id: extruderCheckBox
|
||||||
text: catalog.i18nc("@option:check","Extruder driver ugrades")
|
text: catalog.i18nc("@option:check","Extruder driver ugrades")
|
||||||
checked: base.addOriginalProgress.upgrades[0]
|
checked: true
|
||||||
}
|
}
|
||||||
CheckBox
|
CheckBox
|
||||||
{
|
{
|
||||||
id: heatedBedCheckBox1
|
id: heatedBedCheckBox1
|
||||||
text: catalog.i18nc("@option:check","Heated printer bed (standard kit)")
|
text: catalog.i18nc("@option:check","Heated printer bed")
|
||||||
y: extruderCheckBox.height * 1
|
y: extruderCheckBox.height * 1
|
||||||
checked: base.addOriginalProgress.upgrades[1]
|
checked: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (heatedBedCheckBox2.checked == true)
|
if (heatedBedCheckBox2.checked == true)
|
||||||
heatedBedCheckBox2.checked = false
|
heatedBedCheckBox2.checked = false
|
||||||
@ -76,7 +73,7 @@ Item
|
|||||||
id: heatedBedCheckBox2
|
id: heatedBedCheckBox2
|
||||||
text: catalog.i18nc("@option:check","Heated printer bed (self built)")
|
text: catalog.i18nc("@option:check","Heated printer bed (self built)")
|
||||||
y: extruderCheckBox.height * 2
|
y: extruderCheckBox.height * 2
|
||||||
checked: base.addOriginalProgress.upgrades[2]
|
checked: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (heatedBedCheckBox1.checked == true)
|
if (heatedBedCheckBox1.checked == true)
|
||||||
heatedBedCheckBox1.checked = false
|
heatedBedCheckBox1.checked = false
|
||||||
|
@ -14,35 +14,40 @@ Item
|
|||||||
property int leftRow: wizardPage.width*0.40
|
property int leftRow: wizardPage.width*0.40
|
||||||
property int rightRow: wizardPage.width*0.60
|
property int rightRow: wizardPage.width*0.60
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
property bool alreadyTested: base.addOriginalProgress.checkUp[base.addOriginalProgress.checkUp.length-1]
|
|
||||||
property bool x_min_pressed: false
|
property bool x_min_pressed: false
|
||||||
property bool y_min_pressed: false
|
property bool y_min_pressed: false
|
||||||
property bool z_min_pressed: false
|
property bool z_min_pressed: false
|
||||||
property bool heater_works: false
|
property bool heater_works: false
|
||||||
property int extruder_target_temp: 0
|
property int extruder_target_temp: 0
|
||||||
property int bed_target_temp: 0
|
property int bed_target_temp: 0
|
||||||
|
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||||
|
property var checkupProgress: {
|
||||||
|
"connection": false,
|
||||||
|
"endstopX": wizardPage.x_min_pressed,
|
||||||
|
"endstopY": wizardPage.y_min_pressed,
|
||||||
|
"endstopZ": wizardPage.z_min_pressed,
|
||||||
|
"nozzleTemp": false,
|
||||||
|
"bedTemp": false
|
||||||
|
}
|
||||||
|
|
||||||
property variant printer_connection: {
|
property variant printer_connection: {
|
||||||
if (UM.USBPrinterManager.connectedPrinterList.rowCount() != 0){
|
if (UM.USBPrinterManager.connectedPrinterList.rowCount() != 0){
|
||||||
base.addOriginalProgress.checkUp[0] = true
|
wizardPage.checkupProgress.connection = true
|
||||||
checkTotalCheckUp()
|
|
||||||
return UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
return UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
|
||||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
|
||||||
|
|
||||||
function checkTotalCheckUp(){
|
function checkTotalCheckUp(){
|
||||||
var allDone = true
|
var allDone = true
|
||||||
for (var i = 0; i < (base.addOriginalProgress.checkUp.length - 1); i++){
|
for(var property in checkupProgress){
|
||||||
if (base.addOriginalProgress.checkUp[i] == false){
|
if (checkupProgress[property] == false){
|
||||||
allDone = false
|
allDone = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allDone == true){
|
if (allDone == true){
|
||||||
base.addOriginalProgress.checkUp[base.addOriginalProgress.checkUp.length] = true
|
|
||||||
skipCheckButton.enabled = false
|
skipCheckButton.enabled = false
|
||||||
resultText.visible = true
|
resultText.visible = true
|
||||||
}
|
}
|
||||||
@ -91,7 +96,7 @@ Item
|
|||||||
id: startCheckButton
|
id: startCheckButton
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
enabled: !alreadyTested
|
//enabled: !alreadyTested
|
||||||
text: catalog.i18nc("@action:button","Start Printer Check");
|
text: catalog.i18nc("@action:button","Start Printer Check");
|
||||||
onClicked: {
|
onClicked: {
|
||||||
checkupContent.visible = true
|
checkupContent.visible = true
|
||||||
@ -107,7 +112,7 @@ Item
|
|||||||
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.sizes.default_margin.height/2
|
anchors.topMargin: parent.width < wizardPage.width ? 0 : UM.Theme.sizes.default_margin.height/2
|
||||||
anchors.left: parent.width < wizardPage.width ? startCheckButton.right : parent.left
|
anchors.left: parent.width < wizardPage.width ? startCheckButton.right : parent.left
|
||||||
anchors.leftMargin: parent.width < wizardPage.width ? UM.Theme.sizes.default_margin.width : 0
|
anchors.leftMargin: parent.width < wizardPage.width ? UM.Theme.sizes.default_margin.width : 0
|
||||||
enabled: !alreadyTested
|
//enabled: !alreadyTested
|
||||||
text: catalog.i18nc("@action:button","Skip Printer Check");
|
text: catalog.i18nc("@action:button","Skip Printer Check");
|
||||||
onClicked: {
|
onClicked: {
|
||||||
base.currentPage += 1
|
base.currentPage += 1
|
||||||
@ -119,7 +124,7 @@ Item
|
|||||||
id: checkupContent
|
id: checkupContent
|
||||||
anchors.top: startStopButtons.bottom
|
anchors.top: startStopButtons.bottom
|
||||||
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
||||||
visible: alreadyTested
|
visible: false
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
@ -156,7 +161,7 @@ Item
|
|||||||
anchors.left: endstopXLabel.right
|
anchors.left: endstopXLabel.right
|
||||||
anchors.top: connectionLabel.bottom
|
anchors.top: connectionLabel.bottom
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: x_min_pressed || base.addOriginalProgress.checkUp[1] ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
text: x_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
Label
|
Label
|
||||||
@ -175,7 +180,7 @@ Item
|
|||||||
anchors.left: endstopYLabel.right
|
anchors.left: endstopYLabel.right
|
||||||
anchors.top: endstopXLabel.bottom
|
anchors.top: endstopXLabel.bottom
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: y_min_pressed || base.addOriginalProgress.checkUp[2] ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
text: y_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
Label
|
Label
|
||||||
@ -194,7 +199,7 @@ Item
|
|||||||
anchors.left: endstopZLabel.right
|
anchors.left: endstopZLabel.right
|
||||||
anchors.top: endstopYLabel.bottom
|
anchors.top: endstopYLabel.bottom
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: z_min_pressed || base.addOriginalProgress.checkUp[3] ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
text: z_min_pressed ? catalog.i18nc("@info:status","Works") : catalog.i18nc("@info:status","Not checked")
|
||||||
}
|
}
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Label
|
Label
|
||||||
@ -233,14 +238,9 @@ Item
|
|||||||
{
|
{
|
||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
if (alreadyTested){
|
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||||
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
printer_connection.heatupNozzle(190)
|
||||||
}
|
wizardPage.extruder_target_temp = 190
|
||||||
else {
|
|
||||||
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
|
||||||
printer_connection.heatupNozzle(190)
|
|
||||||
wizardPage.extruder_target_temp = 190
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,14 +294,9 @@ Item
|
|||||||
{
|
{
|
||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
if (alreadyTested){
|
bedTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||||
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
printer_connection.heatupBed(60)
|
||||||
}
|
wizardPage.bed_target_temp = 60
|
||||||
else {
|
|
||||||
bedTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
|
||||||
printer_connection.heatupBed(60)
|
|
||||||
wizardPage.bed_target_temp = 60
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +315,7 @@ Item
|
|||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: resultText
|
id: resultText
|
||||||
visible: base.addOriginalProgress.checkUp[base.addOriginalProgress.checkUp.length-1]
|
visible: false
|
||||||
anchors.top: bedTemp.bottom
|
anchors.top: bedTemp.bottom
|
||||||
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
anchors.topMargin: UM.Theme.sizes.default_margin.height
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@ -338,19 +333,16 @@ Item
|
|||||||
{
|
{
|
||||||
if(key == "x_min")
|
if(key == "x_min")
|
||||||
{
|
{
|
||||||
base.addOriginalProgress.checkUp[1] = true
|
|
||||||
x_min_pressed = true
|
x_min_pressed = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
}
|
}
|
||||||
if(key == "y_min")
|
if(key == "y_min")
|
||||||
{
|
{
|
||||||
base.addOriginalProgress.checkUp[2] = true
|
|
||||||
y_min_pressed = true
|
y_min_pressed = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
}
|
}
|
||||||
if(key == "z_min")
|
if(key == "z_min")
|
||||||
{
|
{
|
||||||
base.addOriginalProgress.checkUp[3] = true
|
|
||||||
z_min_pressed = true
|
z_min_pressed = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
}
|
}
|
||||||
@ -363,7 +355,7 @@ Item
|
|||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||||
base.addOriginalProgress.checkUp[4] = true
|
wizardPage.checkupProgress.nozzleTemp = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
printer_connection.heatupNozzle(0)
|
printer_connection.heatupNozzle(0)
|
||||||
}
|
}
|
||||||
@ -374,7 +366,7 @@ Item
|
|||||||
if(printer_connection.bedTemperature > wizardPage.bed_target_temp - 5 && printer_connection.bedTemperature < wizardPage.bed_target_temp + 5)
|
if(printer_connection.bedTemperature > wizardPage.bed_target_temp - 5 && printer_connection.bedTemperature < wizardPage.bed_target_temp + 5)
|
||||||
{
|
{
|
||||||
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||||
base.addOriginalProgress.checkUp[5] = true
|
wizardPage.checkupProgress.bedTemp = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
printer_connection.heatupBed(0)
|
printer_connection.heatupBed(0)
|
||||||
}
|
}
|
||||||
|
50
resources/themes/cura/icons/check.svg
Normal file
50
resources/themes/cura/icons/check.svg
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="Capa_1"
|
||||||
|
x="0px"
|
||||||
|
y="0px"
|
||||||
|
width="415.582px"
|
||||||
|
height="415.582px"
|
||||||
|
viewBox="0 0 415.582 415.582"
|
||||||
|
style="enable-background:new 0 0 415.582 415.582;"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="check.svg"><metadata
|
||||||
|
id="metadata11"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs9" /><sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1134"
|
||||||
|
id="namedview7"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.61"
|
||||||
|
inkscape:cx="211.31288"
|
||||||
|
inkscape:cy="137.35337"
|
||||||
|
inkscape:window-x="1440"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="Capa_1" /><g
|
||||||
|
id="g3"><path
|
||||||
|
d="m 411.47,96.426 -34.319,-34.32 c -5.48192,-5.482079 -14.34421,-5.455083 -19.853,0 L 152.348,265.058 56.282,174.994 c -5.48,-5.482 -14.37,-5.482 -19.851,0 l -32.319,32.32 c -5.482,5.481 -5.482,14.37 0,19.852 l 138.311,138.31 c 2.741,2.742 6.334,4.112 9.926,4.112 3.593,0 7.186,-1.37 9.926,-4.112 L 411.47,116.277 c 2.633,-2.632 4.111,-6.203 4.111,-9.925 10e-4,-3.724 -1.47804,-7.29296 -4.111,-9.926 z"
|
||||||
|
id="path5"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssccccscscccs" /></g></svg>
|
After Width: | Height: | Size: 2.1 KiB |
@ -66,6 +66,7 @@
|
|||||||
"text_hover": [35, 35, 35, 255],
|
"text_hover": [35, 35, 35, 255],
|
||||||
"text_pressed": [12, 169, 227, 255],
|
"text_pressed": [12, 169, 227, 255],
|
||||||
|
|
||||||
|
"error": [255, 140, 0, 255],
|
||||||
"sidebar_header_bar": [12, 169, 227, 255],
|
"sidebar_header_bar": [12, 169, 227, 255],
|
||||||
|
|
||||||
"button": [139, 143, 153, 255],
|
"button": [139, 143, 153, 255],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user