Im writing gcode sender. I want visualize path of machine work by lines (and separate G00 move lines by other color). To render element I used VBO and its works fine, but I dont know how to set individual colors for edges. I tried "mark" a vertex with G00 move in a separate list of rgb colors (as you can easy guess, its doesnt work propertly). All solutions found on the internet dont work with my code. Im really newbie in OpenGL and Im run out of ideas. Maybe someone can show me a solution that I dont see. For help I really thanks.
My code that extracts points from the buffer and establish edges:
def get_edges(self):
for x in range(0, len(self.points) - 2):
self.edges.append(x)
self.edges.append(x+1)
self.edges.append(x+1)
self.edges.append(x)
def get_points_from_buffer(self):
is_first_zminmax = True
is_first_fminmax = True
last_motion_mode = None
for command in self.buffer:
if command.find("G") != -1:
last_motion_mode = command[command.find("G"):command.find("G") + 3]
if command.find("F") != -1:
start = command.find("F") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
f = int(command[start])
else:
if stop == len(command) - 1:
f = int(command[start:stop+1])
else:
f = int(command[start:stop])
if is_first_fminmax is True:
is_first_fminmax = False
self.FMinMax[0] = f
self.FMinMax[1] = f
elif f < self.FMinMax[0]:
self.FMinMax[0] = f
elif f > self.FMinMax[1]:
self.FMinMax[1] = f
if command.find("X") != -1 or command.find("Y") != -1 or command.find("Z") != -1:
if last_motion_mode == "G00":
self.colors.append((0.25, 1.0, 0.0))
elif last_motion_mode != "G00":
self.colors.append((1.0, 1.0, 1.0))
if command.find("X") != -1:
start = command.find("X") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
x = float(command[start])
else:
if stop == len(command) - 1:
x = float(command[start:stop + 1])
else:
x = float(command[start:stop])
elif len(self.points) == 0:
x = 0
else:
x = self.points[len(self.points) - 1][0]
if command.find("Y") != -1:
start = command.find("Y") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
y = float(command[start])
else:
if stop == len(command) - 1:
y = float(command[start:stop + 1])
else:
y = float(command[start:stop])
elif len(self.points) == 0:
y = 0
else:
y = self.points[len(self.points) - 1][1]
if command.find("Z") != -1:
z = self.get_z(command)
if last_motion_mode != "G00" and is_first_zminmax is True:
is_first_zminmax = False
self.ZMinMax[0] = z
self.ZMinMax[1] = z
elif last_motion_mode != "G00":
if z < self.ZMinMax[0]:
self.ZMinMax[0] = z
elif z > self.ZMinMax[1]:
self.ZMinMax[1] = z
elif len(self.points) == 0:
z = 0
else:
z = self.points[len(self.points) - 1][2]
p = (x, y, z)
self.points.append(p)
self.is_motion_line.append(True)
else:
self.is_motion_line.append(False)
self.difZ = self.ZMinMax[1] - self.ZMinMax[0]
My OpenGL code:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.arrays import vbo
import numpy as np
from PyQt5 import QtOpenGL
class MyOpenGlWidget(QtOpenGL.QGLWidget):
def __init__(self, parent=None):
QtOpenGL.QGLWidget.__init__(self, parent)
def initGeometry(self, points=None, edges=None, colors=None):
if points is not None and edges is not None and colors is not None:
self.points = np.array(points)
self.vertVBO = vbo.VBO(np.reshape(self.points, (1, -1)).astype(np.float32))
self.vertVBO.bind()
# self.colors = np.array(colors)
# self.clrVBO = vbo.VBO(np.reshape(self.colors, (1, -1)).astype(np.float32))
# self.clrVBO.bind()
self.edges = np.array(edges)
else:
self.points = np.array([])
self.vertVBO = vbo.VBO(np.reshape(self.points, (1, -1)).astype(np.float32))
self.vertVBO.bind()
self.colors = np.array([])
self.clrVBO = vbo.VBO(np.reshape(self.colors, (1, -1)).astype(np.float32))
self.clrVBO.bind()
self.edges = np.array([])
def initializeGL(self):
glClearColor(0.0, 0.0, 0.0, 0.0)
glEnable(GL_DEPTH_TEST)
self.initGeometry()
self.rotX = 0.0
self.rotY = 0.0
self.rotZ = 0.0
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
aspect = w / float(h)
gluPerspective(45.0, aspect, 1.0, 100.0)
glMatrixMode(GL_MODELVIEW)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
def paintGL(self, coordinates=None):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glPushMatrix()
glTranslate(0.0, 0.0, -50.0)
glScale(0.1, 0.1, 0.1)
glRotate(self.rotX, 1.0, 0.0, 0.0)
glRotate(self.rotY, 0.0, 1.0, 0.0)
glRotate(self.rotZ, 0.0, 0.0, 1.0)
glTranslate(-0.5, -0.5, -0.5)
glEnableClientState(GL_VERTEX_ARRAY)
# glEnableClientState(GL_COLOR_ARRAY)
glVertexPointer(3, GL_FLOAT, 0, self.vertVBO)
# glColorPointer(3, GL_FLOAT, 0, self.clrVBO)
glDrawElements(GL_QUADS, len(self.edges), GL_UNSIGNED_INT, self.edges)
glDisableClientState(GL_VERTEX_ARRAY)
# glDisableClientState(GL_COLOR_ARRAY)
glPopMatrix()
What I already have:
What I want:
What I get after uncomment code from OpenGl file:
The last parameter of glVertexPointer
and glColorPointer
is not the buffer object, but an offset in to the buffer objects data store.
When you call glVertexPointer
or glColorPointer
, the buffer currently bound to the target GL_ARRAY_BUFFER
is associated to the fixed function attribute. You need to bind the proper buffer before calling glVertexPointer
or glColorPointer
:
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
self.vertVBO.bind()
glVertexPointer(3, GL_FLOAT, 0, None)
self.clrVBO.bind()
glColorPointer(3, GL_FLOAT, 0, None)