diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 8c1ee8fc36..caa39cc703 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -218,7 +218,7 @@ class CuraApplication(QtApplication): "CuraEngineBackend", "UserAgreement", "SolidView", - "LayerView", + "SimulationView", "STLReader", "SelectionTool", "CameraTool", @@ -1386,7 +1386,7 @@ class CuraApplication(QtApplication): extension = os.path.splitext(filename)[1] if extension.lower() in self._non_sliceable_extensions: - self.getController().setActiveView("LayerView") + self.getController().setActiveView("SimulationView") view = self.getController().getActiveView() view.resetLayerData() view.setLayer(9999999) diff --git a/cura/Layer.py b/cura/Layer.py index d5ef5c9bb4..9cd45380fc 100644 --- a/cura/Layer.py +++ b/cura/Layer.py @@ -47,12 +47,12 @@ class Layer: return result - def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, line_types, indices): + def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, feedrates, extruders, line_types, indices): result_vertex_offset = vertex_offset result_index_offset = index_offset self._element_count = 0 for polygon in self._polygons: - polygon.build(result_vertex_offset, result_index_offset, vertices, colors, line_dimensions, extruders, line_types, indices) + polygon.build(result_vertex_offset, result_index_offset, vertices, colors, line_dimensions, feedrates, extruders, line_types, indices) result_vertex_offset += polygon.lineMeshVertexCount() result_index_offset += polygon.lineMeshElementCount() self._element_count += polygon.elementCount diff --git a/cura/LayerDataBuilder.py b/cura/LayerDataBuilder.py index 6e50611e64..d6cc81a4e9 100755 --- a/cura/LayerDataBuilder.py +++ b/cura/LayerDataBuilder.py @@ -20,11 +20,11 @@ class LayerDataBuilder(MeshBuilder): if layer not in self._layers: self._layers[layer] = Layer(layer) - def addPolygon(self, layer, polygon_type, data, line_width): + def addPolygon(self, layer, polygon_type, data, line_width, line_thickness, line_feedrate): if layer not in self._layers: self.addLayer(layer) - p = LayerPolygon(self, polygon_type, data, line_width) + p = LayerPolygon(self, polygon_type, data, line_width, line_thickness, line_feedrate) self._layers[layer].polygons.append(p) def getLayer(self, layer): @@ -64,13 +64,14 @@ class LayerDataBuilder(MeshBuilder): line_dimensions = numpy.empty((vertex_count, 2), numpy.float32) colors = numpy.empty((vertex_count, 4), numpy.float32) indices = numpy.empty((index_count, 2), numpy.int32) + feedrates = numpy.empty((vertex_count), numpy.float32) extruders = numpy.empty((vertex_count), numpy.float32) line_types = numpy.empty((vertex_count), numpy.float32) vertex_offset = 0 index_offset = 0 for layer, data in sorted(self._layers.items()): - ( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, line_types, indices) + ( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, line_dimensions, feedrates, extruders, line_types, indices) self._element_counts[layer] = data.elementCount self.addVertices(vertices) @@ -107,6 +108,11 @@ class LayerDataBuilder(MeshBuilder): "value": line_types, "opengl_name": "a_line_type", "opengl_type": "float" + }, + "feedrates": { + "value": feedrates, + "opengl_name": "a_feedrate", + "opengl_type": "float" } } diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 7f41351b7f..9766e0c82a 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -28,7 +28,8 @@ class LayerPolygon: # \param data new_points # \param line_widths array with line widths # \param line_thicknesses: array with type as index and thickness as value - def __init__(self, extruder, line_types, data, line_widths, line_thicknesses): + # \param line_feedrates array with line feedrates + def __init__(self, extruder, line_types, data, line_widths, line_thicknesses, line_feedrates): self._extruder = extruder self._types = line_types for i in range(len(self._types)): @@ -37,6 +38,7 @@ class LayerPolygon: self._data = data self._line_widths = line_widths self._line_thicknesses = line_thicknesses + self._line_feedrates = line_feedrates self._vertex_begin = 0 self._vertex_end = 0 @@ -84,10 +86,11 @@ class LayerPolygon: # \param vertices : vertex numpy array to be filled # \param colors : vertex numpy array to be filled # \param line_dimensions : vertex numpy array to be filled + # \param feedrates : vertex numpy array to be filled # \param extruders : vertex numpy array to be filled # \param line_types : vertex numpy array to be filled # \param indices : index numpy array to be filled - def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, line_types, indices): + def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, feedrates, extruders, line_types, indices): if self._build_cache_line_mesh_mask is None or self._build_cache_needed_points is None: self.buildCache() @@ -109,10 +112,13 @@ class LayerPolygon: # Create an array with colors for each vertex and remove the color data for the points that has been thrown away. colors[self._vertex_begin:self._vertex_end, :] = numpy.tile(self._colors, (1, 2)).reshape((-1, 4))[needed_points_list.ravel()] - # Create an array with line widths for each vertex. + # Create an array with line widths and thicknesses for each vertex. line_dimensions[self._vertex_begin:self._vertex_end, 0] = numpy.tile(self._line_widths, (1, 2)).reshape((-1, 1))[needed_points_list.ravel()][:, 0] line_dimensions[self._vertex_begin:self._vertex_end, 1] = numpy.tile(self._line_thicknesses, (1, 2)).reshape((-1, 1))[needed_points_list.ravel()][:, 0] + # Create an array with feedrates for each line + feedrates[self._vertex_begin:self._vertex_end] = numpy.tile(self._line_feedrates, (1, 2)).reshape((-1, 1))[needed_points_list.ravel()][:, 0] + extruders[self._vertex_begin:self._vertex_end] = self._extruder # Convert type per vertex to type per line @@ -166,6 +172,14 @@ class LayerPolygon: @property def lineWidths(self): return self._line_widths + + @property + def lineThicknesses(self): + return self._line_thicknesses + + @property + def lineFeedrates(self): + return self._line_feedrates @property def jumpMask(self): diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index c2e4e5bb5f..69612210ec 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -61,6 +61,8 @@ message Polygon { Type type = 1; // Type of move bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used) float line_width = 3; // The width of the line being laid down + float line_thickness = 4; // The thickness of the line being laid down + float line_feedrate = 5; // The feedrate of the line being laid down } message LayerOptimized { @@ -82,6 +84,8 @@ message PathSegment { bytes points = 3; // The points defining the line segments, bytes of float[2/3] array of length N+1 bytes line_type = 4; // Type of line segment as an unsigned char array of length 1 or N, where N is the number of line segments in this path bytes line_width = 5; // The widths of the line segments as bytes of a float array of length 1 or N + bytes line_thickness = 6; // The thickness of the line segments as bytes of a float array of length 1 or N + bytes line_feedrate = 7; // The feedrate of the line segments as bytes of a float array of length 1 or N } diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 14c1c10b90..d35df967b2 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -608,7 +608,7 @@ class CuraEngineBackend(QObject, Backend): def _onActiveViewChanged(self): if Application.getInstance().getController().getActiveView(): view = Application.getInstance().getController().getActiveView() - if view.getPluginId() == "LayerView": # If switching to layer view, we should process the layers if that hasn't been done yet. + if view.getPluginId() == "SimulationView": # If switching to layer view, we should process the layers if that hasn't been done yet. self._layer_view_active = True # There is data and we're not slicing at the moment # if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment. diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index a352564bc2..14646cbac1 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -61,7 +61,7 @@ class ProcessSlicedLayersJob(Job): def run(self): start_time = time() - if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView": + if Application.getInstance().getController().getActiveView().getPluginId() == "SimulationView": self._progress_message.show() Job.yieldThread() if self._abort_requested: @@ -109,6 +109,7 @@ class ProcessSlicedLayersJob(Job): layer_data.addLayer(abs_layer_number) this_layer = layer_data.getLayer(abs_layer_number) layer_data.setLayerHeight(abs_layer_number, layer.height) + layer_data.setLayerThickness(abs_layer_number, layer.thickness) for p in range(layer.repeatedMessageCount("path_segment")): polygon = layer.getRepeatedMessage("path_segment", p) @@ -127,10 +128,11 @@ class ProcessSlicedLayersJob(Job): line_widths = numpy.fromstring(polygon.line_width, dtype="f4") # Convert bytearray to numpy array line_widths = line_widths.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. - # In the future, line_thicknesses should be given by CuraEngine as well. - # Currently the infill layer thickness also translates to line width - line_thicknesses = numpy.zeros(line_widths.shape, dtype="f4") - line_thicknesses[:] = layer.thickness / 1000 # from micrometer to millimeter + line_thicknesses = numpy.fromstring(polygon.line_thickness, dtype="f4") # Convert bytearray to numpy array + line_thicknesses = line_thicknesses.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. + + line_feedrates = numpy.fromstring(polygon.line_feedrate, dtype="f4") # Convert bytearray to numpy array + line_feedrates = line_feedrates.reshape((-1,1)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. # Create a new 3D-array, copy the 2D points over and insert the right height. # This uses manual array creation + copy rather than numpy.insert since this is @@ -145,7 +147,7 @@ class ProcessSlicedLayersJob(Job): new_points[:, 1] = points[:, 2] new_points[:, 2] = -points[:, 1] - this_poly = LayerPolygon.LayerPolygon(extruder, line_types, new_points, line_widths, line_thicknesses) + this_poly = LayerPolygon.LayerPolygon(extruder, line_types, new_points, line_widths, line_thicknesses, line_feedrates) this_poly.buildCache() this_layer.polygons.append(this_poly) @@ -219,7 +221,7 @@ class ProcessSlicedLayersJob(Job): self._progress_message.setProgress(100) view = Application.getInstance().getController().getActiveView() - if view.getPluginId() == "LayerView": + if view.getPluginId() == "SimulationView": view.resetLayerData() if self._progress_message: @@ -232,7 +234,7 @@ class ProcessSlicedLayersJob(Job): def _onActiveViewChanged(self): if self.isRunning(): - if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView": + if Application.getInstance().getController().getActiveView().getPluginId() == "SimulationView": if not self._progress_message: self._progress_message = Message(catalog.i18nc("@info:status", "Processing Layers"), 0, False, 0, catalog.i18nc("@info:title", "Information")) if self._progress_message.getProgress() != 100: diff --git a/plugins/GCodeReader/GCodeReader.py b/plugins/GCodeReader/GCodeReader.py index 1b2795800e..2a7e29e370 100755 --- a/plugins/GCodeReader/GCodeReader.py +++ b/plugins/GCodeReader/GCodeReader.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Aleph Objects, Inc. +# Copyright (c) 2017 Aleph Objects, Inc. # Cura is released under the terms of the LGPLv3 or higher. from UM.Application import Application @@ -40,7 +40,8 @@ class GCodeReader(MeshReader): self._extruder_number = 0 self._clearValues() self._scene_node = None - self._position = namedtuple('Position', ['x', 'y', 'z', 'e']) + # X, Y, Z position, F feedrate and E extruder values are stored + self._position = namedtuple('Position', ['x', 'y', 'z', 'f', 'e']) self._is_layers_in_file = False # Does the Gcode have the layers comment? self._extruder_offsets = {} # Offsets for multi extruders. key is index, value is [x-offset, y-offset] self._current_layer_thickness = 0.2 # default @@ -48,7 +49,9 @@ class GCodeReader(MeshReader): Preferences.getInstance().addPreference("gcodereader/show_caution", True) def _clearValues(self): + self._filament_diameter = 2.85 self._extruder_number = 0 + self._extrusion_length_offset = [0] self._layer_type = LayerPolygon.Inset0Type self._layer_number = 0 self._previous_z = 0 @@ -97,7 +100,7 @@ class GCodeReader(MeshReader): def _createPolygon(self, layer_thickness, path, extruder_offsets): countvalid = 0 for point in path: - if point[3] > 0: + if point[5] > 0: countvalid += 1 if countvalid >= 2: # we know what to do now, no need to count further @@ -115,27 +118,56 @@ class GCodeReader(MeshReader): line_types = numpy.empty((count - 1, 1), numpy.int32) line_widths = numpy.empty((count - 1, 1), numpy.float32) line_thicknesses = numpy.empty((count - 1, 1), numpy.float32) - # TODO: need to calculate actual line width based on E values + line_feedrates = numpy.empty((count - 1, 1), numpy.float32) line_widths[:, 0] = 0.35 # Just a guess line_thicknesses[:, 0] = layer_thickness points = numpy.empty((count, 3), numpy.float32) + extrusion_values = numpy.empty((count, 1), numpy.float32) i = 0 for point in path: points[i, :] = [point[0] + extruder_offsets[0], point[2], -point[1] - extruder_offsets[1]] + extrusion_values[i] = point[4] if i > 0: - line_types[i - 1] = point[3] - if point[3] in [LayerPolygon.MoveCombingType, LayerPolygon.MoveRetractionType]: + line_feedrates[i - 1] = point[3] + line_types[i - 1] = point[5] + if point[5] in [LayerPolygon.MoveCombingType, LayerPolygon.MoveRetractionType]: line_widths[i - 1] = 0.1 + line_thicknesses[i - 1] = 0.0 # Travels are set as zero thickness lines + else: + line_widths[i - 1] = self._calculateLineWidth(points[i], points[i-1], extrusion_values[i], extrusion_values[i-1], layer_thickness) i += 1 - this_poly = LayerPolygon(self._extruder_number, line_types, points, line_widths, line_thicknesses) + this_poly = LayerPolygon(self._extruder_number, line_types, points, line_widths, line_thicknesses, line_feedrates) this_poly.buildCache() this_layer.polygons.append(this_poly) return True + def _calculateLineWidth(self, current_point, previous_point, current_extrusion, previous_extrusion, layer_thickness): + # Area of the filament + Af = (self._filament_diameter / 2) ** 2 * numpy.pi + # Length of the extruded filament + de = current_extrusion - previous_extrusion + # Volumne of the extruded filament + dVe = de * Af + # Length of the printed line + dX = numpy.sqrt((current_point[0] - previous_point[0])**2 + (current_point[2] - previous_point[2])**2) + # When the extruder recovers from a retraction, we get zero distance + if dX == 0: + return 0.1 + # Area of the printed line. This area is a rectangle + Ae = dVe / dX + # This area is a rectangle with area equal to layer_thickness * layer_width + line_width = Ae / layer_thickness + + # A threshold is set to avoid weird paths in the GCode + if line_width > 1.2: + return 0.35 + return line_width + def _gCode0(self, position, params, path): - x, y, z, e = position + x, y, z, f, e = position + if self._is_absolute_positioning: x = params.x if params.x is not None else x y = params.y if params.y is not None else y @@ -145,22 +177,24 @@ class GCodeReader(MeshReader): y += params.y if params.y is not None else 0 z += params.z if params.z is not None else 0 + f = params.f if params.f is not None else f + if params.e is not None: new_extrusion_value = params.e if self._is_absolute_positioning else e[self._extruder_number] + params.e if new_extrusion_value > e[self._extruder_number]: - path.append([x, y, z, self._layer_type]) # extrusion + path.append([x, y, z, f, params.e + self._extrusion_length_offset[self._extruder_number], self._layer_type]) # extrusion else: - path.append([x, y, z, LayerPolygon.MoveRetractionType]) # retraction + path.append([x, y, z, f, params.e + self._extrusion_length_offset[self._extruder_number], LayerPolygon.MoveRetractionType]) # retraction e[self._extruder_number] = new_extrusion_value # Only when extruding we can determine the latest known "layer height" which is the difference in height between extrusions # Also, 1.5 is a heuristic for any priming or whatsoever, we skip those. if z > self._previous_z and (z - self._previous_z < 1.5): - self._current_layer_thickness = z - self._previous_z + 0.05 # allow a tiny overlap + self._current_layer_thickness = z - self._previous_z # allow a tiny overlap self._previous_z = z else: - path.append([x, y, z, LayerPolygon.MoveCombingType]) - return self._position(x, y, z, e) + path.append([x, y, z, f, e[self._extruder_number] + self._extrusion_length_offset[self._extruder_number], LayerPolygon.MoveCombingType]) + return self._position(x, y, z, f, e) # G0 and G1 should be handled exactly the same. _gCode1 = _gCode0 @@ -171,6 +205,7 @@ class GCodeReader(MeshReader): params.x if params.x is not None else position.x, params.y if params.y is not None else position.y, 0, + position.f, position.e) ## Set the absolute positioning @@ -187,11 +222,14 @@ class GCodeReader(MeshReader): # For example: G92 X10 will set the X to 10 without any physical motion. def _gCode92(self, position, params, path): if params.e is not None: + # Sometimes a G92 E0 is introduced in the middle of the GCode so we need to keep those offsets for calculate the line_width + self._extrusion_length_offset[self._extruder_number] += position.e[self._extruder_number] - params.e position.e[self._extruder_number] = params.e return self._position( params.x if params.x is not None else position.x, params.y if params.y is not None else position.y, params.z if params.z is not None else position.z, + params.f if params.f is not None else position.f, position.e) def _processGCode(self, G, line, position, path): @@ -199,7 +237,7 @@ class GCodeReader(MeshReader): line = line.split(";", 1)[0] # Remove comments (if any) if func is not None: s = line.upper().split(" ") - x, y, z, e = None, None, None, None + x, y, z, f, e = None, None, None, None, None for item in s[1:]: if len(item) <= 1: continue @@ -211,17 +249,20 @@ class GCodeReader(MeshReader): y = float(item[1:]) if item[0] == "Z": z = float(item[1:]) + if item[0] == "F": + f = float(item[1:]) / 60 if item[0] == "E": e = float(item[1:]) if self._is_absolute_positioning and ((x is not None and x < 0) or (y is not None and y < 0)): self._center_is_zero = True - params = self._position(x, y, z, e) + params = self._position(x, y, z, f, e) return func(position, params, path) return position def _processTCode(self, T, line, position, path): self._extruder_number = T if self._extruder_number + 1 > len(position.e): + self._extrusion_length_offset.extend([0] * (self._extruder_number - len(position.e) + 1)) position.e.extend([0] * (self._extruder_number - len(position.e) + 1)) return position @@ -240,6 +281,8 @@ class GCodeReader(MeshReader): def read(self, file_name): Logger.log("d", "Preparing to load %s" % file_name) self._cancelled = False + # We obtain the filament diameter from the selected printer to calculate line widths + self._filament_diameter = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") scene_node = SceneNode() # Override getBoundingBox function of the sceneNode, as this node should return a bounding box, but there is no @@ -277,7 +320,7 @@ class GCodeReader(MeshReader): Logger.log("d", "Parsing %s..." % file_name) - current_position = self._position(0, 0, 0, [0]) + current_position = self._position(0, 0, 0, 0, [0]) current_path = [] for line in file: @@ -310,6 +353,7 @@ class GCodeReader(MeshReader): else: Logger.log("w", "Encountered a unknown type (%s) while parsing g-code.", type) + # When the layer change is reached, the polygon is computed so we have just one layer per layer per extruder if self._is_layers_in_file and line[:len(self._layer_keyword)] == self._layer_keyword: try: layer_number = int(line[len(self._layer_keyword):]) @@ -325,17 +369,12 @@ class GCodeReader(MeshReader): G = self._getInt(line, "G") if G is not None: + # When find a movement, the new posistion is calculated and added to the current_path, but + # don't need to create a polygon until the end of the layer current_position = self._processGCode(G, line, current_position, current_path) - - # < 2 is a heuristic for a movement only, that should not be counted as a layer - if current_position.z > last_z and abs(current_position.z - last_z) < 2: - if self._createPolygon(self._current_layer_thickness, current_path, self._extruder_offsets.get(self._extruder_number, [0, 0])): - current_path.clear() - if not self._is_layers_in_file: - self._layer_number += 1 - continue + # When changing the extruder, the polygon with the stored paths is computed if line.startswith("T"): T = self._getInt(line, "T") if T is not None: @@ -344,8 +383,8 @@ class GCodeReader(MeshReader): current_position = self._processTCode(T, line, current_position, current_path) - # "Flush" leftovers - if not self._is_layers_in_file and len(current_path) > 1: + # "Flush" leftovers. Last layer paths are still stored + if len(current_path) > 1: if self._createPolygon(self._current_layer_thickness, current_path, self._extruder_offsets.get(self._extruder_number, [0, 0])): self._layer_number += 1 current_path.clear() diff --git a/plugins/LayerView/LayerPass.py b/plugins/LayerView/LayerPass.py deleted file mode 100755 index 963c8c75c8..0000000000 --- a/plugins/LayerView/LayerPass.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (c) 2016 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from UM.Resources import Resources -from UM.Scene.SceneNode import SceneNode -from UM.Scene.ToolHandle import ToolHandle -from UM.Application import Application -from UM.PluginRegistry import PluginRegistry - -from UM.View.RenderPass import RenderPass -from UM.View.RenderBatch import RenderBatch -from UM.View.GL.OpenGL import OpenGL - -from cura.Settings.ExtruderManager import ExtruderManager - - -import os.path - -## RenderPass used to display g-code paths. -class LayerPass(RenderPass): - def __init__(self, width, height): - super().__init__("layerview", width, height) - - self._layer_shader = None - self._tool_handle_shader = None - self._gl = OpenGL.getInstance().getBindingsObject() - self._scene = Application.getInstance().getController().getScene() - self._extruder_manager = ExtruderManager.getInstance() - - self._layer_view = None - self._compatibility_mode = None - - def setLayerView(self, layerview): - self._layer_view = layerview - self._compatibility_mode = layerview.getCompatibilityMode() - - def render(self): - if not self._layer_shader: - if self._compatibility_mode: - shader_filename = "layers.shader" - else: - shader_filename = "layers3d.shader" - self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), shader_filename)) - # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers) - self._layer_shader.setUniformValue("u_active_extruder", float(max(0, self._extruder_manager.activeExtruderIndex))) - if self._layer_view: - self._layer_shader.setUniformValue("u_layer_view_type", self._layer_view.getLayerViewType()) - self._layer_shader.setUniformValue("u_extruder_opacity", self._layer_view.getExtruderOpacities()) - self._layer_shader.setUniformValue("u_show_travel_moves", self._layer_view.getShowTravelMoves()) - self._layer_shader.setUniformValue("u_show_helpers", self._layer_view.getShowHelpers()) - self._layer_shader.setUniformValue("u_show_skin", self._layer_view.getShowSkin()) - self._layer_shader.setUniformValue("u_show_infill", self._layer_view.getShowInfill()) - else: - #defaults - self._layer_shader.setUniformValue("u_layer_view_type", 1) - self._layer_shader.setUniformValue("u_extruder_opacity", [1, 1, 1, 1]) - self._layer_shader.setUniformValue("u_show_travel_moves", 0) - self._layer_shader.setUniformValue("u_show_helpers", 1) - self._layer_shader.setUniformValue("u_show_skin", 1) - self._layer_shader.setUniformValue("u_show_infill", 1) - - if not self._tool_handle_shader: - self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader")) - - self.bind() - - tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay) - - for node in DepthFirstIterator(self._scene.getRoot()): - - if isinstance(node, ToolHandle): - tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh()) - - elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible(): - layer_data = node.callDecoration("getLayerData") - if not layer_data: - continue - - # Render all layers below a certain number as line mesh instead of vertices. - if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())): - start = 0 - end = 0 - element_counts = layer_data.getElementCounts() - for layer in sorted(element_counts.keys()): - if layer > self._layer_view._current_layer_num: - break - if self._layer_view._minimum_layer_num > layer: - start += element_counts[layer] - end += element_counts[layer] - - # This uses glDrawRangeElements internally to only draw a certain range of lines. - batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid, mode = RenderBatch.RenderMode.Lines, range = (start, end)) - batch.addItem(node.getWorldTransformation(), layer_data) - batch.render(self._scene.getActiveCamera()) - - # Create a new batch that is not range-limited - batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid) - - if self._layer_view.getCurrentLayerMesh(): - batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerMesh()) - - if self._layer_view.getCurrentLayerJumps(): - batch.addItem(node.getWorldTransformation(), self._layer_view.getCurrentLayerJumps()) - - if len(batch.items) > 0: - batch.render(self._scene.getActiveCamera()) - - # Render toolhandles on top of the layerview - if len(tool_handle_batch.items) > 0: - tool_handle_batch.render(self._scene.getActiveCamera()) - - self.release() diff --git a/plugins/LayerView/LayerSlider.qml b/plugins/LayerView/LayerSlider.qml deleted file mode 100644 index 9abeb01148..0000000000 --- a/plugins/LayerView/LayerSlider.qml +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.2 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.0 as UM -import Cura 1.0 as Cura - -Item { - id: sliderRoot - - // handle properties - property real handleSize: 10 - property real handleRadius: handleSize / 2 - property real minimumRangeHandleSize: handleSize / 2 - property color upperHandleColor: "black" - property color lowerHandleColor: "black" - property color rangeHandleColor: "black" - property real handleLabelWidth: width - property var activeHandle: upperHandle - - // track properties - property real trackThickness: 4 // width of the slider track - property real trackRadius: trackThickness / 2 - property color trackColor: "white" - property real trackBorderWidth: 1 // width of the slider track border - property color trackBorderColor: "black" - - // value properties - property real maximumValue: 100 - property real minimumValue: 0 - property real minimumRange: 0 // minimum range allowed between min and max values - property bool roundValues: true - property real upperValue: maximumValue - property real lowerValue: minimumValue - - property bool layersVisible: true - - function getUpperValueFromSliderHandle () { - return upperHandle.getValue() - } - - function setUpperValue (value) { - upperHandle.setValue(value) - updateRangeHandle() - } - - function getLowerValueFromSliderHandle () { - return lowerHandle.getValue() - } - - function setLowerValue (value) { - lowerHandle.setValue(value) - updateRangeHandle() - } - - function updateRangeHandle () { - rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height) - } - - // set the active handle to show only one label at a time - function setActiveHandle (handle) { - activeHandle = handle - } - - // slider track - Rectangle { - id: track - - width: sliderRoot.trackThickness - height: sliderRoot.height - sliderRoot.handleSize - radius: sliderRoot.trackRadius - anchors.centerIn: sliderRoot - color: sliderRoot.trackColor - border.width: sliderRoot.trackBorderWidth - border.color: sliderRoot.trackBorderColor - visible: sliderRoot.layersVisible - } - - // Range handle - Item { - id: rangeHandle - - y: upperHandle.y + upperHandle.height - width: sliderRoot.handleSize - height: sliderRoot.minimumRangeHandleSize - anchors.horizontalCenter: sliderRoot.horizontalCenter - visible: sliderRoot.layersVisible - - // set the new value when dragging - function onHandleDragged () { - - upperHandle.y = y - upperHandle.height - lowerHandle.y = y + height - - var upperValue = sliderRoot.getUpperValueFromSliderHandle() - var lowerValue = sliderRoot.getLowerValueFromSliderHandle() - - // set both values after moving the handle position - UM.LayerView.setCurrentLayer(upperValue) - UM.LayerView.setMinimumLayer(lowerValue) - } - - function setValue (value) { - var range = sliderRoot.upperValue - sliderRoot.lowerValue - value = Math.min(value, sliderRoot.maximumValue) - value = Math.max(value, sliderRoot.minimumValue + range) - - UM.LayerView.setCurrentLayer(value) - UM.LayerView.setMinimumLayer(value - range) - } - - Rectangle { - width: sliderRoot.trackThickness - 2 * sliderRoot.trackBorderWidth - height: parent.height + sliderRoot.handleSize - anchors.centerIn: parent - color: sliderRoot.rangeHandleColor - } - - MouseArea { - anchors.fill: parent - - drag { - target: parent - axis: Drag.YAxis - minimumY: upperHandle.height - maximumY: sliderRoot.height - (rangeHandle.height + lowerHandle.height) - } - - onPositionChanged: parent.onHandleDragged() - onPressed: sliderRoot.setActiveHandle(rangeHandle) - } - - LayerSliderLabel { - id: rangleHandleLabel - - height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width, y + height / 2) - visible: sliderRoot.activeHandle == parent - - // custom properties - maximumValue: sliderRoot.maximumValue - value: sliderRoot.upperValue - busy: UM.LayerView.busy - setValue: rangeHandle.setValue // connect callback functions - } - } - - // Upper handle - Rectangle { - id: upperHandle - - y: sliderRoot.height - (sliderRoot.minimumRangeHandleSize + 2 * sliderRoot.handleSize) - width: sliderRoot.handleSize - height: sliderRoot.handleSize - anchors.horizontalCenter: sliderRoot.horizontalCenter - radius: sliderRoot.handleRadius - color: sliderRoot.upperHandleColor - visible: sliderRoot.layersVisible - - function onHandleDragged () { - - // don't allow the lower handle to be heigher than the upper handle - if (lowerHandle.y - (y + height) < sliderRoot.minimumRangeHandleSize) { - lowerHandle.y = y + height + sliderRoot.minimumRangeHandleSize - } - - // update the range handle - sliderRoot.updateRangeHandle() - - // set the new value after moving the handle position - UM.LayerView.setCurrentLayer(getValue()) - } - - // get the upper value based on the slider position - function getValue () { - var result = y / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) - result = sliderRoot.maximumValue + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumValue)) - result = sliderRoot.roundValues ? Math.round(result) : result - return result - } - - // set the slider position based on the upper value - function setValue (value) { - - UM.LayerView.setCurrentLayer(value) - - var diff = (value - sliderRoot.maximumValue) / (sliderRoot.minimumValue - sliderRoot.maximumValue) - var newUpperYPosition = Math.round(diff * (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize))) - y = newUpperYPosition - - // update the range handle - sliderRoot.updateRangeHandle() - } - - // dragging - MouseArea { - anchors.fill: parent - - drag { - target: parent - axis: Drag.YAxis - minimumY: 0 - maximumY: sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize) - } - - onPositionChanged: parent.onHandleDragged() - onPressed: sliderRoot.setActiveHandle(upperHandle) - } - - LayerSliderLabel { - id: upperHandleLabel - - height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width, y + height / 2) - visible: sliderRoot.activeHandle == parent - - // custom properties - maximumValue: sliderRoot.maximumValue - value: sliderRoot.upperValue - busy: UM.LayerView.busy - setValue: upperHandle.setValue // connect callback functions - } - } - - // Lower handle - Rectangle { - id: lowerHandle - - y: sliderRoot.height - sliderRoot.handleSize - width: parent.handleSize - height: parent.handleSize - anchors.horizontalCenter: parent.horizontalCenter - radius: sliderRoot.handleRadius - color: sliderRoot.lowerHandleColor - - visible: slider.layersVisible - - function onHandleDragged () { - - // don't allow the upper handle to be lower than the lower handle - if (y - (upperHandle.y + upperHandle.height) < sliderRoot.minimumRangeHandleSize) { - upperHandle.y = y - (upperHandle.heigth + sliderRoot.minimumRangeHandleSize) - } - - // update the range handle - sliderRoot.updateRangeHandle() - - // set the new value after moving the handle position - UM.LayerView.setMinimumLayer(getValue()) - } - - // get the lower value from the current slider position - function getValue () { - var result = (y - (sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)) / (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize)); - result = sliderRoot.maximumValue - sliderRoot.minimumRange + result * (sliderRoot.minimumValue - (sliderRoot.maximumValue - sliderRoot.minimumRange)) - result = sliderRoot.roundValues ? Math.round(result) : result - return result - } - - // set the slider position based on the lower value - function setValue (value) { - - UM.LayerView.setMinimumLayer(value) - - var diff = (value - sliderRoot.maximumValue) / (sliderRoot.minimumValue - sliderRoot.maximumValue) - var newLowerYPosition = Math.round((sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize) + diff * (sliderRoot.height - (2 * sliderRoot.handleSize + sliderRoot.minimumRangeHandleSize))) - y = newLowerYPosition - - // update the range handle - sliderRoot.updateRangeHandle() - } - - // dragging - MouseArea { - anchors.fill: parent - - drag { - target: parent - axis: Drag.YAxis - minimumY: upperHandle.height + sliderRoot.minimumRangeHandleSize - maximumY: sliderRoot.height - parent.height - } - - onPositionChanged: parent.onHandleDragged() - onPressed: sliderRoot.setActiveHandle(lowerHandle) - } - - LayerSliderLabel { - id: lowerHandleLabel - - height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height - x: parent.x - width - UM.Theme.getSize("default_margin").width - anchors.verticalCenter: parent.verticalCenter - target: Qt.point(sliderRoot.width, y + height / 2) - visible: sliderRoot.activeHandle == parent - - // custom properties - maximumValue: sliderRoot.maximumValue - value: sliderRoot.lowerValue - busy: UM.LayerView.busy - setValue: lowerHandle.setValue // connect callback functions - } - } -} diff --git a/plugins/LayerView/LayerSliderLabel.qml b/plugins/LayerView/LayerSliderLabel.qml deleted file mode 100644 index c989679285..0000000000 --- a/plugins/LayerView/LayerSliderLabel.qml +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.2 -import QtQuick.Controls 1.2 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.0 as UM -import Cura 1.0 as Cura - -UM.PointingRectangle { - id: sliderLabelRoot - - // custom properties - property real maximumValue: 100 - property real value: 0 - property var setValue // Function - property bool busy: false - - target: Qt.point(parent.width, y + height / 2) - arrowSize: UM.Theme.getSize("default_arrow").width - height: parent.height - width: valueLabel.width + UM.Theme.getSize("default_margin").width - visible: false - - // make sure the text field is focussed when pressing the parent handle - // needed to connect the key bindings when switching active handle - onVisibleChanged: if (visible) valueLabel.forceActiveFocus() - - color: UM.Theme.getColor("tool_panel_background") - borderColor: UM.Theme.getColor("lining") - borderWidth: UM.Theme.getSize("default_lining").width - - Behavior on height { - NumberAnimation { - duration: 50 - } - } - - // catch all mouse events so they're not handled by underlying 3D scene - MouseArea { - anchors.fill: parent - } - - TextField { - id: valueLabel - - anchors { - left: parent.left - leftMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) - verticalCenter: parent.verticalCenter - } - - width: 40 * screenScaleFactor - text: sliderLabelRoot.value + 1 // the current handle value, add 1 because layers is an array - horizontalAlignment: TextInput.AlignRight - - // key bindings, work when label is currenctly focused (active handle in LayerSlider) - Keys.onUpPressed: sliderLabelRoot.setValue(sliderLabelRoot.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) - Keys.onDownPressed: sliderLabelRoot.setValue(sliderLabelRoot.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1)) - - style: TextFieldStyle { - textColor: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") - background: Item { } - } - - onEditingFinished: { - - // Ensure that the cursor is at the first position. On some systems the text isn't fully visible - // Seems to have to do something with different dpi densities that QML doesn't quite handle. - // Another option would be to increase the size even further, but that gives pretty ugly results. - cursorPosition = 0 - - if (valueLabel.text != "") { - // -1 because we need to convert back to an array structure - sliderLabelRoot.setValue(parseInt(valueLabel.text) - 1) - } - } - - validator: IntValidator { - bottom: 1 - top: sliderLabelRoot.maximumValue + 1 // +1 because actual layers is an array - } - } - - BusyIndicator { - id: busyIndicator - - anchors { - left: parent.right - leftMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) - verticalCenter: parent.verticalCenter - } - - width: sliderLabelRoot.height - height: width - - visible: sliderLabelRoot.busy - running: sliderLabelRoot.busy - } -} diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py deleted file mode 100755 index 04be97b747..0000000000 --- a/plugins/LayerView/LayerView.py +++ /dev/null @@ -1,495 +0,0 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -import sys - -from UM.PluginRegistry import PluginRegistry -from UM.View.View import View -from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from UM.Resources import Resources -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.MeshBuilder import MeshBuilder -from UM.Job import Job -from UM.Preferences import Preferences -from UM.Logger import Logger -from UM.View.GL.OpenGL import OpenGL -from UM.Message import Message -from UM.Application import Application -from UM.View.GL.OpenGLContext import OpenGLContext - -from cura.ConvexHullNode import ConvexHullNode -from cura.Settings.ExtruderManager import ExtruderManager - -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QApplication - -from . import LayerViewProxy - -from UM.i18n import i18nCatalog -catalog = i18nCatalog("cura") - -from . import LayerPass - -import numpy -import os.path - -## View used to display g-code paths. -class LayerView(View): - # Must match LayerView.qml - LAYER_VIEW_TYPE_MATERIAL_TYPE = 0 - LAYER_VIEW_TYPE_LINE_TYPE = 1 - - def __init__(self): - super().__init__() - - self._max_layers = 0 - self._current_layer_num = 0 - self._minimum_layer_num = 0 - self._current_layer_mesh = None - self._current_layer_jumps = None - self._top_layers_job = None - self._activity = False - self._old_max_layers = 0 - - self._busy = False - - self._ghost_shader = None - self._layer_pass = None - self._composite_pass = None - self._old_layer_bindings = None - self._layerview_composite_shader = None - self._old_composite_shader = None - - self._global_container_stack = None - self._proxy = LayerViewProxy.LayerViewProxy() - self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged) - - self._resetSettings() - self._legend_items = None - self._show_travel_moves = False - - Preferences.getInstance().addPreference("view/top_layer_count", 5) - Preferences.getInstance().addPreference("view/only_show_top_layers", False) - Preferences.getInstance().addPreference("view/force_layer_view_compatibility_mode", False) - - Preferences.getInstance().addPreference("layerview/layer_view_type", 0) - Preferences.getInstance().addPreference("layerview/extruder_opacities", "") - - Preferences.getInstance().addPreference("layerview/show_travel_moves", False) - Preferences.getInstance().addPreference("layerview/show_helpers", True) - Preferences.getInstance().addPreference("layerview/show_skin", True) - Preferences.getInstance().addPreference("layerview/show_infill", True) - - Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) - self._updateWithPreferences() - - self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count")) - self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers")) - self._compatibility_mode = True # for safety - - self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"), - title = catalog.i18nc("@info:title", "Layer View")) - - def _resetSettings(self): - self._layer_view_type = 0 # 0 is material color, 1 is color by linetype, 2 is speed - self._extruder_count = 0 - self._extruder_opacity = [1.0, 1.0, 1.0, 1.0] - self._show_travel_moves = 0 - self._show_helpers = 1 - self._show_skin = 1 - self._show_infill = 1 - - def getActivity(self): - return self._activity - - def getLayerPass(self): - if not self._layer_pass: - # Currently the RenderPass constructor requires a size > 0 - # This should be fixed in RenderPass's constructor. - self._layer_pass = LayerPass.LayerPass(1, 1) - self._compatibility_mode = OpenGLContext.isLegacyOpenGL() or bool(Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode")) - self._layer_pass.setLayerView(self) - return self._layer_pass - - def getCurrentLayer(self): - return self._current_layer_num - - def getMinimumLayer(self): - return self._minimum_layer_num - - def _onSceneChanged(self, node): - self.calculateMaxLayers() - - def getMaxLayers(self): - return self._max_layers - - busyChanged = Signal() - - def isBusy(self): - return self._busy - - def setBusy(self, busy): - if busy != self._busy: - self._busy = busy - self.busyChanged.emit() - - def resetLayerData(self): - self._current_layer_mesh = None - self._current_layer_jumps = None - - def beginRendering(self): - scene = self.getController().getScene() - renderer = self.getRenderer() - - if not self._ghost_shader: - self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) - self._ghost_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_ghost").getRgb())) - - 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(): - renderer.queueNode(node, transparent = True, shader = self._ghost_shader) - - def setLayer(self, value): - if self._current_layer_num != value: - self._current_layer_num = value - if self._current_layer_num < 0: - self._current_layer_num = 0 - if self._current_layer_num > self._max_layers: - self._current_layer_num = self._max_layers - if self._current_layer_num < self._minimum_layer_num: - self._minimum_layer_num = self._current_layer_num - - self._startUpdateTopLayers() - - self.currentLayerNumChanged.emit() - - def setMinimumLayer(self, value): - if self._minimum_layer_num != value: - self._minimum_layer_num = value - if self._minimum_layer_num < 0: - self._minimum_layer_num = 0 - if self._minimum_layer_num > self._max_layers: - self._minimum_layer_num = self._max_layers - if self._minimum_layer_num > self._current_layer_num: - self._current_layer_num = self._minimum_layer_num - - self._startUpdateTopLayers() - - self.currentLayerNumChanged.emit() - - ## Set the layer view type - # - # \param layer_view_type integer as in LayerView.qml and this class - def setLayerViewType(self, layer_view_type): - self._layer_view_type = layer_view_type - self.currentLayerNumChanged.emit() - - ## Return the layer view type, integer as in LayerView.qml and this class - def getLayerViewType(self): - return self._layer_view_type - - ## Set the extruder opacity - # - # \param extruder_nr 0..3 - # \param opacity 0.0 .. 1.0 - def setExtruderOpacity(self, extruder_nr, opacity): - if 0 <= extruder_nr <= 3: - self._extruder_opacity[extruder_nr] = opacity - self.currentLayerNumChanged.emit() - - def getExtruderOpacities(self): - return self._extruder_opacity - - def setShowTravelMoves(self, show): - self._show_travel_moves = show - self.currentLayerNumChanged.emit() - - def getShowTravelMoves(self): - return self._show_travel_moves - - def setShowHelpers(self, show): - self._show_helpers = show - self.currentLayerNumChanged.emit() - - def getShowHelpers(self): - return self._show_helpers - - def setShowSkin(self, show): - self._show_skin = show - self.currentLayerNumChanged.emit() - - def getShowSkin(self): - return self._show_skin - - def setShowInfill(self, show): - self._show_infill = show - self.currentLayerNumChanged.emit() - - def getShowInfill(self): - return self._show_infill - - def getCompatibilityMode(self): - return self._compatibility_mode - - def getExtruderCount(self): - return self._extruder_count - - def calculateMaxLayers(self): - scene = self.getController().getScene() - self._activity = True - - self._old_max_layers = self._max_layers - ## Recalculate num max layers - new_max_layers = 0 - for node in DepthFirstIterator(scene.getRoot()): - layer_data = node.callDecoration("getLayerData") - if not layer_data: - continue - - min_layer_number = sys.maxsize - max_layer_number = -sys.maxsize - for layer_id in layer_data.getLayers(): - if max_layer_number < layer_id: - max_layer_number = layer_id - if min_layer_number > layer_id: - min_layer_number = layer_id - layer_count = max_layer_number - min_layer_number - - if new_max_layers < layer_count: - new_max_layers = layer_count - - if new_max_layers > 0 and new_max_layers != self._old_max_layers: - self._max_layers = new_max_layers - - # The qt slider has a bit of weird behavior that if the maxvalue needs to be changed first - # if it's the largest value. If we don't do this, we can have a slider block outside of the - # slider. - if new_max_layers > self._current_layer_num: - self.maxLayersChanged.emit() - self.setLayer(int(self._max_layers)) - else: - self.setLayer(int(self._max_layers)) - self.maxLayersChanged.emit() - self._startUpdateTopLayers() - - maxLayersChanged = Signal() - currentLayerNumChanged = Signal() - globalStackChanged = Signal() - preferencesChanged = Signal() - - ## Hackish way to ensure the proxy is already created, which ensures that the layerview.qml is already created - # as this caused some issues. - def getProxy(self, engine, script_engine): - return self._proxy - - def endRendering(self): - pass - - def event(self, event): - modifiers = QApplication.keyboardModifiers() - ctrl_is_active = modifiers & Qt.ControlModifier - shift_is_active = modifiers & Qt.ShiftModifier - if event.type == Event.KeyPressEvent and ctrl_is_active: - amount = 10 if shift_is_active else 1 - if event.key == KeyEvent.UpKey: - self.setLayer(self._current_layer_num + amount) - return True - if event.key == KeyEvent.DownKey: - self.setLayer(self._current_layer_num - amount) - return True - - if event.type == Event.ViewActivateEvent: - # Make sure the LayerPass is created - layer_pass = self.getLayerPass() - self.getRenderer().addRenderPass(layer_pass) - - Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged) - self._onGlobalStackChanged() - - if not self._layerview_composite_shader: - self._layerview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layerview_composite.shader")) - theme = Application.getInstance().getTheme() - self._layerview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) - self._layerview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) - - if not self._composite_pass: - self._composite_pass = self.getRenderer().getRenderPass("composite") - - self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later - self._composite_pass.getLayerBindings().append("layerview") - self._old_composite_shader = self._composite_pass.getCompositeShader() - self._composite_pass.setCompositeShader(self._layerview_composite_shader) - - elif event.type == Event.ViewDeactivateEvent: - self._wireprint_warning_message.hide() - Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged) - if self._global_container_stack: - self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) - - self.getRenderer().removeRenderPass(self._layer_pass) - self._composite_pass.setLayerBindings(self._old_layer_bindings) - self._composite_pass.setCompositeShader(self._old_composite_shader) - - def getCurrentLayerMesh(self): - return self._current_layer_mesh - - def getCurrentLayerJumps(self): - return self._current_layer_jumps - - def _onGlobalStackChanged(self): - if self._global_container_stack: - self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) - self._global_container_stack = Application.getInstance().getGlobalContainerStack() - if self._global_container_stack: - self._global_container_stack.propertyChanged.connect(self._onPropertyChanged) - self._extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") - self._onPropertyChanged("wireframe_enabled", "value") - self.globalStackChanged.emit() - else: - self._wireprint_warning_message.hide() - - def _onPropertyChanged(self, key, property_name): - if key == "wireframe_enabled" and property_name == "value": - if self._global_container_stack.getProperty("wireframe_enabled", "value"): - self._wireprint_warning_message.show() - else: - self._wireprint_warning_message.hide() - - def _startUpdateTopLayers(self): - if not self._compatibility_mode: - return - - if self._top_layers_job: - self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh) - self._top_layers_job.cancel() - - self.setBusy(True) - - self._top_layers_job = _CreateTopLayersJob(self._controller.getScene(), self._current_layer_num, self._solid_layers) - self._top_layers_job.finished.connect(self._updateCurrentLayerMesh) - self._top_layers_job.start() - - def _updateCurrentLayerMesh(self, job): - self.setBusy(False) - - if not job.getResult(): - return - self.resetLayerData() # Reset the layer data only when job is done. Doing it now prevents "blinking" data. - self._current_layer_mesh = job.getResult().get("layers") - if self._show_travel_moves: - self._current_layer_jumps = job.getResult().get("jumps") - self._controller.getScene().sceneChanged.emit(self._controller.getScene().getRoot()) - - self._top_layers_job = None - - def _updateWithPreferences(self): - self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count")) - self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers")) - self._compatibility_mode = OpenGLContext.isLegacyOpenGL() or bool( - Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode")) - - self.setLayerViewType(int(float(Preferences.getInstance().getValue("layerview/layer_view_type")))); - - for extruder_nr, extruder_opacity in enumerate(Preferences.getInstance().getValue("layerview/extruder_opacities").split("|")): - try: - opacity = float(extruder_opacity) - except ValueError: - opacity = 1.0 - self.setExtruderOpacity(extruder_nr, opacity) - - self.setShowTravelMoves(bool(Preferences.getInstance().getValue("layerview/show_travel_moves"))) - self.setShowHelpers(bool(Preferences.getInstance().getValue("layerview/show_helpers"))) - self.setShowSkin(bool(Preferences.getInstance().getValue("layerview/show_skin"))) - self.setShowInfill(bool(Preferences.getInstance().getValue("layerview/show_infill"))) - - self._startUpdateTopLayers() - self.preferencesChanged.emit() - - def _onPreferencesChanged(self, preference): - if preference not in { - "view/top_layer_count", - "view/only_show_top_layers", - "view/force_layer_view_compatibility_mode", - "layerview/layer_view_type", - "layerview/extruder_opacities", - "layerview/show_travel_moves", - "layerview/show_helpers", - "layerview/show_skin", - "layerview/show_infill", - }: - return - - self._updateWithPreferences() - - -class _CreateTopLayersJob(Job): - def __init__(self, scene, layer_number, solid_layers): - super().__init__() - - self._scene = scene - self._layer_number = layer_number - self._solid_layers = solid_layers - self._cancel = False - - def run(self): - layer_data = None - for node in DepthFirstIterator(self._scene.getRoot()): - layer_data = node.callDecoration("getLayerData") - if layer_data: - break - - if self._cancel or not layer_data: - return - - layer_mesh = MeshBuilder() - for i in range(self._solid_layers): - layer_number = self._layer_number - i - if layer_number < 0: - continue - - try: - layer = layer_data.getLayer(layer_number).createMesh() - except Exception: - Logger.logException("w", "An exception occurred while creating layer mesh.") - return - - if not layer or layer.getVertices() is None: - continue - - layer_mesh.addIndices(layer_mesh.getVertexCount() + layer.getIndices()) - layer_mesh.addVertices(layer.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 = numpy.ones((1, 4), dtype=numpy.float32) * (2.0 - (i / self._solid_layers)) / 2.0 - brightness[0, 3] = 1.0 - layer_mesh.addColors(layer.getColors() * brightness) - - if self._cancel: - return - - Job.yieldThread() - - if self._cancel: - return - - Job.yieldThread() - jump_mesh = layer_data.getLayer(self._layer_number).createJumps() - if not jump_mesh or jump_mesh.getVertices() is None: - jump_mesh = None - - self.setResult({"layers": layer_mesh.build(), "jumps": jump_mesh}) - - def cancel(self): - self._cancel = True - super().cancel() - diff --git a/plugins/LayerView/LayerView.qml b/plugins/LayerView/LayerView.qml deleted file mode 100755 index 7261926bc5..0000000000 --- a/plugins/LayerView/LayerView.qml +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright (c) 2017 Ultimaker B.V. -// Cura is released under the terms of the LGPLv3 or higher. - -import QtQuick 2.4 -import QtQuick.Controls 1.2 -import QtQuick.Layouts 1.1 -import QtQuick.Controls.Styles 1.1 - -import UM 1.0 as UM -import Cura 1.0 as Cura - -Item -{ - id: base - width: { - if (UM.LayerView.compatibilityMode) { - return UM.Theme.getSize("layerview_menu_size_compatibility").width; - } else { - return UM.Theme.getSize("layerview_menu_size").width; - } - } - height: { - if (UM.LayerView.compatibilityMode) { - return UM.Theme.getSize("layerview_menu_size_compatibility").height; - } else if (UM.Preferences.getValue("layerview/layer_view_type") == 0) { - return UM.Theme.getSize("layerview_menu_size_material_color_mode").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) - } else { - return UM.Theme.getSize("layerview_menu_size").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) - } - } - - property var buttonTarget: { - if(parent != null) - { - var force_binding = parent.y; // ensure this gets reevaluated when the panel moves - return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y) - } - return Qt.point(0,0) - } - - visible: parent != null ? !parent.parent.monitoringPrint: true - - UM.PointingRectangle { - id: layerViewMenu - anchors.right: parent.right - anchors.top: parent.top - width: parent.width - height: parent.height - z: slider.z - 1 - color: UM.Theme.getColor("tool_panel_background") - borderWidth: UM.Theme.getSize("default_lining").width - borderColor: UM.Theme.getColor("lining") - arrowSize: 0 // hide arrow until weird issue with first time rendering is fixed - - ColumnLayout { - id: view_settings - - property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|") - property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves") - property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers") - property bool show_skin: UM.Preferences.getValue("layerview/show_skin") - property bool show_infill: UM.Preferences.getValue("layerview/show_infill") - // if we are in compatibility mode, we only show the "line type" - property bool show_legend: UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") == 1 - property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers") - property int top_layer_count: UM.Preferences.getValue("view/top_layer_count") - - anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("default_margin").height - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("default_margin").width - spacing: UM.Theme.getSize("layerview_row_spacing").height - anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - - Label - { - id: layerViewTypesLabel - anchors.left: parent.left - text: catalog.i18nc("@label","Color scheme") - font: UM.Theme.getFont("default"); - visible: !UM.LayerView.compatibilityMode - Layout.fillWidth: true - color: UM.Theme.getColor("setting_control_text") - } - - ListModel // matches LayerView.py - { - id: layerViewTypes - } - - Component.onCompleted: - { - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Material Color"), - type_id: 0 - }) - layerViewTypes.append({ - text: catalog.i18nc("@label:listbox", "Line Type"), - type_id: 1 // these ids match the switching in the shader - }) - } - - ComboBox - { - id: layerTypeCombobox - anchors.left: parent.left - Layout.fillWidth: true - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width - model: layerViewTypes - visible: !UM.LayerView.compatibilityMode - style: UM.Theme.styles.combobox - anchors.right: parent.right - anchors.rightMargin: 10 * screenScaleFactor - - onActivated: - { - UM.Preferences.setValue("layerview/layer_view_type", index); - } - - Component.onCompleted: - { - currentIndex = UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); - updateLegends(currentIndex); - } - - function updateLegends(type_id) - { - // update visibility of legends - view_settings.show_legend = UM.LayerView.compatibilityMode || (type_id == 1); - } - - } - - Label - { - id: compatibilityModeLabel - anchors.left: parent.left - text: catalog.i18nc("@label","Compatibility Mode") - font: UM.Theme.getFont("default") - color: UM.Theme.getColor("text") - visible: UM.LayerView.compatibilityMode - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width - } - - Label - { - id: space2Label - anchors.left: parent.left - text: " " - font.pointSize: 0.5 - } - - Connections { - target: UM.Preferences - onPreferenceChanged: - { - layerTypeCombobox.currentIndex = UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type"); - layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex); - view_settings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|"); - view_settings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves"); - view_settings.show_helpers = UM.Preferences.getValue("layerview/show_helpers"); - view_settings.show_skin = UM.Preferences.getValue("layerview/show_skin"); - view_settings.show_infill = UM.Preferences.getValue("layerview/show_infill"); - view_settings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers"); - view_settings.top_layer_count = UM.Preferences.getValue("view/top_layer_count"); - } - } - - Repeater { - model: Cura.ExtrudersModel{} - CheckBox { - id: extrudersModelCheckBox - checked: view_settings.extruder_opacities[index] > 0.5 || view_settings.extruder_opacities[index] == undefined || view_settings.extruder_opacities[index] == "" - onClicked: { - view_settings.extruder_opacities[index] = checked ? 1.0 : 0.0 - UM.Preferences.setValue("layerview/extruder_opacities", view_settings.extruder_opacities.join("|")); - } - visible: !UM.LayerView.compatibilityMode - enabled: index + 1 <= 4 - Rectangle { - anchors.verticalCenter: parent.verticalCenter - anchors.right: extrudersModelCheckBox.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: model.color - radius: width / 2 - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: !view_settings.show_legend - } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width - style: UM.Theme.styles.checkbox - Label - { - text: model.name - elide: Text.ElideRight - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") - anchors.verticalCenter: parent.verticalCenter - anchors.left: extrudersModelCheckBox.left; - anchors.right: extrudersModelCheckBox.right; - anchors.leftMargin: UM.Theme.getSize("checkbox").width + UM.Theme.getSize("default_margin").width /2 - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 - } - } - } - - Repeater { - model: ListModel { - id: typesLegenModel - Component.onCompleted: - { - typesLegenModel.append({ - label: catalog.i18nc("@label", "Show Travels"), - initialValue: view_settings.show_travel_moves, - preference: "layerview/show_travel_moves", - colorId: "layerview_move_combing" - }); - typesLegenModel.append({ - label: catalog.i18nc("@label", "Show Helpers"), - initialValue: view_settings.show_helpers, - preference: "layerview/show_helpers", - colorId: "layerview_support" - }); - typesLegenModel.append({ - label: catalog.i18nc("@label", "Show Shell"), - initialValue: view_settings.show_skin, - preference: "layerview/show_skin", - colorId: "layerview_inset_0" - }); - typesLegenModel.append({ - label: catalog.i18nc("@label", "Show Infill"), - initialValue: view_settings.show_infill, - preference: "layerview/show_infill", - colorId: "layerview_infill" - }); - } - } - - CheckBox { - id: legendModelCheckBox - checked: model.initialValue - onClicked: { - UM.Preferences.setValue(model.preference, checked); - } - Rectangle { - anchors.verticalCenter: parent.verticalCenter - anchors.right: legendModelCheckBox.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: UM.Theme.getColor(model.colorId) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: view_settings.show_legend - } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width - style: UM.Theme.styles.checkbox - Label - { - text: label - font: UM.Theme.getFont("default") - elide: Text.ElideRight - color: UM.Theme.getColor("setting_control_text") - anchors.verticalCenter: parent.verticalCenter - anchors.left: legendModelCheckBox.left; - anchors.right: legendModelCheckBox.right; - anchors.leftMargin: UM.Theme.getSize("checkbox").width + UM.Theme.getSize("default_margin").width /2 - anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 - } - } - } - - CheckBox { - checked: view_settings.only_show_top_layers - onClicked: { - UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0); - } - text: catalog.i18nc("@label", "Only Show Top Layers") - visible: UM.LayerView.compatibilityMode - style: UM.Theme.styles.checkbox - } - CheckBox { - checked: view_settings.top_layer_count == 5 - onClicked: { - UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1); - } - text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") - visible: UM.LayerView.compatibilityMode - style: UM.Theme.styles.checkbox - } - - Repeater { - model: ListModel { - id: typesLegenModelNoCheck - Component.onCompleted: - { - typesLegenModelNoCheck.append({ - label: catalog.i18nc("@label", "Top / Bottom"), - colorId: "layerview_skin", - }); - typesLegenModelNoCheck.append({ - label: catalog.i18nc("@label", "Inner Wall"), - colorId: "layerview_inset_x", - }); - } - } - - Label { - text: label - visible: view_settings.show_legend - id: typesLegendModelLabel - Rectangle { - anchors.verticalCenter: parent.verticalCenter - anchors.right: typesLegendModelLabel.right - anchors.rightMargin: UM.Theme.getSize("default_margin").width - width: UM.Theme.getSize("layerview_legend_size").width - height: UM.Theme.getSize("layerview_legend_size").height - color: UM.Theme.getColor(model.colorId) - border.width: UM.Theme.getSize("default_lining").width - border.color: UM.Theme.getColor("lining") - visible: view_settings.show_legend - } - Layout.fillWidth: true - Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height - Layout.preferredWidth: UM.Theme.getSize("layerview_row").width - color: UM.Theme.getColor("setting_control_text") - font: UM.Theme.getFont("default") - } - } - } - - LayerSlider { - id: slider - - width: UM.Theme.getSize("slider_handle").width - height: UM.Theme.getSize("layerview_menu_size").height - - anchors { - top: parent.bottom - topMargin: UM.Theme.getSize("slider_layerview_margin").height - right: layerViewMenu.right - rightMargin: UM.Theme.getSize("slider_layerview_margin").width - } - - // custom properties - upperValue: UM.LayerView.currentLayer - lowerValue: UM.LayerView.minimumLayer - maximumValue: UM.LayerView.numLayers - handleSize: UM.Theme.getSize("slider_handle").width - trackThickness: UM.Theme.getSize("slider_groove").width - trackColor: UM.Theme.getColor("slider_groove") - trackBorderColor: UM.Theme.getColor("slider_groove_border") - upperHandleColor: UM.Theme.getColor("slider_handle") - lowerHandleColor: UM.Theme.getColor("slider_handle") - rangeHandleColor: UM.Theme.getColor("slider_groove_fill") - handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width - layersVisible: UM.LayerView.layerActivity && CuraApplication.platformActivity ? true : false - - // update values when layer data changes - Connections { - target: UM.LayerView - onMaxLayersChanged: slider.setUpperValue(UM.LayerView.currentLayer) - onMinimumLayerChanged: slider.setLowerValue(UM.LayerView.minimumLayer) - onCurrentLayerChanged: slider.setUpperValue(UM.LayerView.currentLayer) - } - - // make sure the slider handlers show the correct value after switching views - Component.onCompleted: { - slider.setLowerValue(UM.LayerView.minimumLayer) - slider.setUpperValue(UM.LayerView.currentLayer) - } - } - } - - FontMetrics { - id: fontMetrics - font: UM.Theme.getFont("default") - } -} diff --git a/plugins/LayerView/LayerViewProxy.py b/plugins/LayerView/LayerViewProxy.py deleted file mode 100644 index 4cf84117da..0000000000 --- a/plugins/LayerView/LayerViewProxy.py +++ /dev/null @@ -1,151 +0,0 @@ -from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty -from UM.FlameProfiler import pyqtSlot -from UM.Application import Application - -import LayerView - - -class LayerViewProxy(QObject): - def __init__(self, parent=None): - super().__init__(parent) - self._current_layer = 0 - self._controller = Application.getInstance().getController() - self._controller.activeViewChanged.connect(self._onActiveViewChanged) - self._onActiveViewChanged() - - currentLayerChanged = pyqtSignal() - maxLayersChanged = pyqtSignal() - activityChanged = pyqtSignal() - globalStackChanged = pyqtSignal() - preferencesChanged = pyqtSignal() - busyChanged = pyqtSignal() - - @pyqtProperty(bool, notify=activityChanged) - def layerActivity(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getActivity() - - @pyqtProperty(int, notify=maxLayersChanged) - def numLayers(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getMaxLayers() - - @pyqtProperty(int, notify=currentLayerChanged) - def currentLayer(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getCurrentLayer() - - @pyqtProperty(int, notify=currentLayerChanged) - def minimumLayer(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getMinimumLayer() - - @pyqtProperty(bool, notify=busyChanged) - def busy(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.isBusy() - - return False - - @pyqtProperty(bool, notify=preferencesChanged) - def compatibilityMode(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getCompatibilityMode() - return False - - @pyqtSlot(int) - def setCurrentLayer(self, layer_num): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setLayer(layer_num) - - @pyqtSlot(int) - def setMinimumLayer(self, layer_num): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setMinimumLayer(layer_num) - - @pyqtSlot(int) - def setLayerViewType(self, layer_view_type): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setLayerViewType(layer_view_type) - - @pyqtSlot(result=int) - def getLayerViewType(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getLayerViewType() - return 0 - - # Opacity 0..1 - @pyqtSlot(int, float) - def setExtruderOpacity(self, extruder_nr, opacity): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setExtruderOpacity(extruder_nr, opacity) - - @pyqtSlot(int) - def setShowTravelMoves(self, show): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setShowTravelMoves(show) - - @pyqtSlot(int) - def setShowHelpers(self, show): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setShowHelpers(show) - - @pyqtSlot(int) - def setShowSkin(self, show): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setShowSkin(show) - - @pyqtSlot(int) - def setShowInfill(self, show): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.setShowInfill(show) - - @pyqtProperty(int, notify=globalStackChanged) - def extruderCount(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - return active_view.getExtruderCount() - return 0 - - def _layerActivityChanged(self): - self.activityChanged.emit() - - def _onLayerChanged(self): - self.currentLayerChanged.emit() - self._layerActivityChanged() - - def _onMaxLayersChanged(self): - self.maxLayersChanged.emit() - - def _onBusyChanged(self): - self.busyChanged.emit() - - def _onGlobalStackChanged(self): - self.globalStackChanged.emit() - - def _onPreferencesChanged(self): - self.preferencesChanged.emit() - - def _onActiveViewChanged(self): - active_view = self._controller.getActiveView() - if type(active_view) == LayerView.LayerView.LayerView: - active_view.currentLayerNumChanged.connect(self._onLayerChanged) - active_view.maxLayersChanged.connect(self._onMaxLayersChanged) - active_view.busyChanged.connect(self._onBusyChanged) - active_view.globalStackChanged.connect(self._onGlobalStackChanged) - active_view.preferencesChanged.connect(self._onPreferencesChanged) diff --git a/plugins/LayerView/__init__.py b/plugins/LayerView/__init__.py deleted file mode 100644 index da1a5aed19..0000000000 --- a/plugins/LayerView/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2015 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from . import LayerView, LayerViewProxy -from PyQt5.QtQml import qmlRegisterType, qmlRegisterSingletonType - -from UM.i18n import i18nCatalog -catalog = i18nCatalog("cura") - -def getMetaData(): - return { - "view": { - "name": catalog.i18nc("@item:inlistbox", "Layer view"), - "view_panel": "LayerView.qml", - "weight": 2 - } - } - -def createLayerViewProxy(engine, script_engine): - return LayerViewProxy.LayerViewProxy() - -def register(app): - layer_view = LayerView.LayerView() - qmlRegisterSingletonType(LayerViewProxy.LayerViewProxy, "UM", 1, 0, "LayerView", layer_view.getProxy) - return { "view": LayerView.LayerView() } diff --git a/plugins/LayerView/layers.shader b/plugins/LayerView/layers.shader deleted file mode 100755 index d340773403..0000000000 --- a/plugins/LayerView/layers.shader +++ /dev/null @@ -1,156 +0,0 @@ -[shaders] -vertex = - uniform highp mat4 u_modelViewProjectionMatrix; - uniform lowp float u_active_extruder; - uniform lowp float u_shade_factor; - uniform highp int u_layer_view_type; - - attribute highp float a_extruder; - attribute highp float a_line_type; - attribute highp vec4 a_vertex; - attribute lowp vec4 a_color; - attribute lowp vec4 a_material_color; - - varying lowp vec4 v_color; - varying float v_line_type; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - // shade the color depending on the extruder index - v_color = a_color; - // 8 and 9 are travel moves - if ((a_line_type != 8.0) && (a_line_type != 9.0)) { - v_color = (a_extruder == u_active_extruder) ? v_color : vec4(u_shade_factor * v_color.rgb, v_color.a); - } - - v_line_type = a_line_type; - } - -fragment = - varying lowp vec4 v_color; - varying float v_line_type; - - uniform int u_show_travel_moves; - uniform int u_show_helpers; - uniform int u_show_skin; - uniform int u_show_infill; - - void main() - { - if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) { // actually, 8 and 9 - // discard movements - discard; - } - // support: 4, 5, 7, 10 - if ((u_show_helpers == 0) && ( - ((v_line_type >= 3.5) && (v_line_type <= 4.5)) || - ((v_line_type >= 6.5) && (v_line_type <= 7.5)) || - ((v_line_type >= 9.5) && (v_line_type <= 10.5)) || - ((v_line_type >= 4.5) && (v_line_type <= 5.5)) - )) { - discard; - } - // skin: 1, 2, 3 - if ((u_show_skin == 0) && ( - (v_line_type >= 0.5) && (v_line_type <= 3.5) - )) { - discard; - } - // infill: - if ((u_show_infill == 0) && (v_line_type >= 5.5) && (v_line_type <= 6.5)) { - // discard movements - discard; - } - - gl_FragColor = v_color; - } - -vertex41core = - #version 410 - uniform highp mat4 u_modelViewProjectionMatrix; - uniform lowp float u_active_extruder; - uniform lowp float u_shade_factor; - uniform highp int u_layer_view_type; - - in highp float a_extruder; - in highp float a_line_type; - in highp vec4 a_vertex; - in lowp vec4 a_color; - in lowp vec4 a_material_color; - - out lowp vec4 v_color; - out float v_line_type; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - v_color = a_color; - if ((a_line_type != 8) && (a_line_type != 9)) { - v_color = (a_extruder == u_active_extruder) ? v_color : vec4(u_shade_factor * v_color.rgb, v_color.a); - } - - v_line_type = a_line_type; - } - -fragment41core = - #version 410 - in lowp vec4 v_color; - in float v_line_type; - out vec4 frag_color; - - uniform int u_show_travel_moves; - uniform int u_show_helpers; - uniform int u_show_skin; - uniform int u_show_infill; - - void main() - { - if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) { // actually, 8 and 9 - // discard movements - discard; - } - // helpers: 4, 5, 7, 10 - if ((u_show_helpers == 0) && ( - ((v_line_type >= 3.5) && (v_line_type <= 4.5)) || - ((v_line_type >= 6.5) && (v_line_type <= 7.5)) || - ((v_line_type >= 9.5) && (v_line_type <= 10.5)) || - ((v_line_type >= 4.5) && (v_line_type <= 5.5)) - )) { - discard; - } - // skin: 1, 2, 3 - if ((u_show_skin == 0) && ( - (v_line_type >= 0.5) && (v_line_type <= 3.5) - )) { - discard; - } - // infill: - if ((u_show_infill == 0) && (v_line_type >= 5.5) && (v_line_type <= 6.5)) { - // discard movements - discard; - } - - frag_color = v_color; - } - -[defaults] -u_active_extruder = 0.0 -u_shade_factor = 0.60 -u_layer_view_type = 0 -u_extruder_opacity = [1.0, 1.0, 1.0, 1.0] - -u_show_travel_moves = 0 -u_show_helpers = 1 -u_show_skin = 1 -u_show_infill = 1 - -[bindings] -u_modelViewProjectionMatrix = model_view_projection_matrix - -[attributes] -a_vertex = vertex -a_color = color -a_extruder = extruder -a_line_type = line_type -a_material_color = material_color diff --git a/plugins/LayerView/layers3d.shader b/plugins/LayerView/layers3d.shader deleted file mode 100755 index e8fe425c70..0000000000 --- a/plugins/LayerView/layers3d.shader +++ /dev/null @@ -1,264 +0,0 @@ -[shaders] -vertex41core = - #version 410 - uniform highp mat4 u_modelViewProjectionMatrix; - - uniform highp mat4 u_modelMatrix; - uniform highp mat4 u_viewProjectionMatrix; - uniform lowp float u_active_extruder; - uniform lowp int u_layer_view_type; - uniform lowp vec4 u_extruder_opacity; // currently only for max 4 extruders, others always visible - - uniform highp mat4 u_normalMatrix; - - in highp vec4 a_vertex; - in lowp vec4 a_color; - in lowp vec4 a_material_color; - in highp vec4 a_normal; - in highp vec2 a_line_dim; // line width and thickness - in highp float a_extruder; - in highp float a_line_type; - - out lowp vec4 v_color; - - out highp vec3 v_vertex; - out highp vec3 v_normal; - out lowp vec2 v_line_dim; - out highp int v_extruder; - out highp vec4 v_extruder_opacity; - out float v_line_type; - - out lowp vec4 f_color; - out highp vec3 f_vertex; - out highp vec3 f_normal; - - void main() - { - vec4 v1_vertex = a_vertex; - v1_vertex.y -= a_line_dim.y / 2; // half layer down - - vec4 world_space_vert = u_modelMatrix * v1_vertex; - gl_Position = world_space_vert; - // shade the color depending on the extruder index stored in the alpha component of the color - - switch (u_layer_view_type) { - case 0: // "Material color" - v_color = a_material_color; - break; - case 1: // "Line type" - v_color = a_color; - break; - } - - v_vertex = world_space_vert.xyz; - v_normal = (u_normalMatrix * normalize(a_normal)).xyz; - v_line_dim = a_line_dim; - v_extruder = int(a_extruder); - v_line_type = a_line_type; - v_extruder_opacity = u_extruder_opacity; - - // for testing without geometry shader - f_color = v_color; - f_vertex = v_vertex; - f_normal = v_normal; - } - -geometry41core = - #version 410 - - uniform highp mat4 u_viewProjectionMatrix; - uniform int u_show_travel_moves; - uniform int u_show_helpers; - uniform int u_show_skin; - uniform int u_show_infill; - - layout(lines) in; - layout(triangle_strip, max_vertices = 26) out; - - in vec4 v_color[]; - in vec3 v_vertex[]; - in vec3 v_normal[]; - in vec2 v_line_dim[]; - in int v_extruder[]; - in vec4 v_extruder_opacity[]; - in float v_line_type[]; - - out vec4 f_color; - out vec3 f_normal; - out vec3 f_vertex; - - // Set the set of variables and EmitVertex - void myEmitVertex(vec3 vertex, vec4 color, vec3 normal, vec4 pos) { - f_vertex = vertex; - f_color = color; - f_normal = normal; - gl_Position = pos; - EmitVertex(); - } - - void main() - { - vec4 g_vertex_delta; - vec3 g_vertex_normal_horz; // horizontal and vertical in respect to layers - vec4 g_vertex_offset_horz; // vec4 to match gl_in[x].gl_Position - vec3 g_vertex_normal_vert; - vec4 g_vertex_offset_vert; - vec3 g_vertex_normal_horz_head; - vec4 g_vertex_offset_horz_head; - - float size_x; - float size_y; - - if ((v_extruder_opacity[0][v_extruder[0]] == 0.0) && (v_line_type[0] != 8) && (v_line_type[0] != 9)) { - return; - } - // See LayerPolygon; 8 is MoveCombingType, 9 is RetractionType - if ((u_show_travel_moves == 0) && ((v_line_type[0] == 8) || (v_line_type[0] == 9))) { - return; - } - if ((u_show_helpers == 0) && ((v_line_type[0] == 4) || (v_line_type[0] == 5) || (v_line_type[0] == 7) || (v_line_type[0] == 10))) { - return; - } - if ((u_show_skin == 0) && ((v_line_type[0] == 1) || (v_line_type[0] == 2) || (v_line_type[0] == 3))) { - return; - } - if ((u_show_infill == 0) && (v_line_type[0] == 6)) { - return; - } - - if ((v_line_type[0] == 8) || (v_line_type[0] == 9)) { - // fixed size for movements - size_x = 0.05; - } else { - size_x = v_line_dim[1].x / 2 + 0.01; // radius, and make it nicely overlapping - } - size_y = v_line_dim[1].y / 2 + 0.01; - - g_vertex_delta = gl_in[1].gl_Position - gl_in[0].gl_Position; - g_vertex_normal_horz_head = normalize(vec3(-g_vertex_delta.x, -g_vertex_delta.y, -g_vertex_delta.z)); - g_vertex_offset_horz_head = vec4(g_vertex_normal_horz_head * size_x, 0.0); - - g_vertex_normal_horz = normalize(vec3(g_vertex_delta.z, g_vertex_delta.y, -g_vertex_delta.x)); - - g_vertex_offset_horz = vec4(g_vertex_normal_horz * size_x, 0.0); //size * g_vertex_normal_horz; - g_vertex_normal_vert = vec3(0.0, 1.0, 0.0); - g_vertex_offset_vert = vec4(g_vertex_normal_vert * size_y, 0.0); - - if ((v_line_type[0] == 8) || (v_line_type[0] == 9)) { - // Travels: flat plane with pointy ends - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert)); - - EndPrimitive(); - } else { - // All normal lines are rendered as 3d tubes. - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); - - EndPrimitive(); - - // left side - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); - - EndPrimitive(); - - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); - - EndPrimitive(); - - // right side - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz)); - - EndPrimitive(); - - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); - - EndPrimitive(); - } - } - -fragment41core = - #version 410 - in lowp vec4 f_color; - in lowp vec3 f_normal; - in lowp vec3 f_vertex; - - out vec4 frag_color; - - uniform mediump vec4 u_ambientColor; - uniform highp vec3 u_lightPosition; - - void main() - { - mediump vec4 finalColor = vec4(0.0); - float alpha = f_color.a; - - finalColor.rgb += f_color.rgb * 0.3; - - highp vec3 normal = normalize(f_normal); - highp vec3 light_dir = normalize(u_lightPosition - f_vertex); - - // Diffuse Component - highp float NdotL = clamp(dot(normal, light_dir), 0.0, 1.0); - finalColor += (NdotL * f_color); - finalColor.a = alpha; // Do not change alpha in any way - - frag_color = finalColor; - } - - -[defaults] -u_active_extruder = 0.0 -u_layer_view_type = 0 -u_extruder_opacity = [1.0, 1.0, 1.0, 1.0] - -u_specularColor = [0.4, 0.4, 0.4, 1.0] -u_ambientColor = [0.3, 0.3, 0.3, 0.0] -u_diffuseColor = [1.0, 0.79, 0.14, 1.0] -u_shininess = 20.0 - -u_show_travel_moves = 0 -u_show_helpers = 1 -u_show_skin = 1 -u_show_infill = 1 - -[bindings] -u_modelViewProjectionMatrix = model_view_projection_matrix -u_modelMatrix = model_matrix -u_viewProjectionMatrix = view_projection_matrix -u_normalMatrix = normal_matrix -u_lightPosition = light_0_position - -[attributes] -a_vertex = vertex -a_color = color -a_normal = normal -a_line_dim = line_dim -a_extruder = extruder -a_material_color = material_color -a_line_type = line_type diff --git a/plugins/LayerView/layerview_composite.shader b/plugins/LayerView/layerview_composite.shader deleted file mode 100644 index dcc02acc84..0000000000 --- a/plugins/LayerView/layerview_composite.shader +++ /dev/null @@ -1,148 +0,0 @@ -[shaders] -vertex = - uniform highp mat4 u_modelViewProjectionMatrix; - attribute highp vec4 a_vertex; - attribute highp vec2 a_uvs; - - varying highp vec2 v_uvs; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - v_uvs = a_uvs; - } - -fragment = - uniform sampler2D u_layer0; - uniform sampler2D u_layer1; - uniform sampler2D u_layer2; - - uniform vec2 u_offset[9]; - - uniform vec4 u_background_color; - uniform float u_outline_strength; - uniform vec4 u_outline_color; - - varying vec2 v_uvs; - - float kernel[9]; - - const vec3 x_axis = vec3(1.0, 0.0, 0.0); - const vec3 y_axis = vec3(0.0, 1.0, 0.0); - const vec3 z_axis = vec3(0.0, 0.0, 1.0); - - void main() - { - // blur kernel - kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; - kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; - kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; - - vec4 result = u_background_color; - - vec4 main_layer = texture2D(u_layer0, v_uvs); - vec4 selection_layer = texture2D(u_layer1, v_uvs); - vec4 layerview_layer = texture2D(u_layer2, v_uvs); - - result = main_layer * main_layer.a + result * (1.0 - main_layer.a); - result = layerview_layer * layerview_layer.a + result * (1.0 - layerview_layer.a); - - vec4 sum = vec4(0.0); - for (int i = 0; i < 9; i++) - { - vec4 color = vec4(texture2D(u_layer1, v_uvs.xy + u_offset[i]).a); - sum += color * (kernel[i] / u_outline_strength); - } - - if((selection_layer.rgb == x_axis || selection_layer.rgb == y_axis || selection_layer.rgb == z_axis)) - { - gl_FragColor = result; - } - else - { - gl_FragColor = mix(result, u_outline_color, abs(sum.a)); - } - } - -vertex41core = - #version 410 - uniform highp mat4 u_modelViewProjectionMatrix; - in highp vec4 a_vertex; - in highp vec2 a_uvs; - - out highp vec2 v_uvs; - - void main() - { - gl_Position = u_modelViewProjectionMatrix * a_vertex; - v_uvs = a_uvs; - } - -fragment41core = - #version 410 - uniform sampler2D u_layer0; - uniform sampler2D u_layer1; - uniform sampler2D u_layer2; - - uniform vec2 u_offset[9]; - - uniform vec4 u_background_color; - uniform float u_outline_strength; - uniform vec4 u_outline_color; - - in vec2 v_uvs; - - float kernel[9]; - - const vec3 x_axis = vec3(1.0, 0.0, 0.0); - const vec3 y_axis = vec3(0.0, 1.0, 0.0); - const vec3 z_axis = vec3(0.0, 0.0, 1.0); - - out vec4 frag_color; - - void main() - { - // blur kernel - kernel[0] = 0.0; kernel[1] = 1.0; kernel[2] = 0.0; - kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; - kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; - - vec4 result = u_background_color; - - vec4 main_layer = texture(u_layer0, v_uvs); - vec4 selection_layer = texture(u_layer1, v_uvs); - vec4 layerview_layer = texture(u_layer2, v_uvs); - - result = main_layer * main_layer.a + result * (1.0 - main_layer.a); - result = layerview_layer * layerview_layer.a + result * (1.0 - layerview_layer.a); - - vec4 sum = vec4(0.0); - for (int i = 0; i < 9; i++) - { - vec4 color = vec4(texture(u_layer1, v_uvs.xy + u_offset[i]).a); - sum += color * (kernel[i] / u_outline_strength); - } - - if((selection_layer.rgb == x_axis || selection_layer.rgb == y_axis || selection_layer.rgb == z_axis)) - { - frag_color = result; - } - else - { - frag_color = mix(result, u_outline_color, abs(sum.a)); - } - } - -[defaults] -u_layer0 = 0 -u_layer1 = 1 -u_layer2 = 2 -u_background_color = [0.965, 0.965, 0.965, 1.0] -u_outline_strength = 1.0 -u_outline_color = [0.05, 0.66, 0.89, 1.0] - -[bindings] - -[attributes] -a_vertex = vertex -a_uvs = uv diff --git a/plugins/LayerView/plugin.json b/plugins/LayerView/plugin.json deleted file mode 100644 index 232fe9c361..0000000000 --- a/plugins/LayerView/plugin.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "Layer View", - "author": "Ultimaker B.V.", - "version": "1.0.0", - "description": "Provides the Layer view.", - "api": 4, - "i18n-catalog": "cura" -} diff --git a/resources/themes/cura-dark/theme.json b/resources/themes/cura-dark/theme.json index e61c48bffd..5cfed426e5 100644 --- a/resources/themes/cura-dark/theme.json +++ b/resources/themes/cura-dark/theme.json @@ -133,6 +133,7 @@ "slider_groove_fill": [245, 245, 245, 255], "slider_handle": [255, 255, 255, 255], "slider_handle_hover": [77, 182, 226, 255], + "slider_handle_active": [68, 192, 255, 255], "slider_handle_border": [39, 44, 48, 255], "slider_text_background": [255, 255, 255, 255], @@ -194,6 +195,7 @@ "layerview_move_combing": [0, 0, 255, 255], "layerview_move_retraction": [128, 128, 255, 255], "layerview_support_interface": [64, 192, 255, 255], + "layerview_nozzle": [181, 166, 66, 120], "material_compatibility_warning": [255, 255, 255, 255], diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml index 6d991c5541..ea9d184926 100755 --- a/resources/themes/cura-light/styles.qml +++ b/resources/themes/cura-light/styles.qml @@ -269,6 +269,7 @@ QtObject { arrowSize: Theme.getSize("button_tooltip_arrow").width color: Theme.getColor("button_tooltip") opacity: control.hovered ? 1.0 : 0.0; + visible: control.text != "" width: control.hovered ? button_tip.width + Theme.getSize("button_tooltip").width : 0 height: Theme.getSize("button_tooltip").height diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index f084e87da2..4197285dd8 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -183,6 +183,7 @@ "slider_groove_fill": [127, 127, 127, 255], "slider_handle": [0, 0, 0, 255], "slider_handle_hover": [77, 182, 226, 255], + "slider_handle_active": [68, 192, 255, 255], "slider_handle_border": [39, 44, 48, 255], "slider_text_background": [255, 255, 255, 255], @@ -271,7 +272,8 @@ "layerview_support_infill": [0, 255, 255, 255], "layerview_move_combing": [0, 0, 255, 255], "layerview_move_retraction": [128, 128, 255, 255], - "layerview_support_interface": [64, 192, 255, 255] + "layerview_support_interface": [64, 192, 255, 255], + "layerview_nozzle": [181, 166, 66, 50] }, "sizes": {