From 1217281727d9496a7c31b1f36872eec88e91bbdd Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 29 Dec 2016 16:49:00 +0100 Subject: [PATCH] Busy with layer_view options --- cura/Layer.py | 4 +- cura/LayerDataBuilder.py | 27 ++++-- cura/LayerPolygon.py | 6 +- .../ProcessSlicedLayersJob.py | 34 +++++++- plugins/LayerView/LayerPass.py | 4 + plugins/LayerView/LayerView.qml | 72 +++++++++++++++ plugins/LayerView/layers.shader | 87 +++++++++++-------- 7 files changed, 187 insertions(+), 47 deletions(-) diff --git a/cura/Layer.py b/cura/Layer.py index 3103d1772e..8d35e9c6b2 100644 --- a/cura/Layer.py +++ b/cura/Layer.py @@ -49,12 +49,12 @@ class Layer: return result - def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, indices): + def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, 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, indices) + polygon.build(result_vertex_offset, result_index_offset, vertices, colors, line_dimensions, extruders, 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 41c7790102..2b46a604b7 100644 --- a/cura/LayerDataBuilder.py +++ b/cura/LayerDataBuilder.py @@ -48,7 +48,8 @@ class LayerDataBuilder(MeshBuilder): self._layers[layer].setThickness(thickness) - def build(self): + # material color map: [r, g, b, a] for each extruder row. + def build(self, material_color_map): vertex_count = 0 index_count = 0 for layer, data in self._layers.items(): @@ -59,23 +60,39 @@ 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) + extruders = numpy.empty((vertex_count), numpy.float32) vertex_offset = 0 index_offset = 0 for layer, data in self._layers.items(): - ( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, line_dimensions, indices) + ( vertex_offset, index_offset ) = data.build( vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, indices) self._element_counts[layer] = data.elementCount self.addVertices(vertices) self.addColors(colors) self.addIndices(indices.flatten()) - # self._uvs = line_dimensions + + material_colors = numpy.zeros((line_dimensions.shape[0], 4), dtype=numpy.float32) + for extruder_nr in range(material_color_map.shape[0]): + material_colors[extruders == extruder_nr] = material_color_map[extruder_nr] + attributes = { "line_dimensions": { "value": line_dimensions, "opengl_name": "a_line_dim", - "opengl_type": "vector2f"} - } + "opengl_type": "vector2f" + }, + "extruders": { + "value": extruders, + "opengl_name": "a_extruder", + "opengl_type": "float" + }, + "colors": { + "value": material_colors, + "opengl_name": "a_material_color", + "opengl_type": "vector4f" + }, + } return LayerData(vertices=self.getVertices(), normals=self.getNormals(), indices=self.getIndices(), colors=self.getColors(), uvs=self.getUVCoordinates(), file_name=self.getFileName(), diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 439146e6e2..bb37d641bb 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -38,7 +38,7 @@ class LayerPolygon: # Buffering the colors shouldn't be necessary as it is not # re-used and can save alot of memory usage. - self._color_map = self.__color_map * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr + self._color_map = self.__color_map # * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr self._colors = self._color_map[self._types] # When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType @@ -67,7 +67,7 @@ class LayerPolygon: ## build # line_thicknesses: array with type as index and thickness as value - def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, indices): + def build(self, vertex_offset, index_offset, vertices, colors, line_dimensions, extruders, indices): if (self._build_cache_line_mesh_mask is None) or (self._build_cache_needed_points is None ): self.buildCache() @@ -94,6 +94,8 @@ class LayerPolygon: 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] + extruders[self._vertex_begin:self._vertex_end] = float(self._extruder) + # The relative values of begin and end indices have already been set in buildCache, so we only need to offset them to the parents offset. self._index_begin += index_offset self._index_end += index_offset diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py index be148e41f6..d7be0f1a52 100644 --- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py +++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py @@ -24,6 +24,14 @@ from time import time catalog = i18nCatalog("cura") +def colorCodeToRGBA(color_code): + return [ + int(color_code[1:3], 16) / 255, + int(color_code[3:5], 16) / 255, + int(color_code[5:7], 16) / 255, + 1.0] + + class ProcessSlicedLayersJob(Job): def __init__(self, layers): super().__init__() @@ -148,7 +156,31 @@ class ProcessSlicedLayersJob(Job): self._progress.setProgress(progress) # We are done processing all the layers we got from the engine, now create a mesh out of the data - layer_mesh = layer_data.build() + + # Find out colors per extruder + # TODO: move to a better place. Code is similar to code in ExtrudersModel + from cura.Settings.ExtruderManager import ExtruderManager + import UM + global_container_stack = UM.Application.getInstance().getGlobalContainerStack() + manager = ExtruderManager.getInstance() + extruders = list(manager.getMachineExtruders(global_container_stack.getId())) + if extruders: + material_color_map = numpy.zeros((len(extruders), 4), dtype=numpy.float32) + for extruder in extruders: + material = extruder.findContainer({"type": "material"}) + position = int(extruder.getMetaDataEntry("position", default="0")) # Get the position + color_code = material.getMetaDataEntry("color_code") + color = colorCodeToRGBA(color_code) + material_color_map[position, :] = color + else: + # Single extruder via global stack. + material_color_map = numpy.zeros((1, 4), dtype=numpy.float32) + material = global_container_stack.findContainer({"type": "material"}) + color_code = material.getMetaDataEntry("color_code") + color = colorCodeToRGBA(color_code) + material_color_map[0, :] = color + + layer_mesh = layer_data.build(material_color_map) if self._abort_requested: if self._progress: diff --git a/plugins/LayerView/LayerPass.py b/plugins/LayerView/LayerPass.py index 378f7278c4..dda35624ec 100644 --- a/plugins/LayerView/LayerPass.py +++ b/plugins/LayerView/LayerPass.py @@ -37,6 +37,10 @@ class LayerPass(RenderPass): self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layers.shader")) # 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))) + self._layer_shader.setUniformValue("u_layer_view_type", 0) + self._layer_shader.setUniformValue("u_only_color_active_extruder", 1) + self._layer_shader.setUniformValue("u_extruder_opacity", [1, 1, 1, 1]) + if not self._tool_handle_shader: self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader")) diff --git a/plugins/LayerView/LayerView.qml b/plugins/LayerView/LayerView.qml index fef0c52c12..68c51e5752 100644 --- a/plugins/LayerView/LayerView.qml +++ b/plugins/LayerView/LayerView.qml @@ -95,6 +95,7 @@ Item } Rectangle { + id: slider_background anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter z: slider.z - 1 @@ -113,4 +114,75 @@ Item } } } + + Rectangle { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.top: slider_background.bottom + width: UM.Theme.getSize("slider_layerview_background").width * 3 + height: slider.height + UM.Theme.getSize("default_margin").height * 2 + color: UM.Theme.getColor("tool_panel_background"); + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("lining") + + ListModel + { + id: layerViewTypes + ListElement { + text: "Line type" + type_id: 0 // these ids match the switching in the shader + } + ListElement { + text: "Material color" + type_id: 1 + } + ListElement { + text: "Printing speed" + type_id: 2 + } + } + + ComboBox + { + id: layer_type_combobox + anchors.top: slider_background.bottom + model: layerViewTypes + onActivated: { + CuraApplication.log("Combobox" + String(index)); + CuraApplication.log(layerViewTypes.get(index).type_id); + } + } + + ColumnLayout { + anchors.top: layer_type_combobox.bottom + CheckBox { + checked: true + onClicked: { + CuraApplication.log("First"); + } + text: "Extruder 1" + } + CheckBox { + checked: true + onClicked: { + CuraApplication.log("First"); + } + text: "Extruder 2" + } + CheckBox { + onClicked: { + CuraApplication.log("First"); + } + text: "Travel moves" + } + CheckBox { + checked: true + onClicked: { + CuraApplication.log("First"); + } + text: "Only color active extruder" + } + } + + } } diff --git a/plugins/LayerView/layers.shader b/plugins/LayerView/layers.shader index cb34360226..869230e87d 100644 --- a/plugins/LayerView/layers.shader +++ b/plugins/LayerView/layers.shader @@ -4,24 +4,33 @@ vertex = //uniform highp mat4 u_viewProjectionMatrix; //uniform highp mat4 u_modelViewProjectionMatrix; uniform lowp float u_active_extruder; + uniform lowp int u_layer_view_type; + uniform lowp int u_only_color_active_extruder; + uniform lowp vec4 u_extruder_opacity; // currently only for max 4 extruders, others always visible + uniform lowp float u_shade_factor; uniform highp mat4 u_normalMatrix; attribute highp vec4 a_vertex; attribute lowp vec4 a_color; + attribute lowp vec4 a_material_color; attribute highp vec4 a_normal; attribute highp vec2 a_line_dim; // line width and thickness + attribute highp int a_extruder; varying lowp vec4 v_color; + //varying lowp vec4 v_material_color; varying highp vec3 v_vertex; varying highp vec3 v_normal; //varying lowp vec2 v_uvs; varying lowp vec2 v_line_dim; + varying highp int v_extruder; varying lowp vec4 f_color; varying highp vec3 f_vertex; varying highp vec3 f_normal; + varying highp int f_extruder; void main() { @@ -32,17 +41,38 @@ vertex = gl_Position = world_space_vert; // gl_Position = u_modelViewProjectionMatrix * a_vertex; // shade the color depending on the extruder index stored in the alpha component of the color - v_color = (a_color.a == u_active_extruder) ? a_color : vec4(0.4, 0.4, 0.4, 1.0); //a_color * u_shade_factor; - v_color.a = 1.0; + + switch (u_layer_view_type) { + case 0: // "Line type" + v_color = a_color; + break; + case 1: // "Material color" + v_color = a_material_color; + break; + case 2: // "Speed" + v_color = a_color; + break; + } + if (u_only_color_active_extruder == 1) { + v_color = (a_extruder == u_active_extruder) ? v_color : vec4(0.4, 0.4, 0.4, 1.0); + } else { + v_color = (a_extruder == u_active_extruder) ? v_color : v_color * u_shade_factor; + } + if (a_extruder < 4) { + v_color.a *= u_extruder_opacity[a_extruder]; // make it (in)visible + } v_vertex = world_space_vert.xyz; v_normal = (u_normalMatrix * normalize(a_normal)).xyz; v_line_dim = a_line_dim; + v_extruder = a_extruder; + //v_material_color = a_material_color; // for testing without geometry shader f_color = v_color; f_vertex = v_vertex; f_normal = v_normal; + f_extruder = v_extruder; } geometry = @@ -57,10 +87,14 @@ geometry = in vec3 v_vertex[]; in vec3 v_normal[]; in vec2 v_line_dim[]; + in int v_extruder[]; + //in vec4 v_material_color[]; out vec4 f_color; out vec3 f_normal; out vec3 f_vertex; + out uint f_extruder; + //out vec4 f_material_color; void main() { @@ -75,6 +109,9 @@ geometry = float size_x = v_line_dim[0].x / 2 + 0.01; // radius, and make it nicely overlapping float size_y = v_line_dim[0].y / 2 + 0.01; + f_extruder = v_extruder[0]; + //f_material_color = v_material_color[0]; + //g_vertex_normal_horz = normalize(v_normal[0]); //vec3(g_vertex_delta.z, g_vertex_delta.y, -g_vertex_delta.x); 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)); @@ -241,41 +278,19 @@ geometry = fragment = varying lowp vec4 f_color; + //varying lowp vec4 f_material_color; varying lowp vec3 f_normal; varying lowp vec3 f_vertex; + //flat varying lowp uint f_extruder; uniform mediump vec4 u_ambientColor; - uniform mediump vec4 u_diffuseColor; - //uniform mediump vec4 u_specularColor; - //uniform mediump float u_shininess; - uniform highp vec3 u_lightPosition; - void Impostor(in float sphereRadius, in vec3 cameraSpherePos, in vec2 mapping, out vec3 cameraPos, out vec3 cameraNormal) - { - float lensqr = dot(mapping, mapping); - if(lensqr > 1.0) - discard; - - cameraNormal = vec3(mapping, sqrt(1.0 - lensqr)); - cameraPos = (cameraNormal * sphereRadius) + cameraSpherePos; - } - void main() { - vec3 cameraPos; - vec3 cameraNormal; - - //Impostor(0.2, vec3(0.0, 0.0, 0.0), vec2(0.1, 0.1), cameraPos, cameraNormal); - - //gl_FrontFacing = .. - - //if ((f_normal).z < 0) {discard; } - mediump vec4 finalColor = vec4(0.0); finalColor += u_ambientColor; - //finalColor = f_color; highp vec3 normal = normalize(f_normal); highp vec3 lightDir = normalize(u_lightPosition - f_vertex); @@ -283,23 +298,19 @@ fragment = // Diffuse Component highp float NdotL = clamp(dot(normal, lightDir), 0.0, 1.0); finalColor += (NdotL * f_color); + //finalColor += (NdotL * f_material_color); + //finalColor.a = 1.0; - // Specular Component - // TODO: We should not do specularity for fragments facing away from the light. - /*highp vec3 reflectedLight = reflect(-lightDir, normal); - highp vec3 viewVector = normalize(u_viewPosition - f_vertex); - highp float NdotR = clamp(dot(viewVector, reflectedLight), 0.0, 1.0); - finalColor += pow(NdotR, u_shininess) * u_specularColor;*/ - - finalColor.a = 1.0; gl_FragColor = finalColor; - - //gl_FragColor = f_color; - //gl_FragColor = vec4(f_normal, 1.0); } + [defaults] u_active_extruder = 0.0 +u_layer_view_type = 0 +u_only_color_active_extruder = 1 +u_extruder_opacity = [1.0, 1.0] + u_shade_factor = 0.60 u_specularColor = [0.4, 0.4, 0.4, 1.0] u_ambientColor = [0.3, 0.3, 0.3, 0.3] @@ -318,3 +329,5 @@ a_vertex = vertex a_color = color a_normal = normal a_line_dim = line_dim +a_extruder = extruders +a_material_color = material_color