优化gcodeviewer.py,现在渲染非常流畅
This commit is contained in:
@@ -29,6 +29,7 @@ class AIOPrrintSystemAPI:
|
|||||||
# },
|
# },
|
||||||
# 'progress': {
|
# 'progress': {
|
||||||
# 'completion': random.uniform(0, 100.0),
|
# 'completion': random.uniform(0, 100.0),
|
||||||
|
# # 'filepos': random.randint(1234,20934490),
|
||||||
# 'filepos': 20934490,
|
# 'filepos': 20934490,
|
||||||
# 'printTime': random.randint(1234,54321),
|
# 'printTime': random.randint(1234,54321),
|
||||||
# 'printTimeLeft': random.randint(1234,54321),
|
# 'printTimeLeft': random.randint(1234,54321),
|
||||||
|
|||||||
@@ -7,15 +7,17 @@ from PyQt6.QtOpenGL import QOpenGLShaderProgram, QOpenGLShader, QOpenGLBuffer
|
|||||||
class GCodeParseWorker(QThread):
|
class GCodeParseWorker(QThread):
|
||||||
finished = pyqtSignal(dict)
|
finished = pyqtSignal(dict)
|
||||||
|
|
||||||
def __init__(self, filepath, type_map, default_colors, parent=None):
|
def __init__(self, filepath, type_map, default_colors, type_id_map, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.filepath = filepath
|
self.filepath = filepath
|
||||||
self.TYPE_MAP = type_map
|
self.TYPE_MAP = type_map
|
||||||
self.DEFAULT_COLORS = default_colors
|
self.DEFAULT_COLORS = default_colors
|
||||||
|
self.TYPE_ID_MAP = type_id_map
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
points = []
|
points = []
|
||||||
colors = []
|
colors = []
|
||||||
|
filters = []
|
||||||
type_segments = {}
|
type_segments = {}
|
||||||
segment_zs = {}
|
segment_zs = {}
|
||||||
type_visibility = {}
|
type_visibility = {}
|
||||||
@@ -25,6 +27,7 @@ class GCodeParseWorker(QThread):
|
|||||||
feature_type = 'OTHER'
|
feature_type = 'OTHER'
|
||||||
current_segment_type = 'OTHER'
|
current_segment_type = 'OTHER'
|
||||||
segment_start = 0
|
segment_start = 0
|
||||||
|
segment_count = {}
|
||||||
type_visibility['TRAVEL'] = False
|
type_visibility['TRAVEL'] = False
|
||||||
|
|
||||||
relative_e = False
|
relative_e = False
|
||||||
@@ -126,6 +129,7 @@ class GCodeParseWorker(QThread):
|
|||||||
# add_segment(current_segment_type, segment_start, vertex_idx - segment_start, z)
|
# add_segment(current_segment_type, segment_start, vertex_idx - segment_start, z)
|
||||||
current_segment_type = seg_type
|
current_segment_type = seg_type
|
||||||
segment_start = vertex_idx
|
segment_start = vertex_idx
|
||||||
|
segment_count[seg_type] = segment_count.get(seg_type, 0) + 1
|
||||||
|
|
||||||
if new_x < min_x: min_x = new_x
|
if new_x < min_x: min_x = new_x
|
||||||
if new_x > max_x: max_x = new_x
|
if new_x > max_x: max_x = new_x
|
||||||
@@ -150,6 +154,13 @@ class GCodeParseWorker(QThread):
|
|||||||
gy = int(new_y / 2.0)
|
gy = int(new_y / 2.0)
|
||||||
layer_grids.setdefault(grid_z,set()).add((gx, gy))
|
layer_grids.setdefault(grid_z,set()).add((gx, gy))
|
||||||
|
|
||||||
|
filt_z = round(new_z, 2) if is_extrusion else round(z, 2)
|
||||||
|
type_id = self.TYPE_ID_MAP.get(seg_type, 8)
|
||||||
|
curr_seg_idx = segment_count.get(seg_type, 0)
|
||||||
|
|
||||||
|
filters.extend([type_id, 1.0, curr_seg_idx, filt_z,
|
||||||
|
type_id, 1.0, curr_seg_idx, filt_z])
|
||||||
|
|
||||||
points.extend([x, y, z, new_x, new_y, new_z])
|
points.extend([x, y, z, new_x, new_y, new_z])
|
||||||
colors.extend([*c, *c])
|
colors.extend([*c, *c])
|
||||||
vertex_idx += 2
|
vertex_idx += 2
|
||||||
@@ -171,6 +182,8 @@ class GCodeParseWorker(QThread):
|
|||||||
add_segment(current_segment_type, segment_start, seg_len, z)
|
add_segment(current_segment_type, segment_start, seg_len, z)
|
||||||
segment_visibility[(segment_start, seg_len)] = True
|
segment_visibility[(segment_start, seg_len)] = True
|
||||||
|
|
||||||
|
filters_np = np.array(filters, dtype=np.float32).reshape(-1, 4) if vertex_idx > 0 else np.zeros((0, 4), dtype=np.float32)
|
||||||
|
|
||||||
# 判断哪些segment在内部
|
# 判断哪些segment在内部
|
||||||
for type_name, segments in type_segments.items():
|
for type_name, segments in type_segments.items():
|
||||||
if type_name in ('WALL-INNER', 'SUPPORT', 'FILL'):
|
if type_name in ('WALL-INNER', 'SUPPORT', 'FILL'):
|
||||||
@@ -193,6 +206,7 @@ class GCodeParseWorker(QThread):
|
|||||||
if (gx+ox, gy+oy) in gird:
|
if (gx+ox, gy+oy) in gird:
|
||||||
neighbors += 1
|
neighbors += 1
|
||||||
if neighbors >= 4:
|
if neighbors >= 4:
|
||||||
|
filters_np[start:start+length, 1] = 0.0
|
||||||
segment_visibility[(start, length)] = False
|
segment_visibility[(start, length)] = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
@@ -210,6 +224,7 @@ class GCodeParseWorker(QThread):
|
|||||||
result = {
|
result = {
|
||||||
'vertices': np.array(points, dtype=np.float32) if vertex_idx > 0 else np.zeros((0,), dtype=np.float32),
|
'vertices': np.array(points, dtype=np.float32) if vertex_idx > 0 else np.zeros((0,), dtype=np.float32),
|
||||||
'colors': np.array(colors, dtype=np.float32) if vertex_idx > 0 else np.zeros((0,), dtype=np.float32),
|
'colors': np.array(colors, dtype=np.float32) if vertex_idx > 0 else np.zeros((0,), dtype=np.float32),
|
||||||
|
'filters': filters_np,
|
||||||
'vertex_count': vertex_idx,
|
'vertex_count': vertex_idx,
|
||||||
'center_x': cx,
|
'center_x': cx,
|
||||||
'center_y': cy,
|
'center_y': cy,
|
||||||
@@ -260,14 +275,91 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
'TRAVEL': (0.25, 0.31, 0.38), # 0x405060
|
'TRAVEL': (0.25, 0.31, 0.38), # 0x405060
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPE_ID_MAP = {
|
||||||
|
'WALL-OUTER': 1,
|
||||||
|
'WALL-INNER': 2,
|
||||||
|
'SKIN': 3,
|
||||||
|
'FILL': 4,
|
||||||
|
'SUPPORT': 5,
|
||||||
|
'SUPPORT-INTERFACE': 6,
|
||||||
|
'SKIRT': 7,
|
||||||
|
'OTHER': 8,
|
||||||
|
'TRAVEL': 9,
|
||||||
|
}
|
||||||
|
|
||||||
# 顶点着色器(GLSL ES 1.00)
|
# 顶点着色器(GLSL ES 1.00)
|
||||||
VERTEX_SHADER = """
|
VERTEX_SHADER = """
|
||||||
attribute vec3 aPos;
|
attribute vec3 aPos;
|
||||||
attribute vec3 aColor;
|
attribute vec3 aColor;
|
||||||
|
attribute vec4 aFilter;
|
||||||
varying vec3 vColor;
|
varying vec3 vColor;
|
||||||
uniform mat4 uMVP;
|
uniform mat4 uMVP;
|
||||||
|
|
||||||
|
uniform float uZMin;
|
||||||
|
uniform float uZMax;
|
||||||
|
|
||||||
|
uniform float uVis1; // WALL-OUTER
|
||||||
|
uniform float uVis2; // WALL-INNER
|
||||||
|
uniform float uVis3; // SKIN
|
||||||
|
uniform float uVis4; // FILL
|
||||||
|
uniform float uVis5; // SUPPORT
|
||||||
|
uniform float uVis6; // SUPPORT-INTERFACE
|
||||||
|
uniform float uVis7; // SKIRT
|
||||||
|
uniform float uVis8; // OTHER
|
||||||
|
uniform float uVis9; // TRAVEL
|
||||||
|
|
||||||
|
uniform float uLodFactor;
|
||||||
|
uniform float uZoomMul;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = uMVP * vec4(aPos, 1.0);
|
float doDraw = 1.0;
|
||||||
|
float type_id = aFilter.x;
|
||||||
|
float is_vis = aFilter.y;
|
||||||
|
float seg_idx = aFilter.z;
|
||||||
|
float seg_z = aFilter.w;
|
||||||
|
|
||||||
|
if (is_vis < 0.5) doDraw = 0.0;
|
||||||
|
|
||||||
|
int t = int(type_id + 0.1);
|
||||||
|
|
||||||
|
if (t == 2 || t == 4 || t == 5) {
|
||||||
|
if (seg_z < uZMin || seg_z > uZMax) doDraw = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t == 1 && uVis1 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 2 && uVis2 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 3 && uVis3 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 4 && uVis4 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 5 && uVis5 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 6 && uVis6 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 7 && uVis7 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 8 && uVis8 < 0.5) doDraw = 0.0;
|
||||||
|
else if (t == 9 && uVis9 < 0.5) doDraw = 0.0;
|
||||||
|
|
||||||
|
if (uLodFactor > 0.0) {
|
||||||
|
float simplify_mul = 1.0;
|
||||||
|
if (t == 4) simplify_mul = 3.0;
|
||||||
|
else if (t == 5) simplify_mul = 4.0;
|
||||||
|
else if (t == 9) simplify_mul = 8.0;
|
||||||
|
|
||||||
|
float lod_step_f = max(1.0, floor(uLodFactor * simplify_mul * uZoomMul));
|
||||||
|
if (lod_step_f > 1.0) {
|
||||||
|
if (mod(seg_idx, lod_step_f) != 0.0) doDraw = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uZoomMul > 1.6 && (t == 4 || t == 5 || t == 2)) {
|
||||||
|
if (mod(floor(seg_idx / 2.0), 3.0) != 0.0) doDraw = 0.0;
|
||||||
|
}
|
||||||
|
if (uZoomMul > 2.8 && (t == 4 || t == 5 || t == 2)) {
|
||||||
|
if (mod(floor(seg_idx / 2.0), 6.0) != 0.0) doDraw = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doDraw < 0.5) {
|
||||||
|
gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
} else {
|
||||||
|
gl_Position = uMVP * vec4(aPos, 1.0);
|
||||||
|
}
|
||||||
vColor = aColor;
|
vColor = aColor;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@@ -295,9 +387,11 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
# 数据缓冲区
|
# 数据缓冲区
|
||||||
self.vertices = None
|
self.vertices = None
|
||||||
self.colors = None
|
self.colors = None
|
||||||
|
self.filters = None
|
||||||
self.vertex_count = 0
|
self.vertex_count = 0
|
||||||
self.vbo_vertices = None
|
self.vbo_vertices = None
|
||||||
self.vbo_colors = None
|
self.vbo_colors = None
|
||||||
|
self.vbo_filters = None
|
||||||
self.vbo_ready = False
|
self.vbo_ready = False
|
||||||
|
|
||||||
# 类型分段
|
# 类型分段
|
||||||
@@ -342,7 +436,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
self.uMVP_location = None
|
self.uMVP_location = None
|
||||||
|
|
||||||
# 简化参数
|
# 简化参数
|
||||||
self.enable_lod = True
|
self.enable_lod = False
|
||||||
self.lod_factor = 0.0
|
self.lod_factor = 0.0
|
||||||
self.visible_top_layers = 0
|
self.visible_top_layers = 0
|
||||||
self.visible_bottom_layers = 0
|
self.visible_bottom_layers = 0
|
||||||
@@ -353,7 +447,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
self._worker.terminate()
|
self._worker.terminate()
|
||||||
self._worker.wait()
|
self._worker.wait()
|
||||||
|
|
||||||
self._worker = GCodeParseWorker(filepath, self.TYPE_MAP, self.DEFAULT_COLORS)
|
self._worker = GCodeParseWorker(filepath, self.TYPE_MAP, self.DEFAULT_COLORS, self.TYPE_ID_MAP)
|
||||||
self._worker.finished.connect(self._on_parse_finished)
|
self._worker.finished.connect(self._on_parse_finished)
|
||||||
self._worker.start()
|
self._worker.start()
|
||||||
|
|
||||||
@@ -363,6 +457,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
|
|
||||||
self.vertices = result['vertices']
|
self.vertices = result['vertices']
|
||||||
self.colors = result['colors']
|
self.colors = result['colors']
|
||||||
|
self.filters = result['filters']
|
||||||
self.vertex_count = result['vertex_count']
|
self.vertex_count = result['vertex_count']
|
||||||
self.center_x = result['center_x']
|
self.center_x = result['center_x']
|
||||||
self.center_y = result['center_y']
|
self.center_y = result['center_y']
|
||||||
@@ -419,7 +514,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
self.view_rot_x = max(-90.0, min(0.0, rot_x))
|
self.view_rot_x = max(-90.0, min(0.0, rot_x))
|
||||||
self.view_rot_z = rot_z
|
self.view_rot_z = rot_z
|
||||||
if zoom is not None:
|
if zoom is not None:
|
||||||
self.view_zoom = zoom
|
self.view_zoom = max(-500.0, min(-10.0, zoom))
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
if length == 0:
|
if length == 0:
|
||||||
@@ -442,12 +537,14 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
# 获取属性和 uniform 位置
|
# 获取属性和 uniform 位置
|
||||||
self.aPos_location = self.shader_program.attributeLocation("aPos")
|
self.aPos_location = self.shader_program.attributeLocation("aPos")
|
||||||
self.aColor_location = self.shader_program.attributeLocation("aColor")
|
self.aColor_location = self.shader_program.attributeLocation("aColor")
|
||||||
|
self.aFilter_location = self.shader_program.attributeLocation("aFilter")
|
||||||
self.uMVP_location = self.shader_program.uniformLocation("uMVP")
|
self.uMVP_location = self.shader_program.uniformLocation("uMVP")
|
||||||
self.uDarken_location = self.shader_program.uniformLocation("uDarken")
|
self.uDarken_location = self.shader_program.uniformLocation("uDarken")
|
||||||
|
|
||||||
# 创建缓冲对象
|
# 创建缓冲对象
|
||||||
self.vbo_vertices = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
|
self.vbo_vertices = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
|
||||||
self.vbo_colors = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
|
self.vbo_colors = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
|
||||||
|
self.vbo_filters = QOpenGLBuffer(QOpenGLBuffer.Type.VertexBuffer)
|
||||||
|
|
||||||
def resizeGL(self, w, h):
|
def resizeGL(self, w, h):
|
||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
@@ -500,103 +597,65 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
# 允许 z-fighting 覆盖,用于同一位置多次渲染线条
|
# 允许 z-fighting 覆盖,用于同一位置多次渲染线条
|
||||||
gl.glDepthFunc(gl.GL_LEQUAL)
|
gl.glDepthFunc(gl.GL_LEQUAL)
|
||||||
|
|
||||||
|
count = self.progress_vertices
|
||||||
|
|
||||||
|
# Set uniforms for shader logic
|
||||||
|
visible_toggles = {i: 1.0 for i in range(1, 10)}
|
||||||
|
for name, viz in self.type_visibility.items():
|
||||||
|
type_id = self.TYPE_ID_MAP.get(name, 8)
|
||||||
|
visible_toggles[type_id] = 1.0 if viz else 0.0
|
||||||
|
|
||||||
|
for i in range(1, 10):
|
||||||
|
loc = self.shader_program.uniformLocation(f"uVis{i}")
|
||||||
|
if loc >= 0:
|
||||||
|
self.shader_program.setUniformValue(loc, visible_toggles[i])
|
||||||
|
|
||||||
|
zoom_mul = max(1.0, abs(self.view_zoom) / 250.0)
|
||||||
|
lod_loc = self.shader_program.uniformLocation("uLodFactor")
|
||||||
|
self.shader_program.setUniformValue(lod_loc, float(self.lod_factor) if getattr(self, 'enable_lod', True) else 0.0)
|
||||||
|
zm_loc = self.shader_program.uniformLocation("uZoomMul")
|
||||||
|
self.shader_program.setUniformValue(zm_loc, float(zoom_mul))
|
||||||
|
|
||||||
|
top_limit = self.max_z - self.visible_top_layers * self.layer_height if getattr(self, 'visible_top_layers', 0) > 0 else 9999.0
|
||||||
|
bottom_limit = self.min_z + self.visible_bottom_layers * self.layer_height if getattr(self, 'visible_bottom_layers', 0) > 0 else -9999.0
|
||||||
|
uzmin_loc = self.shader_program.uniformLocation("uZMin")
|
||||||
|
uzmax_loc = self.shader_program.uniformLocation("uZMax")
|
||||||
|
self.shader_program.setUniformValue(uzmin_loc, float(bottom_limit))
|
||||||
|
self.shader_program.setUniformValue(uzmax_loc, float(top_limit))
|
||||||
|
|
||||||
|
self.vbo_filters.bind()
|
||||||
|
self.shader_program.setAttributeBuffer(self.aFilter_location, gl.GL_FLOAT, 0, 4, 0)
|
||||||
|
self.shader_program.enableAttributeArray(self.aFilter_location)
|
||||||
|
|
||||||
# 渲染两次:一次绘制加粗加深的边界底线,一次绘制正常宽度的原色骨架线
|
# 渲染两次:一次绘制加粗加深的边界底线,一次绘制正常宽度的原色骨架线
|
||||||
# (在树莓派等性能有限的平台上,使用真实的3D圆柱/方块代替线条会导致顶点数暴增十几倍直接卡顿,
|
# (在树莓派等性能有限的平台上,使用真实的3D圆柱/方块代替线条会导致顶点数暴增十几倍直接卡顿,
|
||||||
# 因此通过动态加粗像素级线宽来性能无损地模拟出“体积感”)
|
# 因此通过动态加粗像素级线宽来性能无损地模拟出“体积感”)
|
||||||
for pass_idx in range(2):
|
for pass_idx in range(2):
|
||||||
if pass_idx == 0:
|
if pass_idx == 0:
|
||||||
if self.enable_lod:
|
if getattr(self, 'enable_lod', True):
|
||||||
gl.glLineWidth(3.0) # 底线宽度(加大以模拟体积轮廓)
|
gl.glLineWidth(3.0) # 底线宽度(加大以模拟体积轮廓)
|
||||||
else:
|
else:
|
||||||
gl.glLineWidth(6.0) # 底线宽度(加大以模拟体积轮廓)
|
gl.glLineWidth(6.0) # 底线宽度(加大以模拟体积轮廓)
|
||||||
self.shader_program.setUniformValue(self.uDarken_location, 0.8) # 加深颜色至 40% 亮度
|
self.shader_program.setUniformValue(self.uDarken_location, 0.8) # 加深颜色至 40% 亮度
|
||||||
else:
|
else:
|
||||||
if self.enable_lod:
|
if getattr(self, 'enable_lod', True):
|
||||||
gl.glLineWidth(1.5) # 主体宽度(加大以模拟线条厚度)
|
gl.glLineWidth(1.5) # 主体宽度(加大以模拟线条厚度)
|
||||||
else:
|
else:
|
||||||
gl.glLineWidth(3.0) # 主体宽度(加大以模拟线条厚度)
|
gl.glLineWidth(3.0) # 主体宽度(加大以模拟线条厚度)
|
||||||
self.shader_program.setUniformValue(self.uDarken_location, 1.0) # 保持原色
|
self.shader_program.setUniformValue(self.uDarken_location, 1.0) # 保持原色
|
||||||
|
|
||||||
# 按类型分段绘制
|
if count > 0:
|
||||||
# for type_name, segments in self.type_segments.items():
|
gl.glDrawArrays(gl.GL_LINES, 0, count)
|
||||||
# if not self.type_visibility.get(type_name, True):
|
|
||||||
# continue
|
|
||||||
# for start, length in segments:
|
|
||||||
# if start >= self.progress_vertices:
|
|
||||||
# continue
|
|
||||||
# end = start + length
|
|
||||||
# visible_start = start
|
|
||||||
# visible_count = length
|
|
||||||
# if end > self.progress_vertices:
|
|
||||||
# visible_count = self.progress_vertices - start
|
|
||||||
# if visible_count > 0:
|
|
||||||
# gl.glDrawArrays(gl.GL_LINES, visible_start, visible_count)
|
|
||||||
|
|
||||||
# 按类型分段绘制(带LOD)
|
|
||||||
for type_name, segments in self.type_segments.items():
|
|
||||||
if not self.type_visibility.get(type_name, True):
|
|
||||||
continue
|
|
||||||
# 不同类型的简化倍率
|
|
||||||
simplify_mul = 1
|
|
||||||
if type_name == 'FILL':
|
|
||||||
simplify_mul = 3
|
|
||||||
elif type_name == 'SUPPORT':
|
|
||||||
simplify_mul = 4
|
|
||||||
elif type_name == 'TRAVEL':
|
|
||||||
simplify_mul = 8
|
|
||||||
# 根据缩放动态增强简化
|
|
||||||
zoom_mul = max(1.0, abs(self.view_zoom) / 250.0)
|
|
||||||
# 最终步进
|
|
||||||
lod_step = 1
|
|
||||||
if self.enable_lod:
|
|
||||||
lod_step = int(max(1, self.lod_factor * simplify_mul * zoom_mul))
|
|
||||||
seg_index = 0
|
|
||||||
for start, length in segments:
|
|
||||||
if not self.segment_visibility.get((start, length), True):
|
|
||||||
continue
|
|
||||||
if type_name in ('WALL-INNER', 'SUPPORT', 'FILL'):
|
|
||||||
seg_z = self.segment_zs.get((start, length), self.center_z)
|
|
||||||
top_limit = self.max_z - self.visible_top_layers * self.layer_height if self.visible_top_layers > 0 else self.min_z - 1.0
|
|
||||||
bottom_limit = self.min_z + self.visible_bottom_layers * self.layer_height if self.visible_bottom_layers > 0 else self.max_z + 1.0
|
|
||||||
if bottom_limit <= seg_z <= top_limit:
|
|
||||||
continue
|
|
||||||
|
|
||||||
seg_index += 1
|
|
||||||
# LOD抽样
|
|
||||||
if lod_step > 1:
|
|
||||||
if (seg_index % lod_step) != 0:
|
|
||||||
continue
|
|
||||||
if start >= self.progress_vertices:
|
|
||||||
continue
|
|
||||||
|
|
||||||
end = start + length
|
|
||||||
visible_start = start
|
|
||||||
visible_count = length
|
|
||||||
if end > self.progress_vertices:
|
|
||||||
visible_count = self.progress_vertices - start
|
|
||||||
if visible_count <= 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 超远距离时进一步减少绘制长度
|
|
||||||
if self.enable_lod:
|
|
||||||
if type_name in ('FILL','SUPPORT','WALL-INNER'):
|
|
||||||
if abs(self.view_zoom) > 400:
|
|
||||||
if(start // 2) % 3 != 0:
|
|
||||||
continue
|
|
||||||
if abs(self.view_zoom) > 700:
|
|
||||||
if(start // 2) % 6 != 0:
|
|
||||||
continue
|
|
||||||
# visible_count = visible_count // 2
|
|
||||||
if visible_count > 0:
|
|
||||||
gl.glDrawArrays(gl.GL_LINES, visible_start, visible_count)
|
|
||||||
|
|
||||||
# 恢复默认深度测试模式
|
# 恢复默认深度测试模式
|
||||||
gl.glDepthFunc(gl.GL_LESS)
|
gl.glDepthFunc(gl.GL_LESS)
|
||||||
|
|
||||||
self.shader_program.disableAttributeArray(self.aPos_location)
|
self.shader_program.disableAttributeArray(self.aPos_location)
|
||||||
self.shader_program.disableAttributeArray(self.aColor_location)
|
self.shader_program.disableAttributeArray(self.aColor_location)
|
||||||
|
self.shader_program.disableAttributeArray(self.aFilter_location)
|
||||||
self.vbo_vertices.release()
|
self.vbo_vertices.release()
|
||||||
self.vbo_colors.release()
|
self.vbo_colors.release()
|
||||||
|
self.vbo_filters.release()
|
||||||
self.shader_program.release()
|
self.shader_program.release()
|
||||||
|
|
||||||
def _create_vbos(self):
|
def _create_vbos(self):
|
||||||
@@ -604,6 +663,8 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
self.vbo_vertices.destroy()
|
self.vbo_vertices.destroy()
|
||||||
if self.vbo_colors.isCreated():
|
if self.vbo_colors.isCreated():
|
||||||
self.vbo_colors.destroy()
|
self.vbo_colors.destroy()
|
||||||
|
if self.vbo_filters.isCreated():
|
||||||
|
self.vbo_filters.destroy()
|
||||||
|
|
||||||
self.vbo_vertices.create()
|
self.vbo_vertices.create()
|
||||||
self.vbo_vertices.bind()
|
self.vbo_vertices.bind()
|
||||||
@@ -615,6 +676,11 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
self.vbo_colors.allocate(self.colors.tobytes(), self.colors.nbytes)
|
self.vbo_colors.allocate(self.colors.tobytes(), self.colors.nbytes)
|
||||||
self.vbo_colors.release()
|
self.vbo_colors.release()
|
||||||
|
|
||||||
|
self.vbo_filters.create()
|
||||||
|
self.vbo_filters.bind()
|
||||||
|
self.vbo_filters.allocate(self.filters.tobytes(), self.filters.nbytes)
|
||||||
|
self.vbo_filters.release()
|
||||||
|
|
||||||
# ── 触摸/鼠标交互(完全不变) ──
|
# ── 触摸/鼠标交互(完全不变) ──
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
self.last_mouse_pos = event.position()
|
self.last_mouse_pos = event.position()
|
||||||
@@ -634,6 +700,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
def wheelEvent(self, event):
|
def wheelEvent(self, event):
|
||||||
delta = event.angleDelta().y() / 120
|
delta = event.angleDelta().y() / 120
|
||||||
self.view_zoom += delta * 10
|
self.view_zoom += delta * 10
|
||||||
|
self.view_zoom = max(-500.0, min(-10.0, self.view_zoom))
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def event(self, e):
|
def event(self, e):
|
||||||
@@ -696,6 +763,7 @@ class GCodeViewerWidget(QOpenGLWidget):
|
|||||||
if self._pinch_start_dist > 0:
|
if self._pinch_start_dist > 0:
|
||||||
scale = dist / self._pinch_start_dist
|
scale = dist / self._pinch_start_dist
|
||||||
self.view_zoom = self._pinch_start_zoom * (1 / scale)
|
self.view_zoom = self._pinch_start_zoom * (1 / scale)
|
||||||
|
self.view_zoom = max(-500.0, min(-10.0, self.view_zoom))
|
||||||
|
|
||||||
# 平移 (双指并行移动)
|
# 平移 (双指并行移动)
|
||||||
dcx = center_x - self._pinch_start_center[0]
|
dcx = center_x - self._pinch_start_center[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user