Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphics Buffer Update -- New PR #10259

Merged
merged 12 commits into from
Nov 15, 2021
23 changes: 22 additions & 1 deletion cura/Layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions cura/LayerDataBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
}
}

Expand Down
23 changes: 23 additions & 0 deletions cura/LayerPolygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.

Expand Down
20 changes: 14 additions & 6 deletions plugins/SimulationView/SimulationPass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
18 changes: 16 additions & 2 deletions plugins/SimulationView/layers3d.shader
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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
16 changes: 15 additions & 1 deletion plugins/SimulationView/layers3d_shadow.shader
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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