diff --git a/cura/Layer.py b/cura/Layer.py index af42488e2a8..87aad3c9495 100644 --- a/cura/Layer.py +++ b/cura/Layer.py @@ -15,6 +15,7 @@ def __init__(self, layer_id: int) -> None: self._height = 0.0 self._thickness = 0.0 self._polygons = [] # type: List[LayerPolygon] + self._vertex_count = 0 self._element_count = 0 @property @@ -29,6 +30,10 @@ def thickness(self): def polygons(self) -> List[LayerPolygon]: return self._polygons + @property + def vertexCount(self): + return self._vertex_count + @property def elementCount(self): return self._element_count @@ -43,24 +48,40 @@ def lineMeshVertexCount(self) -> int: result = 0 for polygon in self._polygons: result += polygon.lineMeshVertexCount() - return result def lineMeshElementCount(self) -> int: result = 0 for polygon in self._polygons: result += polygon.lineMeshElementCount() + return result + def lineMeshCumulativeTypeChangeCount(self, path: int) -> int: + """ The number of line-type changes in this layer up until #path. + See also LayerPolygon::cumulativeTypeChangeCounts. + + :param path: The path-index up until which the cumulative changes are counted. + :return: The cumulative number of line-type changes up until this path. + """ + result = 0 + for polygon in self._polygons: + num_counts = len(polygon.cumulativeTypeChangeCounts) + if path < num_counts: + return result + polygon.cumulativeTypeChangeCounts[path] + path -= num_counts + result += polygon.cumulativeTypeChangeCounts[num_counts - 1] return result 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._vertex_count = 0 self._element_count = 0 for polygon in self._polygons: 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._vertex_count += polygon.vertexCount self._element_count += polygon.elementCount return result_vertex_offset, result_index_offset diff --git a/cura/LayerDataBuilder.py b/cura/LayerDataBuilder.py index d8801c9e7bb..39eced5ac6c 100755 --- a/cura/LayerDataBuilder.py +++ b/cura/LayerDataBuilder.py @@ -63,6 +63,7 @@ def build(self, material_color_map, line_type_brightness = 1.0): feedrates = numpy.empty((vertex_count), numpy.float32) extruders = numpy.empty((vertex_count), numpy.float32) line_types = numpy.empty((vertex_count), numpy.float32) + vertex_indices = numpy.arange(0, vertex_count, 1, dtype = numpy.float32) vertex_offset = 0 index_offset = 0 @@ -109,6 +110,12 @@ def build(self, material_color_map, line_type_brightness = 1.0): "value": feedrates, "opengl_name": "a_feedrate", "opengl_type": "float" + }, + # Can't use glDrawElements to index (due to oversight in (Py)Qt), can't use gl_PrimitiveID (due to legacy support): + "vertex_indices": { + "value": vertex_indices, + "opengl_name": "a_vertex_index", + "opengl_type": "float" } } diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 2c3b432b1d6..5eb8c96ec50 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -55,6 +55,14 @@ def __init__(self, extruder: int, line_types: numpy.ndarray, data: numpy.ndarray self._jump_mask = self.__jump_map[self._types] self._jump_count = numpy.sum(self._jump_mask) + self._cumulative_type_change_counts = numpy.zeros(len(self._types)) # See the comment on the 'cumulativeTypeChangeCounts' property below. + last_type = self.types[0] + current_type_count = 0 + for i in range(0, len(self._cumulative_type_change_counts)): + if last_type != self.types[i]: + current_type_count += 1 + last_type = self.types[i] + self._cumulative_type_change_counts[i] = current_type_count self._mesh_line_count = len(self._types) - self._jump_count self._vertex_count = self._mesh_line_count + numpy.sum(self._types[1:] == self._types[:-1]) @@ -179,6 +187,10 @@ def types(self): def data(self): return self._data + @property + def vertexCount(self): + return self._vertex_end - self._vertex_begin + @property def elementCount(self): return (self._index_end - self._index_begin) * 2 # The range of vertices multiplied by 2 since each vertex is used twice @@ -207,6 +219,17 @@ def meshLineCount(self): def jumpCount(self): return self._jump_count + @property + def cumulativeTypeChangeCounts(self): + """ This polygon class stores with a vertex the type of the line to the next vertex. However, in other contexts, + other ways of representing this might be more suited to the task (for example, when a vertex can possibly only + have _one_ type, it's unavoidable to duplicate vertices when the type is changed). In such situations it's might + be useful to know how many times the type has changed, in order to keep the various vertex-indices aligned. + + :return: The total times the line-type changes from one type to another within this LayerPolygon. + """ + return self._cumulative_type_change_counts + def getNormals(self) -> numpy.ndarray: """Calculate normals for the entire polygon using numpy. diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py index 2754fb5d949..86cf643e082 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -142,6 +142,7 @@ def render(self): 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 + current_polygon_offset = 0 element_counts = layer_data.getElementCounts() for layer in sorted(element_counts.keys()): # In the current layer, we show just the indicated paths @@ -155,18 +156,25 @@ def render(self): if index >= polygon.data.size // 3 - offset: index -= polygon.data.size // 3 - offset offset = 1 # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon + current_polygon_offset += 1 continue # The head position is calculated and translated head_position = Vector(polygon.data[index+offset][0], polygon.data[index+offset][1], polygon.data[index+offset][2]) + node.getWorldPosition() break break - if self._layer_view._minimum_layer_num > layer: - start += element_counts[layer] - end += element_counts[layer] - - # Calculate the range of paths in the last layer + end += layer_data.getLayer(layer).vertexCount + if layer < self._layer_view._minimum_layer_num: + start = end + + # Calculate the range of paths in the last layer. -- The type-change count is needed to keep the + # vertex-indices aligned between the two different ways we represent polygons here. + # Since there is one type per line, that could give a vertex two different types, if it's a vertex + # where a type-chage occurs. However, the shader expects vertices to have only one type. In order to + # fix this, those vertices are duplicated. This introduces a discrepancy that we have to take into + # account, which is done by the type-change-count. + type_change_count = layer_data.getLayer(self._layer_view._current_layer_num).lineMeshCumulativeTypeChangeCount(max(self._layer_view._current_path_num - 1, 0)) current_layer_start = end - current_layer_end = end + self._layer_view._current_path_num * 2 # Because each point is used twice + current_layer_end = current_layer_start + self._layer_view._current_path_num + current_polygon_offset + type_change_count # This uses glDrawRangeElements internally to only draw a certain range of lines. # All the layers but the current selected layer are rendered first diff --git a/plugins/SimulationView/layers.shader b/plugins/SimulationView/layers.shader index e6210c2b65b..97e0180307c 100644 --- a/plugins/SimulationView/layers.shader +++ b/plugins/SimulationView/layers.shader @@ -13,9 +13,11 @@ vertex = attribute highp vec4 a_vertex; attribute lowp vec4 a_color; attribute lowp vec4 a_material_color; + attribute highp float a_vertex_index; varying lowp vec4 v_color; varying float v_line_type; + varying highp float v_vertex_index; void main() { @@ -28,6 +30,7 @@ vertex = } v_line_type = a_line_type; + v_vertex_index = a_vertex_index; } fragment = @@ -40,14 +43,21 @@ fragment = #endif // GL_ES varying lowp vec4 v_color; varying float v_line_type; + varying highp float v_vertex_index; uniform int u_show_travel_moves; uniform int u_show_helpers; uniform int u_show_skin; uniform int u_show_infill; + uniform highp vec2 u_drawRange; + void main() { + if (u_drawRange.x >= 0.0 && u_drawRange.y >= 0.0 && (v_vertex_index < u_drawRange.x || v_vertex_index > u_drawRange.y)) + { + discard; + } if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) { // actually, 8 and 9 // discard movements discard; @@ -77,77 +87,6 @@ fragment = gl_FragColor = v_color; } -vertex41core = - #version 410 - uniform highp mat4 u_modelMatrix; - uniform highp mat4 u_viewMatrix; - uniform highp mat4 u_projectionMatrix; - - 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_projectionMatrix * u_viewMatrix * u_modelMatrix * 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 @@ -159,10 +98,13 @@ u_show_helpers = 1 u_show_skin = 1 u_show_infill = 1 +u_drawRange = [-1.0, -1.0] + [bindings] u_modelMatrix = model_matrix u_viewMatrix = view_matrix u_projectionMatrix = projection_matrix +u_drawRange = draw_range [attributes] a_vertex = vertex @@ -170,3 +112,4 @@ a_color = color a_extruder = extruder a_line_type = line_type a_material_color = material_color +a_vertex_index = vertex_index diff --git a/plugins/SimulationView/layers3d.shader b/plugins/SimulationView/layers3d.shader index f9d67f284ca..dc5aee2d1cb 100644 --- a/plugins/SimulationView/layers3d.shader +++ b/plugins/SimulationView/layers3d.shader @@ -27,6 +27,7 @@ vertex41core = in highp float a_extruder; in highp float a_prev_line_type; in highp float a_line_type; + in highp float a_vertex_index; in highp float a_feedrate; in highp float a_thickness; @@ -37,8 +38,9 @@ vertex41core = out lowp vec2 v_line_dim; out highp int v_extruder; out highp mat4 v_extruder_opacity; - out float v_prev_line_type; - out float v_line_type; + out highp float v_prev_line_type; + out highp float v_line_type; + out highp float v_index; out lowp vec4 f_color; out highp vec3 f_vertex; @@ -168,6 +170,7 @@ vertex41core = v_extruder = int(a_extruder); v_prev_line_type = a_prev_line_type; v_line_type = a_line_type; + v_index = a_vertex_index; v_extruder_opacity = u_extruder_opacity; // for testing without geometry shader @@ -191,6 +194,8 @@ geometry41core = uniform int u_show_infill; uniform int u_show_starts; + uniform highp vec2 u_drawRange; + layout(lines) in; layout(triangle_strip, max_vertices = 40) out; @@ -202,6 +207,7 @@ geometry41core = in mat4 v_extruder_opacity[]; in float v_prev_line_type[]; in float v_line_type[]; + in float v_index[]; out vec4 f_color; out vec3 f_normal; @@ -231,6 +237,10 @@ geometry41core = float size_x; float size_y; + if (u_drawRange[0] >= 0.0 && u_drawRange[1] >= 0.0 && (v_index[0] < u_drawRange[0] || v_index[0] >= u_drawRange[1])) + { + return; + } if ((v_extruder_opacity[0][int(mod(v_extruder[0], 4))][v_extruder[0] / 4] == 0.0) && (v_line_type[0] != 8) && (v_line_type[0] != 9)) { return; } @@ -427,12 +437,15 @@ u_max_feedrate = 1 u_min_thickness = 0 u_max_thickness = 1 +u_drawRange = [-1.0, -1.0] + [bindings] u_modelMatrix = model_matrix u_viewMatrix = view_matrix u_projectionMatrix = projection_matrix u_normalMatrix = normal_matrix u_lightPosition = light_0_position +u_drawRange = draw_range [attributes] a_vertex = vertex @@ -445,3 +458,4 @@ a_prev_line_type = prev_line_type a_line_type = line_type a_feedrate = feedrate a_thickness = thickness +a_vertex_index = vertex_index diff --git a/plugins/SimulationView/layers3d_shadow.shader b/plugins/SimulationView/layers3d_shadow.shader index 88268938c94..81ae84ae053 100644 --- a/plugins/SimulationView/layers3d_shadow.shader +++ b/plugins/SimulationView/layers3d_shadow.shader @@ -18,6 +18,7 @@ vertex41core = in highp vec2 a_line_dim; // line width and thickness in highp float a_extruder; in highp float a_line_type; + in highp float a_vertex_index; out lowp vec4 v_color; @@ -26,7 +27,8 @@ vertex41core = out lowp vec2 v_line_dim; out highp int v_extruder; out highp mat4 v_extruder_opacity; - out float v_line_type; + out highp float v_line_type; + out highp float v_index; out lowp vec4 f_color; out highp vec3 f_vertex; @@ -47,6 +49,7 @@ vertex41core = v_line_dim = a_line_dim; v_extruder = int(a_extruder); v_line_type = a_line_type; + v_index = a_vertex_index; v_extruder_opacity = u_extruder_opacity; // for testing without geometry shader @@ -67,6 +70,8 @@ geometry41core = uniform int u_show_skin; uniform int u_show_infill; + uniform highp vec2 u_drawRange; + layout(lines) in; layout(triangle_strip, max_vertices = 26) out; @@ -77,6 +82,7 @@ geometry41core = in int v_extruder[]; in mat4 v_extruder_opacity[]; in float v_line_type[]; + in float v_index[]; out vec4 f_color; out vec3 f_normal; @@ -106,6 +112,10 @@ geometry41core = float size_x; float size_y; + if (u_drawRange[0] >= 0.0 && u_drawRange[1] >= 0.0 && (v_index[0] < u_drawRange[0] || v_index[0] >= u_drawRange[1])) + { + return; + } if ((v_extruder_opacity[0][int(mod(v_extruder[0], 4))][v_extruder[0] / 4] == 0.0) && (v_line_type[0] != 8) && (v_line_type[0] != 9)) { return; } @@ -268,12 +278,15 @@ u_show_helpers = 1 u_show_skin = 1 u_show_infill = 1 +u_drawRange = [-1.0, -1.0] + [bindings] u_modelMatrix = model_matrix u_viewMatrix = view_matrix u_projectionMatrix = projection_matrix u_normalMatrix = normal_matrix u_lightPosition = light_0_position +u_drawRange = draw_range [attributes] a_vertex = vertex @@ -284,3 +297,4 @@ a_line_dim = line_dim a_extruder = extruder a_material_color = material_color a_line_type = line_type +a_vertex_index = vertex_index diff --git a/plugins/SimulationView/layers_shadow.shader b/plugins/SimulationView/layers_shadow.shader index 4bc2de3d0b1..403fd2bd8e6 100644 --- a/plugins/SimulationView/layers_shadow.shader +++ b/plugins/SimulationView/layers_shadow.shader @@ -13,9 +13,11 @@ vertex = attribute highp vec4 a_vertex; attribute lowp vec4 a_color; attribute lowp vec4 a_material_color; + attribute highp float a_vertex_index; varying lowp vec4 v_color; varying float v_line_type; + varying highp float v_vertex_index; void main() { @@ -28,6 +30,7 @@ vertex = // } v_line_type = a_line_type; + v_vertex_index = a_vertex_index; } fragment = @@ -40,14 +43,21 @@ fragment = #endif // GL_ES varying lowp vec4 v_color; varying float v_line_type; + varying highp float v_vertex_index; uniform int u_show_travel_moves; uniform int u_show_helpers; uniform int u_show_skin; uniform int u_show_infill; + uniform highp vec2 u_drawRange; + void main() { + if (u_drawRange.x >= 0.0 && u_drawRange.y >= 0.0 && (v_vertex_index < u_drawRange.x || v_vertex_index > u_drawRange.y)) + { + discard; + } if ((u_show_travel_moves == 0) && (v_line_type >= 7.5) && (v_line_type <= 9.5)) { // actually, 8 and 9 // discard movements @@ -81,78 +91,6 @@ fragment = gl_FragColor = v_color; } -vertex41core = - #version 410 - uniform highp mat4 u_modelMatrix; - uniform highp mat4 u_viewMatrix; - uniform highp mat4 u_projectionMatrix; - - 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_projectionMatrix * u_viewMatrix * u_modelMatrix * a_vertex; - v_color = vec4(0.4, 0.4, 0.4, 0.9); // default color for not current layer - // 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, 11 - 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)) || - ((v_line_type >= 10.5) && (v_line_type <= 11.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 @@ -164,10 +102,13 @@ u_show_helpers = 1 u_show_skin = 1 u_show_infill = 1 +u_drawRange = [-1.0, -1.0] + [bindings] u_modelMatrix = model_matrix u_viewMatrix = view_matrix u_projectionMatrix = projection_matrix +u_drawRange = draw_range [attributes] a_vertex = vertex @@ -175,3 +116,4 @@ a_color = color a_extruder = extruder a_line_type = line_type a_material_color = material_color +a_vertex_index = vertex_index