mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-13 19:25:58 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
a321bd588b
21
CHANGES
21
CHANGES
@ -7,6 +7,24 @@ Cura 15.06 is a new release built from the ground up on a completely new
|
||||
framework called Uranium. This framework has been designed to make it easier to
|
||||
extend Cura with additional functionality as well as provide a cleaner UI.
|
||||
|
||||
Changes since 15.05.93
|
||||
----------------------
|
||||
|
||||
* Fixed: No shortcuts for moving up/down layers in layer view.
|
||||
* Fixed: Last view layers could not be scrolled through in layer view.
|
||||
* Fixed: Files provided on command line would not actually show up on the build
|
||||
platform.
|
||||
* Fixed: Render a ghost of the selection in Layer view to make the actual object
|
||||
position clear.
|
||||
* Fixed: Showing a menu would clear the selection.
|
||||
* Fixed: Size and scaling factor display for scale tool.
|
||||
* Fixed: Missing background for additional tool controls.
|
||||
* Fixed: Loading message times out when loading large files.
|
||||
* Fixed: Show recent files in the file menu.
|
||||
* Fixed: Windows installer will now install MSVC 2010 redistributable, to
|
||||
prevent issues with missing DLL's.
|
||||
* Fixed: Collapsed/expanded state of setting categories not stored.
|
||||
|
||||
Changes since 15.05.91
|
||||
----------------------
|
||||
|
||||
@ -26,7 +44,8 @@ Changes since 15.05.91
|
||||
* Fixed: Camera panning now works correctly instead of doing nothing.
|
||||
* Fixed: Camera would flip around center point at maximum rotation.
|
||||
* Fixed: Build platform grid blocked view from below objects.
|
||||
* Fixed: Viewport on MacOSX with high-DPI screens was only taking 1/4th of the window
|
||||
* Fixed: Viewport on MacOSX with high-DPI screens was only taking 1/4th of the
|
||||
window
|
||||
|
||||
Changes since 15.05.90
|
||||
----------------------
|
||||
|
@ -1,7 +1,9 @@
|
||||
Cura
|
||||
====
|
||||
|
||||
This is the source code of Cura.
|
||||
This is the new, shiny, unreleased frontend for Cura. [daid/Cura](https://github.com/daid/Cura.git) is the old legacy Cura that everyone knows and loves/hates.
|
||||
|
||||
We re-worked the whole GUI code at Ultimaker, because my old code started to become an unmaintainable ball of poo.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
@ -12,3 +14,8 @@ Dependencies
|
||||
This will be needed at runtime to perform the actual slicing.
|
||||
* PySerial
|
||||
Only required for USB printing support.
|
||||
|
||||
Build scripts
|
||||
-------------
|
||||
|
||||
Please checkout [cura-build](https://github.com/Ultimaker/cura-build)
|
||||
|
@ -48,6 +48,9 @@ class ConvexHullNode(SceneNode):
|
||||
|
||||
self.setMeshData(mesh)
|
||||
|
||||
def getWatchedNode(self):
|
||||
return self._node
|
||||
|
||||
def render(self, renderer):
|
||||
if not self._material:
|
||||
self._material = renderer.createMaterial(Resources.getPath(Resources.ShadersLocation, "basic.vert"), Resources.getPath(Resources.ShadersLocation, "color.frag"))
|
||||
|
@ -17,6 +17,7 @@ from UM.Logger import Logger
|
||||
from UM.Preferences import Preferences
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.JobQueue import JobQueue
|
||||
|
||||
from UM.Scene.BoxRenderer import BoxRenderer
|
||||
from UM.Scene.Selection import Selection
|
||||
@ -71,6 +72,18 @@ class CuraApplication(QtApplication):
|
||||
|
||||
Preferences.getInstance().addPreference("cura/active_machine", "")
|
||||
Preferences.getInstance().addPreference("cura/active_mode", "simple")
|
||||
Preferences.getInstance().addPreference("cura/recent_files", "")
|
||||
Preferences.getInstance().addPreference("cura/categories_expanded", "")
|
||||
|
||||
JobQueue.getInstance().jobFinished.connect(self._onJobFinished)
|
||||
|
||||
self._recent_files = []
|
||||
files = Preferences.getInstance().getValue("cura/recent_files").split(";")
|
||||
for f in files:
|
||||
if not os.path.isfile(f):
|
||||
continue
|
||||
|
||||
self._recent_files.append(f)
|
||||
|
||||
## Handle loading of all plugin types (and the backend explicitly)
|
||||
# \sa PluginRegistery
|
||||
@ -305,6 +318,25 @@ class CuraApplication(QtApplication):
|
||||
|
||||
return log
|
||||
|
||||
recentFilesChanged = pyqtSignal()
|
||||
@pyqtProperty("QStringList", notify = recentFilesChanged)
|
||||
def recentFiles(self):
|
||||
return self._recent_files
|
||||
|
||||
@pyqtSlot("QStringList")
|
||||
def setExpandedCategories(self, categories):
|
||||
categories = list(set(categories))
|
||||
categories.sort()
|
||||
joined = ";".join(categories)
|
||||
if joined != Preferences.getInstance().getValue("cura/categories_expanded"):
|
||||
Preferences.getInstance().setValue("cura/categories_expanded", joined)
|
||||
self.expandedCategoriesChanged.emit()
|
||||
|
||||
expandedCategoriesChanged = pyqtSignal()
|
||||
@pyqtProperty("QStringList", notify = expandedCategoriesChanged)
|
||||
def expandedCategories(self):
|
||||
return Preferences.getInstance().getValue("cura/categories_expanded").split(";")
|
||||
|
||||
outputDevicesChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty("QVariantMap", notify = outputDevicesChanged)
|
||||
@ -460,3 +492,18 @@ class CuraApplication(QtApplication):
|
||||
|
||||
op = AddSceneNodeOperation(node, self.getController().getScene().getRoot())
|
||||
op.push()
|
||||
|
||||
def _onJobFinished(self, job):
|
||||
if type(job) is not ReadMeshJob:
|
||||
return
|
||||
|
||||
f = job.getFileName()
|
||||
if f in self._recent_files:
|
||||
self._recent_files.remove(f)
|
||||
|
||||
self._recent_files.insert(0, f)
|
||||
if len(self._recent_files) > 10:
|
||||
del self._recent_files[10]
|
||||
|
||||
Preferences.getInstance().setValue("cura/recent_files", ";".join(self._recent_files))
|
||||
self.recentFilesChanged.emit()
|
||||
|
@ -99,6 +99,15 @@ Function LaunchLink
|
||||
Exec '"$WINDIR\explorer.exe" "$SMPROGRAMS\Cura ${VERSION}\Cura ${VERSION}.lnk"'
|
||||
FunctionEnd
|
||||
|
||||
Section "Install Visual Studio 2010 Redistributable"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "vcredist_2010_x86.exe"
|
||||
|
||||
IfSilent +2
|
||||
ExecWait '"$INSTDIR\vcredist_2010_x86.exe"'
|
||||
|
||||
SectionEnd
|
||||
|
||||
;Section "Install Arduino Drivers"
|
||||
; ; Set output path to the driver directory.
|
||||
; SetOutPath "$INSTDIR\drivers\"
|
||||
|
@ -1,6 +1,3 @@
|
||||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: Cura.proto
|
||||
|
||||
@ -21,7 +18,7 @@ _sym_db = _symbol_database.Default()
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='Cura.proto',
|
||||
package='Cura',
|
||||
serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"i\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\x12\x1f\n\x08settings\x18\x05 \x03(\x0b\x32\r.Cura.Setting\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"D\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x12\x17\n\x0fmaterial_amount\x18\x03 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"\x1b\n\x0bGCodePrefix\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x62\x06proto3')
|
||||
serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"i\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\x12\x1f\n\x08settings\x18\x05 \x03(\x0b\x32\r.Cura.Setting\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"W\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0e\n\x06height\x18\x02 \x01(\x02\x12\x11\n\tthickness\x18\x03 \x01(\x02\x12\x1f\n\x08polygons\x18\x04 \x03(\x0b\x32\r.Cura.Polygon\"\xdb\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\x12\x12\n\nline_width\x18\x03 \x01(\x02\"\x89\x01\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\x12\x0e\n\nInfillType\x10\x06\x12\x15\n\x11SupportInfillType\x10\x07\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"D\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x12\x17\n\x0fmaterial_amount\x18\x03 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"\x1b\n\x0bGCodePrefix\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x62\x06proto3')
|
||||
)
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
@ -57,11 +54,19 @@ _POLYGON_TYPE = _descriptor.EnumDescriptor(
|
||||
name='SkirtType', index=5, number=5,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='InfillType', index=6, number=6,
|
||||
options=None,
|
||||
type=None),
|
||||
_descriptor.EnumValueDescriptor(
|
||||
name='SupportInfillType', index=7, number=7,
|
||||
options=None,
|
||||
type=None),
|
||||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=430,
|
||||
serialized_end=528,
|
||||
serialized_start=486,
|
||||
serialized_end=623,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_POLYGON_TYPE)
|
||||
|
||||
@ -266,8 +271,22 @@ _LAYER = _descriptor.Descriptor(
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='polygons', full_name='Cura.Layer.polygons', index=1,
|
||||
number=2, type=11, cpp_type=10, label=3,
|
||||
name='height', full_name='Cura.Layer.height', index=1,
|
||||
number=2, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='thickness', full_name='Cura.Layer.thickness', index=2,
|
||||
number=3, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='polygons', full_name='Cura.Layer.polygons', index=3,
|
||||
number=4, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
@ -284,7 +303,7 @@ _LAYER = _descriptor.Descriptor(
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=314,
|
||||
serialized_end=366,
|
||||
serialized_end=401,
|
||||
)
|
||||
|
||||
|
||||
@ -309,6 +328,13 @@ _POLYGON = _descriptor.Descriptor(
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='line_width', full_name='Cura.Polygon.line_width', index=2,
|
||||
number=3, type=2, cpp_type=6, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
@ -321,8 +347,8 @@ _POLYGON = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=369,
|
||||
serialized_end=528,
|
||||
serialized_start=404,
|
||||
serialized_end=623,
|
||||
)
|
||||
|
||||
|
||||
@ -358,8 +384,8 @@ _GCODELAYER = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=530,
|
||||
serialized_end=568,
|
||||
serialized_start=625,
|
||||
serialized_end=663,
|
||||
)
|
||||
|
||||
|
||||
@ -402,8 +428,8 @@ _OBJECTPRINTTIME = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=570,
|
||||
serialized_end=638,
|
||||
serialized_start=665,
|
||||
serialized_end=733,
|
||||
)
|
||||
|
||||
|
||||
@ -432,8 +458,8 @@ _SETTINGLIST = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=640,
|
||||
serialized_end=686,
|
||||
serialized_start=735,
|
||||
serialized_end=781,
|
||||
)
|
||||
|
||||
|
||||
@ -469,8 +495,8 @@ _SETTING = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=688,
|
||||
serialized_end=726,
|
||||
serialized_start=783,
|
||||
serialized_end=821,
|
||||
)
|
||||
|
||||
|
||||
@ -499,8 +525,8 @@ _GCODEPREFIX = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=728,
|
||||
serialized_end=755,
|
||||
serialized_start=823,
|
||||
serialized_end=850,
|
||||
)
|
||||
|
||||
_OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT
|
||||
|
@ -2,7 +2,9 @@
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from UM.Mesh.MeshData import MeshData
|
||||
from UM.Mesh.MeshBuilder import MeshBuilder
|
||||
from UM.Math.Color import Color
|
||||
from UM.Math.Vector import Vector
|
||||
|
||||
import numpy
|
||||
import math
|
||||
@ -13,12 +15,19 @@ class LayerData(MeshData):
|
||||
self._layers = {}
|
||||
self._element_counts = {}
|
||||
|
||||
def addPolygon(self, layer, type, data):
|
||||
def addLayer(self, layer):
|
||||
if layer not in self._layers:
|
||||
self._layers[layer] = []
|
||||
self._layers[layer] = Layer(layer)
|
||||
|
||||
p = Polygon(self, type, data)
|
||||
self._layers[layer].append(p)
|
||||
def addPolygon(self, layer, type, data, line_width):
|
||||
if layer not in self._layers:
|
||||
self.addLayer(layer)
|
||||
|
||||
p = Polygon(self, type, data, line_width)
|
||||
self._layers[layer].polygons.append(p)
|
||||
|
||||
def getLayer(self, layer):
|
||||
return self._layers[layer]
|
||||
|
||||
def getLayers(self):
|
||||
return self._layers
|
||||
@ -26,14 +35,112 @@ class LayerData(MeshData):
|
||||
def getElementCounts(self):
|
||||
return self._element_counts
|
||||
|
||||
def setLayerHeight(self, layer, height):
|
||||
if layer not in self._layers:
|
||||
self.addLayer(layer)
|
||||
|
||||
self._layers[layer].setHeight(height)
|
||||
|
||||
def setLayerThickness(self, layer, thickness):
|
||||
if layer not in self._layers:
|
||||
self.addLayer(layer)
|
||||
|
||||
self._layers[layer].setThickness(thickness)
|
||||
|
||||
def build(self):
|
||||
for layer, data in self._layers.items():
|
||||
if layer not in self._element_counts:
|
||||
self._element_counts[layer] = []
|
||||
data.build()
|
||||
|
||||
for polygon in data:
|
||||
polygon.build()
|
||||
self._element_counts[layer].append(polygon.elementCount)
|
||||
self._element_counts[layer] = data.elementCount
|
||||
|
||||
class Layer():
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
self._height = 0.0
|
||||
self._thickness = 0.0
|
||||
self._polygons = []
|
||||
self._element_count = 0
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self._height
|
||||
|
||||
@property
|
||||
def thickness(self):
|
||||
return self._thickness
|
||||
|
||||
@property
|
||||
def polygons(self):
|
||||
return self._polygons
|
||||
|
||||
@property
|
||||
def elementCount(self):
|
||||
return self._element_count
|
||||
|
||||
def setHeight(self, height):
|
||||
self._height = height
|
||||
|
||||
def setThickness(self, thickness):
|
||||
self._thickness = thickness
|
||||
|
||||
def build(self):
|
||||
for polygon in self._polygons:
|
||||
if polygon._type == Polygon.InfillType or polygon._type == Polygon.SupportInfillType:
|
||||
continue
|
||||
|
||||
polygon.build()
|
||||
self._element_count += polygon.elementCount
|
||||
|
||||
def createMesh(self):
|
||||
builder = MeshBuilder()
|
||||
|
||||
for polygon in self._polygons:
|
||||
poly_color = polygon.getColor()
|
||||
poly_color = Color(poly_color[0], poly_color[1], poly_color[2], poly_color[3])
|
||||
|
||||
points = numpy.copy(polygon.data)
|
||||
if polygon.type == Polygon.InfillType or polygon.type == Polygon.SkinType or polygon.type == Polygon.SupportInfillType:
|
||||
points[:,1] -= 0.01
|
||||
|
||||
# Calculate normals for the entire polygon using numpy.
|
||||
normals = numpy.copy(points)
|
||||
normals[:,1] = 0.0 # We are only interested in 2D normals
|
||||
|
||||
# Calculate the edges between points.
|
||||
# The call to numpy.roll shifts the entire array by one so that
|
||||
# we end up subtracting each next point from the current, wrapping
|
||||
# around. This gives us the edges from the next point to the current
|
||||
# point.
|
||||
normals[:] = normals[:] - numpy.roll(normals, -1, axis = 0)
|
||||
# Calculate the length of each edge using standard Pythagoras
|
||||
lengths = numpy.sqrt(normals[:,0] ** 2 + normals[:,2] ** 2)
|
||||
# The normal of a 2D vector is equal to its x and y coordinates swapped
|
||||
# and then x inverted. This code does that.
|
||||
normals[:,[0, 2]] = normals[:,[2, 0]]
|
||||
normals[:,0] *= -1
|
||||
|
||||
# Normalize the normals.
|
||||
normals[:,0] /= lengths
|
||||
normals[:,2] /= lengths
|
||||
|
||||
# Scale all by the line width of the polygon so we can easily offset.
|
||||
normals *= (polygon.lineWidth / 2)
|
||||
|
||||
#TODO: Use numpy magic to perform the vertex creation to speed up things.
|
||||
for i in range(len(points)):
|
||||
start = points[i - 1]
|
||||
end = points[i]
|
||||
|
||||
normal = normals[i - 1]
|
||||
|
||||
point1 = Vector(data = start - normal)
|
||||
point2 = Vector(data = start + normal)
|
||||
point3 = Vector(data = end + normal)
|
||||
point4 = Vector(data = end - normal)
|
||||
|
||||
builder.addQuad(point1, point2, point3, point4, color = poly_color)
|
||||
|
||||
return builder.getData()
|
||||
|
||||
class Polygon():
|
||||
NoneType = 0
|
||||
@ -42,34 +149,26 @@ class Polygon():
|
||||
SkinType = 3
|
||||
SupportType = 4
|
||||
SkirtType = 5
|
||||
InfillType = 6
|
||||
SupportInfillType = 7
|
||||
|
||||
def __init__(self, mesh, type, data):
|
||||
def __init__(self, mesh, type, data, line_width):
|
||||
super().__init__()
|
||||
self._mesh = mesh
|
||||
self._type = type
|
||||
self._data = data
|
||||
self._line_width = line_width / 1000
|
||||
|
||||
def build(self):
|
||||
self._begin = self._mesh._vertex_count
|
||||
self._mesh.addVertices(self._data)
|
||||
self._end = self._begin + len(self._data) - 1
|
||||
|
||||
color = None
|
||||
if self._type == self.Inset0Type:
|
||||
color = [1, 0, 0, 1]
|
||||
elif self._type == self.InsetXType:
|
||||
color = [0, 1, 0, 1]
|
||||
elif self._type == self.SkinType:
|
||||
color = [1, 1, 0, 1]
|
||||
elif self._type == self.SupportType:
|
||||
color = [0, 1, 1, 1]
|
||||
elif self._type == self.SkirtType:
|
||||
color = [0, 1, 1, 1]
|
||||
else:
|
||||
color = [1, 1, 1, 1]
|
||||
color = self.getColor()
|
||||
color[3] = 2.0
|
||||
|
||||
colors = [color for i in range(len(self._data))]
|
||||
self._mesh.addColors(numpy.array(colors, dtype=numpy.float32))
|
||||
self._mesh.addColors(numpy.array(colors, dtype=numpy.float32) * 0.5)
|
||||
|
||||
indices = []
|
||||
for i in range(self._begin, self._end):
|
||||
@ -80,6 +179,24 @@ class Polygon():
|
||||
indices.append(self._begin)
|
||||
self._mesh.addIndices(numpy.array(indices, dtype=numpy.int32))
|
||||
|
||||
def getColor(self):
|
||||
if self._type == self.Inset0Type:
|
||||
return [1.0, 0.0, 0.0, 1.0]
|
||||
elif self._type == self.InsetXType:
|
||||
return [0.0, 1.0, 0.0, 1.0]
|
||||
elif self._type == self.SkinType:
|
||||
return [1.0, 1.0, 0.0, 1.0]
|
||||
elif self._type == self.SupportType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
elif self._type == self.SkirtType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
elif self._type == self.InfillType:
|
||||
return [1.0, 1.0, 0.0, 1.0]
|
||||
elif self._type == self.SupportInfillType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
else:
|
||||
return [1.0, 1.0, 1.0, 1.0]
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._type
|
||||
@ -90,4 +207,8 @@ class Polygon():
|
||||
|
||||
@property
|
||||
def elementCount(self):
|
||||
return (self._end - self._begin) * 2 #The range of vertices multiplied by 2 since each vertex is used twice
|
||||
return ((self._end - self._begin) + 1) * 2 #The range of vertices multiplied by 2 since each vertex is used twice
|
||||
|
||||
@property
|
||||
def lineWidth(self):
|
||||
return self._line_width
|
||||
|
@ -32,22 +32,24 @@ class ProcessSlicedObjectListJob(Job):
|
||||
settings = Application.getInstance().getActiveMachine()
|
||||
layerHeight = settings.getSettingValueByKey("layer_height")
|
||||
|
||||
mesh = MeshData()
|
||||
for object in self._message.objects:
|
||||
try:
|
||||
try:
|
||||
node = objectIdMap[object.id]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
mesh = MeshData()
|
||||
|
||||
layerData = LayerData.LayerData()
|
||||
for layer in object.layers:
|
||||
layerData.addLayer(layer.id)
|
||||
layerData.setLayerHeight(layer.id, layer.height)
|
||||
layerData.setLayerThickness(layer.id, layer.thickness)
|
||||
for polygon in layer.polygons:
|
||||
points = numpy.fromstring(polygon.points, dtype="i8") # Convert bytearray to numpy array
|
||||
points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly.
|
||||
points = numpy.asarray(points, dtype=numpy.float32)
|
||||
points /= 1000
|
||||
points = numpy.insert(points, 1, layer.id * layerHeight, axis = 1)
|
||||
points = numpy.insert(points, 1, (layer.height / 1000), axis = 1)
|
||||
|
||||
points[:,2] *= -1
|
||||
|
||||
@ -55,16 +57,11 @@ class ProcessSlicedObjectListJob(Job):
|
||||
center = [settings.getSettingValueByKey("machine_width") / 2, 0.0, -settings.getSettingValueByKey("machine_depth") / 2]
|
||||
points -= numpy.array(center)
|
||||
|
||||
#points = numpy.pad(points, ((0,0), (0,1)), "constant", constant_values=(0.0, 1.0))
|
||||
#inverse = node.getWorldTransformation().getInverse().getData()
|
||||
#points = points.dot(inverse)
|
||||
#points = points[:,0:3]
|
||||
layerData.addPolygon(layer.id, polygon.type, points, polygon.line_width)
|
||||
|
||||
layerData.addPolygon(layer.id, polygon.type, points)
|
||||
# We are done processing all the layers we got from the engine, now create a mesh out of the data
|
||||
layerData.build()
|
||||
mesh.layerData = layerData
|
||||
|
||||
# We are done processing all the layers we got from the engine, now create a mesh out of the data
|
||||
layerData.build()
|
||||
mesh.layerData = layerData
|
||||
|
||||
new_node.setMeshData(mesh)
|
||||
new_node.setParent(self._scene.getRoot())
|
||||
|
@ -9,6 +9,10 @@ from UM.Event import Event, KeyEvent
|
||||
from UM.Signal import Signal
|
||||
from UM.Scene.Selection import Selection
|
||||
from UM.Math.Color import Color
|
||||
from UM.Mesh.MeshData import MeshData
|
||||
|
||||
from cura.ConvexHullNode import ConvexHullNode
|
||||
|
||||
from . import LayerViewProxy
|
||||
|
||||
## View used to display g-code paths.
|
||||
@ -22,6 +26,9 @@ class LayerView(View):
|
||||
self._controller.getScene().sceneChanged.connect(self._onSceneChanged)
|
||||
self._max_layers = 10
|
||||
self._current_layer_num = 10
|
||||
self._current_layer_mesh = None
|
||||
|
||||
self._solid_layers = 5
|
||||
|
||||
def getCurrentLayer(self):
|
||||
return self._current_layer_num
|
||||
@ -45,6 +52,11 @@ class LayerView(View):
|
||||
self._selection_material.setUniformValue("u_color", Color(35, 35, 35, 128))
|
||||
|
||||
for node in DepthFirstIterator(scene.getRoot()):
|
||||
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
|
||||
# However, it is somewhat relevant when the node is selected, so do render it then.
|
||||
if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
|
||||
continue
|
||||
|
||||
if not node.render(renderer):
|
||||
if node.getMeshData() and node.isVisible():
|
||||
if Selection.isSelected(node):
|
||||
@ -55,19 +67,39 @@ class LayerView(View):
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
start = 0
|
||||
end = 0
|
||||
# Render all layers below a certain number as line mesh instead of vertices.
|
||||
if self._current_layer_num - self._solid_layers > -1:
|
||||
start = 0
|
||||
end = 0
|
||||
element_counts = layer_data.getElementCounts()
|
||||
for layer, counts in element_counts.items():
|
||||
if layer + self._solid_layers > self._current_layer_num:
|
||||
break
|
||||
end += counts
|
||||
|
||||
element_counts = layer_data.getElementCounts()
|
||||
for layer, counts in element_counts.items():
|
||||
end += sum(counts)
|
||||
## Hack to ensure the end is correct. Not quite sure what causes this
|
||||
end += 2 * len(counts)
|
||||
# This uses glDrawRangeElements internally to only draw a certain range of lines.
|
||||
renderer.queueNode(node, mesh = layer_data, material = self._material, mode = Renderer.RenderLines, start = start, end = end)
|
||||
|
||||
if layer >= self._current_layer_num:
|
||||
break
|
||||
# We currently recreate the current "solid" layers every time a
|
||||
if not self._current_layer_mesh:
|
||||
self._current_layer_mesh = MeshData()
|
||||
for i in range(self._solid_layers):
|
||||
layer = self._current_layer_num - i
|
||||
if layer < 0:
|
||||
continue
|
||||
|
||||
renderer.queueNode(node, mesh = layer_data, material = self._material, mode = Renderer.RenderLines, start = start, end = end)
|
||||
layer_mesh = layer_data.getLayer(layer).createMesh()
|
||||
if not layer_mesh or layer_mesh.getVertices() is None:
|
||||
continue
|
||||
|
||||
self._current_layer_mesh.addVertices(layer_mesh.getVertices())
|
||||
|
||||
# Scale layer color by a brightness factor based on the current layer number
|
||||
# This will result in a range of 0.5 - 1.0 to multiply colors by.
|
||||
brightness = (2.0 - (i / self._solid_layers)) / 2.0
|
||||
self._current_layer_mesh.addColors(layer_mesh.getColors() * brightness)
|
||||
|
||||
renderer.queueNode(node, mesh = self._current_layer_mesh, material = self._material)
|
||||
|
||||
def setLayer(self, value):
|
||||
if self._current_layer_num != value:
|
||||
@ -76,6 +108,8 @@ class LayerView(View):
|
||||
self._current_layer_num = 0
|
||||
if self._current_layer_num > self._max_layers:
|
||||
self._current_layer_num = self._max_layers
|
||||
|
||||
self._current_layer_mesh = None
|
||||
self.currentLayerNumChanged.emit()
|
||||
|
||||
currentLayerNumChanged = Signal()
|
||||
@ -96,7 +130,7 @@ class LayerView(View):
|
||||
except AttributeError:
|
||||
continue
|
||||
if new_max_layers < len(layer_data.getLayers()):
|
||||
new_max_layers = len(layer_data.getLayers())
|
||||
new_max_layers = len(layer_data.getLayers()) - 1
|
||||
|
||||
if new_max_layers > 0 and new_max_layers != self._old_max_layers:
|
||||
self._max_layers = new_max_layers
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
import UM 1.0 as UM
|
||||
@ -12,48 +11,53 @@ UM.Dialog {
|
||||
id: base
|
||||
|
||||
//: About dialog title
|
||||
title: qsTr("About Cura");
|
||||
title: qsTr("About Cura")
|
||||
minimumWidth: 400
|
||||
minimumHeight: 300
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent;
|
||||
Image {
|
||||
id: logo
|
||||
width: parent.width * 0.75
|
||||
height: width * (1/4.25)
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true;
|
||||
Layout.fillHeight: true;
|
||||
}
|
||||
source: UM.Theme.images.logo
|
||||
|
||||
Image {
|
||||
Layout.alignment: Qt.AlignHCenter;
|
||||
Layout.preferredWidth: parent.width * 0.75;
|
||||
Layout.preferredHeight: width * (1/4.25);
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset : -(height * 0.5)
|
||||
}
|
||||
|
||||
source: UM.Theme.images.logo;
|
||||
Label {
|
||||
id: version
|
||||
|
||||
sourceSize.width: width;
|
||||
sourceSize.height: height;
|
||||
}
|
||||
text: "Cura 15.06 Beta"
|
||||
font: UM.Theme.fonts.large
|
||||
anchors.horizontalCenter : logo.horizontalCenter
|
||||
anchors.horizontalCenterOffset : (logo.width * 0.25)
|
||||
anchors.top: logo.bottom
|
||||
anchors.topMargin : 5
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignHCenter;
|
||||
Label {
|
||||
id: description
|
||||
width: parent.width
|
||||
|
||||
text: "Cura 15.06 Beta";
|
||||
font: UM.Theme.fonts.large;
|
||||
}
|
||||
//: About dialog application description
|
||||
text: qsTr("End-to-end solution for fused filament 3D printing.")
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.top: version.bottom
|
||||
anchors.topMargin : 10
|
||||
}
|
||||
|
||||
Label {
|
||||
//: About dialog application description
|
||||
text: qsTr("End-to-end solution for fused filament 3D printing.")
|
||||
}
|
||||
Label {
|
||||
id: author_note
|
||||
width: parent.width
|
||||
|
||||
Label {
|
||||
//: About dialog application author note
|
||||
text: qsTr("Cura has been developed by Ultimaker B.V. in cooperation with the community.")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true;
|
||||
Layout.fillHeight: true;
|
||||
}
|
||||
//: About dialog application author note
|
||||
text: qsTr("Cura has been developed by Ultimaker B.V. in cooperation with the community.")
|
||||
wrapMode: Text.WordWrap
|
||||
anchors.top: description.bottom
|
||||
}
|
||||
|
||||
rightButtons: Button {
|
||||
|
@ -25,6 +25,7 @@ UM.MainWindow {
|
||||
window: base
|
||||
|
||||
Menu {
|
||||
id: fileMenu
|
||||
//: File menu
|
||||
title: qsTr("&File");
|
||||
|
||||
@ -33,6 +34,19 @@ UM.MainWindow {
|
||||
|
||||
MenuSeparator { }
|
||||
|
||||
Instantiator {
|
||||
model: Printer.recentFiles
|
||||
MenuItem {
|
||||
property url filePath: modelData;
|
||||
text: (index + 1) + ". " + modelData.slice(modelData.lastIndexOf("/") + 1);
|
||||
onTriggered: UM.MeshFileHandler.readLocalFile(filePath);
|
||||
}
|
||||
onObjectAdded: fileMenu.insertItem(index, object)
|
||||
onObjectRemoved: fileMenu.removeItem(object)
|
||||
}
|
||||
|
||||
MenuSeparator { }
|
||||
|
||||
MenuItem { action: actions.quit; }
|
||||
}
|
||||
|
||||
@ -178,8 +192,8 @@ UM.MainWindow {
|
||||
id: openFileButton;
|
||||
|
||||
iconSource: UM.Theme.icons.open;
|
||||
style: UM.Theme.styles.tool_button;
|
||||
|
||||
style: UM.Backend.progress < 0 ? UM.Theme.styles.open_file_button : UM.Theme.styles.tool_button;
|
||||
tooltip: '';
|
||||
anchors {
|
||||
top: parent.top;
|
||||
topMargin: UM.Theme.sizes.window_margin.height;
|
||||
@ -218,7 +232,7 @@ UM.MainWindow {
|
||||
iconSource: UM.Theme.icons.viewmode;
|
||||
|
||||
style: UM.Theme.styles.tool_button;
|
||||
|
||||
tooltip: '';
|
||||
menu: Menu {
|
||||
id: viewMenu;
|
||||
Instantiator {
|
||||
@ -419,3 +433,4 @@ UM.MainWindow {
|
||||
|
||||
Component.onCompleted: UM.Theme.load(UM.Resources.getPath(UM.Resources.ThemesLocation, "cura"))
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
// Copyright (c) 2015 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.0
|
||||
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
import UM 1.0 as UM
|
||||
|
||||
UM.SettingView { }
|
||||
UM.SettingView {
|
||||
expandedCategories: Printer.expandedCategories;
|
||||
onExpandedCategoriesChanged: Printer.setExpandedCategories(expandedCategories);
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ Item {
|
||||
Button {
|
||||
text: model.name;
|
||||
iconSource: UM.Theme.icons[model.icon];
|
||||
tooltip: model.description;
|
||||
|
||||
checkable: true;
|
||||
checked: model.active;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "ultimaker_original_plus",
|
||||
"name": "Ultimaker Original Plus",
|
||||
"name": "Ultimaker Original+",
|
||||
"icon": "icon_ultimaker.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "UltimakerPlusbackplate.png",
|
||||
|
@ -35,47 +35,42 @@ QtObject {
|
||||
}
|
||||
}
|
||||
|
||||
property Component tool_button: Component {
|
||||
property Component open_file_button: Component {
|
||||
ButtonStyle {
|
||||
background: UM.AngledCornerRectangle {
|
||||
property bool down: control.pressed || (control.checkable && control.checked);
|
||||
|
||||
background: Item {
|
||||
implicitWidth: UM.Theme.sizes.button.width;
|
||||
implicitHeight: UM.Theme.sizes.button.height;
|
||||
color: {
|
||||
if(!control.enabled) {
|
||||
return UM.Theme.colors.button_disabled;
|
||||
} else if(control.checkable && control.checked && control.hovered) {
|
||||
return UM.Theme.colors.button_active_hover;
|
||||
} else if(control.pressed || (control.checkable && control.checked)) {
|
||||
return UM.Theme.colors.button_active;
|
||||
} else if(control.hovered) {
|
||||
return UM.Theme.colors.button_hover;
|
||||
} else {
|
||||
return UM.Theme.colors.button;
|
||||
}
|
||||
}
|
||||
Behavior on color { ColorAnimation { duration: 50; } }
|
||||
cornerSize: UM.Theme.sizes.default_margin.width;
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.top;
|
||||
|
||||
anchors.bottom: parent.verticalCenter;
|
||||
width: parent.width;
|
||||
height: control.hovered ? label.height : 0;
|
||||
Behavior on height { NumberAnimation { duration: 75; } }
|
||||
height: control.hovered ? parent.height / 2 + label.height : 0;
|
||||
Behavior on height { NumberAnimation { duration: 100; } }
|
||||
|
||||
opacity: control.hovered ? 1.0 : 0.0;
|
||||
Behavior on opacity { NumberAnimation { duration: 75; } }
|
||||
Behavior on opacity { NumberAnimation { duration: 100; } }
|
||||
|
||||
Label {
|
||||
id: label
|
||||
id: label;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
text: control.text;
|
||||
text: control.text.replace("&", "");
|
||||
font: UM.Theme.fonts.button_tooltip;
|
||||
color: UM.Theme.colors.button_tooltip_text;
|
||||
}
|
||||
}
|
||||
|
||||
UM.AngledCornerRectangle {
|
||||
anchors.fill: parent;
|
||||
color: {
|
||||
if(control.hovered) {
|
||||
return UM.Theme.colors.button_active_hover;
|
||||
} else {
|
||||
return UM.Theme.colors.button_active;
|
||||
}
|
||||
}
|
||||
Behavior on color { ColorAnimation { duration: 50; } }
|
||||
cornerSize: UM.Theme.sizes.default_margin.width;
|
||||
}
|
||||
}
|
||||
|
||||
label: Item {
|
||||
@ -92,6 +87,113 @@ QtObject {
|
||||
}
|
||||
}
|
||||
|
||||
property Component tool_button: Component {
|
||||
ButtonStyle {
|
||||
background: Item {
|
||||
implicitWidth: UM.Theme.sizes.button.width;
|
||||
implicitHeight: UM.Theme.sizes.button.height;
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.verticalCenter;
|
||||
|
||||
width: parent.width;
|
||||
height: control.hovered ? parent.height / 2 + label.height : 0;
|
||||
Behavior on height { NumberAnimation { duration: 100; } }
|
||||
|
||||
opacity: control.hovered ? 1.0 : 0.0;
|
||||
Behavior on opacity { NumberAnimation { duration: 100; } }
|
||||
|
||||
Label {
|
||||
id: label
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
text: control.text.replace("&", "");
|
||||
font: UM.Theme.fonts.button_tooltip;
|
||||
color: UM.Theme.colors.button_tooltip_text;
|
||||
}
|
||||
}
|
||||
|
||||
UM.AngledCornerRectangle {
|
||||
id: buttonFace;
|
||||
|
||||
anchors.fill: parent;
|
||||
|
||||
property bool down: control.pressed || (control.checkable && control.checked);
|
||||
|
||||
color: {
|
||||
if(!control.enabled) {
|
||||
return UM.Theme.colors.button_disabled;
|
||||
} else if(control.checkable && control.checked && control.hovered) {
|
||||
return UM.Theme.colors.button_active_hover;
|
||||
} else if(control.pressed || (control.checkable && control.checked)) {
|
||||
return UM.Theme.colors.button_active;
|
||||
} else if(control.hovered) {
|
||||
return UM.Theme.colors.button_hover;
|
||||
} else {
|
||||
return UM.Theme.colors.button;
|
||||
}
|
||||
}
|
||||
Behavior on color { ColorAnimation { duration: 50; } }
|
||||
cornerSize: UM.Theme.sizes.default_margin.width;
|
||||
}
|
||||
}
|
||||
|
||||
label: Item {
|
||||
Image {
|
||||
anchors.centerIn: parent;
|
||||
|
||||
source: control.iconSource;
|
||||
width: UM.Theme.sizes.button_icon.width;
|
||||
height: UM.Theme.sizes.button_icon.height;
|
||||
|
||||
sourceSize: UM.Theme.sizes.button_icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
property Component progressbar: Component{
|
||||
ProgressBarStyle {
|
||||
background: UM.AngledCornerRectangle {
|
||||
anchors.fill: parent
|
||||
anchors.left: parent.left
|
||||
implicitWidth: UM.Theme.sizes.progressbar.width
|
||||
implicitHeight: UM.Theme.sizes.progressbar.height
|
||||
color: "transparent"
|
||||
}
|
||||
progress: UM.AngledCornerRectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.fill: parent
|
||||
cornerSize: UM.Theme.sizes.progressbar_control.height
|
||||
color: UM.Theme.colors.progressbar_background
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: UM.Theme.sizes.progressbar_margin.width
|
||||
visible: control.indeterminate
|
||||
Row {
|
||||
Repeater {
|
||||
UM.AngledCornerRectangle {
|
||||
cornerSize: UM.Theme.sizes.progressbar_control.height
|
||||
color: UM.Theme.colors.progressbar_control
|
||||
width: UM.Theme.sizes.progressbar_control.width
|
||||
height: UM.Theme.sizes.progressbar_control.height
|
||||
}
|
||||
model: 1
|
||||
}
|
||||
SequentialAnimation on x {
|
||||
id: xAnim
|
||||
property int animEndPoint: UM.Theme.sizes.progressbar.width - UM.Theme.sizes.progressbar_control.width
|
||||
running: control.indeterminate
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation { from: 0; to: xAnim.animEndPoint; duration: 2000;}
|
||||
NumberAnimation { from: xAnim.animEndPoint; to: 0; duration: 2000;}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Component sidebar_category: Component {
|
||||
ButtonStyle {
|
||||
background: UM.AngledCornerRectangle {
|
||||
|
@ -52,15 +52,15 @@
|
||||
"border": [205, 202, 201, 255],
|
||||
"secondary": [205, 202, 201, 255],
|
||||
|
||||
"text": [174, 174, 174, 255],
|
||||
"text_inactive": [205, 202, 201, 255],
|
||||
"text": [140, 144, 154, 255],
|
||||
"text_inactive": [174, 174, 174, 255],
|
||||
"text_hover": [35, 35, 35, 255],
|
||||
"text_pressed": [12, 169, 227, 255],
|
||||
|
||||
"button": [205, 202, 201, 255],
|
||||
"button_hover": [174, 174, 174, 255],
|
||||
"button": [160, 163, 171, 255],
|
||||
"button_hover": [140, 144, 154, 255],
|
||||
"button_active": [12, 169, 227, 255],
|
||||
"button_active_hover": [34, 150, 190, 255],
|
||||
"button_active_hover": [34, 150, 199, 255],
|
||||
"button_text": [255, 255, 255, 255],
|
||||
"button_disabled": [245, 245, 245, 255],
|
||||
"button_tooltip_text": [35, 35, 35, 255],
|
||||
@ -77,7 +77,7 @@
|
||||
"setting_category_active_hover": [34, 150, 190, 255],
|
||||
"setting_category_text": [255, 255, 255, 255],
|
||||
|
||||
"setting_label": [174, 174, 174, 255],
|
||||
"setting_label": [140, 144, 154, 255],
|
||||
"setting_control": [255, 255, 255, 255],
|
||||
"setting_control_highlight": [245, 245, 245, 255],
|
||||
"setting_control_border": [174, 174, 174, 255],
|
||||
@ -88,6 +88,9 @@
|
||||
"setting_validation_warning": [255, 186, 15, 255],
|
||||
"setting_validation_ok": [255, 255, 255, 255],
|
||||
|
||||
"progressbar_background": [245, 245, 245, 255],
|
||||
"progressbar_control": [12, 169, 227, 255],
|
||||
|
||||
"slider_groove": [245, 245, 245, 255],
|
||||
"slider_groove_border": [205, 202, 201, 255],
|
||||
"slider_groove_fill": [205, 202, 201, 255],
|
||||
@ -98,7 +101,7 @@
|
||||
"checkbox_hover": [245, 245, 245, 255],
|
||||
"checkbox_border": [174, 174, 174, 255],
|
||||
"checkbox_mark": [35, 35, 35, 255],
|
||||
"checkbox_text": [174, 174, 174, 255],
|
||||
"checkbox_text": [140, 144, 154, 255],
|
||||
|
||||
"tooltip": [255, 225, 146, 255],
|
||||
|
||||
@ -133,7 +136,11 @@
|
||||
"setting_unit_margin": [0.5, 0.5],
|
||||
|
||||
"button": [4.25, 4.25],
|
||||
"button_icon": [3.57, 3.57],
|
||||
"button_icon": [2.9, 2.9],
|
||||
|
||||
"progressbar": [26.0, 0.5],
|
||||
"progressbar_control": [8.0, 0.5],
|
||||
"progressbar_padding": [0.0, 1.0],
|
||||
|
||||
"scrollbar": [0.5, 0.5],
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user