diff --git a/cura/Layer.py b/cura/Layer.py index af42488e2a..52c4583f54 100644 --- a/cura/Layer.py +++ b/cura/Layer.py @@ -43,14 +43,22 @@ class Layer: 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: + 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): diff --git a/cura/LayerDataBuilder.py b/cura/LayerDataBuilder.py index d8801c9e7b..6760098667 100755 --- a/cura/LayerDataBuilder.py +++ b/cura/LayerDataBuilder.py @@ -63,6 +63,7 @@ class LayerDataBuilder(MeshBuilder): 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 @@ class LayerDataBuilder(MeshBuilder): "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 7f62a0a8fa..cf4bb47a86 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -55,6 +55,14 @@ class LayerPolygon: 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)) + 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]) @@ -207,6 +215,10 @@ class LayerPolygon: def jumpCount(self): return self._jump_count + @property + def cumulativeTypeChangeCounts(self): + 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 2754fb5d94..3f5f12a702 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -142,6 +142,7 @@ class SimulationPass(RenderPass): 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,20 @@ class SimulationPass(RenderPass): 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] + end += layer_data.getLayer(layer).lineMeshVertexCount() + if layer < self._layer_view._minimum_layer_num: + start = end # Calculate the range of paths in the last layer + 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/layers3d.shader b/plugins/SimulationView/layers3d.shader index f9d67f284c..4bd54d6d35 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 && u_drawRange[1] >= 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, -1] + [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 88268938c9..92ea43ad64 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 && u_drawRange[1] >= 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, -1] + [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