Skip to content

Commit

Permalink
First commit! Basic wireframe viewer works.
Browse files Browse the repository at this point in the history
  • Loading branch information
cibomahto committed May 14, 2011
0 parents commit ce0285a
Show file tree
Hide file tree
Showing 9 changed files with 566 additions and 0 deletions.
23 changes: 23 additions & 0 deletions GCodeViewer.pro
@@ -0,0 +1,23 @@
#-------------------------------------------------
#
# Project created by QtCreator 2011-05-11T22:05:25
#
#-------------------------------------------------

QT += core gui
QT += opengl

TARGET = GCodeViewer
TEMPLATE = app


SOURCES += main.cpp\
mainwindow.cpp \
gcode.cpp \
gcodeview.cpp

HEADERS += mainwindow.h \
gcode.h \
gcodeview.h

FORMS += mainwindow.ui
107 changes: 107 additions & 0 deletions gcode.cpp
@@ -0,0 +1,107 @@
#include "gcode.h"

char gcode::codes[] = "ABDEFGHIJKLMPQRSTXYZ";


gcode::gcode(string command) :
command(command) {

// cout << "parsing command: " << command << std::endl;

// Parse (and strip) any comments out into a comment string
parseComments();

// Parse any codes out into the code tables
parseCodes();
}


// Find any comments, store them, then remove them from the command
// TODO: Handle this correctly. For now, we just look for ( and bail.
void gcode::parseComments() {
if (command.find_first_of(")") != string::npos) {
comment = command.substr(command.find_first_of("(")+1);
command = command.substr(0,command.find_first_of("("));
// cout << " comment=" << comment << std::endl;
}

}


// Find any codes, and store them
void gcode::parseCodes() {
// For each code letter we know about, scan for it and record it's value.
int codeIndex = 0;

while (codes[codeIndex]!=0) {
// Search the command for an occurance of said code letter
if (command.find_first_of(codes[codeIndex]) != string::npos) {
double value = atof(command.substr(command.find_first_of(codes[codeIndex])+1).c_str());

// cout << " code=" << codes[codeIndex] << " value=" << value << std::endl;
parameters.push_back(gCodeParameter(codes[codeIndex],value));
}
codeIndex++;
}
}


string gcode::getCommand() {
// TODO: Note that this is the command minus any comments.
return string(command);
}


string gcode::getComment() {
return string(comment);
}


bool gcode::hasCode(char searchCode) {
for (int i = 0; i < parameters.size(); i++) {
if(parameters[i].code == searchCode) {
return true;
}
}

return false;
}


double gcode::getCodeValue(char searchCode) {
for (int i = 0; i < parameters.size(); i++) {
if(parameters[i].code == searchCode) {
return parameters[i].value;
}
}

return -1; // TODO: What do we return if there is no code?
}


gcodeModel::gcodeModel() {

}

void gcodeModel::loadGCode(string filename) {
points.clear();

ifstream file;

// TODO: error checking!
file.open(filename.c_str());

while (file.good()) {
string line;

std::getline(file, line);
gcode code = gcode(line);

// cout << " hascodeG:" << code.hasCode('G') << std::endl;

// If the code contains a line, let's add it to our list.
if (code.hasCode('G') && (int)code.getCodeValue('G') == 1) {
points.push_back(point(code.getCodeValue('X'), code.getCodeValue('Y'),code.getCodeValue('Z')));
}
}
}
76 changes: 76 additions & 0 deletions gcode.h
@@ -0,0 +1,76 @@
#ifndef GCODE_H
#define GCODE_H

#include <string>
#include <vector>
#include <fstream>

using std::string;
using std::vector;
using std::ifstream;

// Object that represents a single parsed line of GCode.
class gcode {
private:
class gCodeParameter {
public:
char code;
double value;

gCodeParameter(char code, double value) {
this->code = code;
this->value = value;
}
};

// These are the letter codes that we understand
static char codes[];

// The actual GCode command string
string command;

// Parsed out comment
string comment;

// The set of parameters in this GCode
vector<gCodeParameter> parameters;

// Find any comments, store them, then remove them from the command
void parseComments();

// Find any codes, and store them
void parseCodes();

public:
gcode(string command);

string getCommand();
string getComment();
bool hasCode(char searchCode);
double getCodeValue(char searchCode);
};

// TODO: Use whatever the equivalent class here should be.
struct point {
public:
float x;
float y;
float z;

point(float x, float y, float z) : x(x), y(y), z(z) {}
};

// Object that can open a file containing GCode and turn it into a series of lines
class gcodeModel {
public:
// For now, we have a long list of points to string together, that is public!
vector<point> points;

public:
gcodeModel();

void loadGCode(string filename);
};


#endif // GCODE_H
178 changes: 178 additions & 0 deletions gcodeview.cpp
@@ -0,0 +1,178 @@
#include "gcodeview.h"

#include <QtGui>
#include <QtOpenGL>

#include <math.h>

#import <iostream>
using namespace std;

static void qNormalizeAngle(int &angle)
{
while (angle < 0)
angle += 360 * 16;
while (angle > 360 * 16)
angle -= 360 * 16;
}

GcodeView::GcodeView(QWidget *parent)
: QGLWidget(parent)
{
resetView();

resizeGL(this->width(),this->height());
}

void GcodeView::resetView() {
xRot = 0;
yRot = 0;
zRot = 0;
scale = .1;
}

void GcodeView::setXRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != xRot) {
xRot = angle;
emit xRotationChanged(angle);
updateGL();
}
}

void GcodeView::setYRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != yRot) {
yRot = angle;
emit yRotationChanged(angle);
updateGL();
}
}

void GcodeView::setZRotation(int angle)
{
qNormalizeAngle(angle);
if (angle != zRot) {
zRot = angle;
emit xRotationChanged(angle);
updateGL();
}
}

void GcodeView::initializeGL()
{
// Set up the rendering context, define display lists etc.:
glClearColor(0.0, 0.0, 0.0, 0.0);
glDisable(GL_DEPTH_TEST);

glDisable(GL_LIGHTING);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void GcodeView::setupViewport(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef QT_OPENGL_ES
glOrthof(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0);
#else
glOrtho(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0);
#endif
glMatrixMode(GL_MODELVIEW);
}

void GcodeView::resizeGL(int width, int height)
{
setupViewport(width, height);
}

void GcodeView::paintGL()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

double widthRatio = (double)width()/(double)height();

// do something to the projection?
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-widthRatio, widthRatio, -1, 1, 10, 100);
glTranslatef(0.0f, 0.0f, -15.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, width(), height());


glPushMatrix();

glScalef(scale, scale, scale);

// glTranslatef(0.0, 0.0, -10.0);
glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);

glColor4f(1,1,1,.15);
glLineWidth(2);
glBegin(GL_LINE_STRIP);


for (unsigned int i = 1; i < model.points.size(); i++) {
point a = model.points[i-1];
point b = model.points[i];
glVertex3f(a.x, a.y, a.z); // origin of the line
glVertex3f(b.x, b.y, b.z); // ending point of the line
}

glEnd( );

glPopMatrix();
}

void GcodeView::loadModel(QString filename) {
model.loadGCode(filename.toStdString());
updateGL();
}

void GcodeView::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}

void GcodeView::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->x() - lastPos.x();
int dy = event->y() - lastPos.y();

if (event->buttons() & Qt::LeftButton) {
setXRotation(xRot + 1 * dy);
setYRotation(yRot + 1 * dx);
} else if (event->buttons() & Qt::RightButton) {
setXRotation(xRot - 1 * dy);
setYRotation(yRot - 1 * dx);
}
lastPos = event->pos();
}

void GcodeView::wheelEvent(QWheelEvent *event)
{
float newScale = scale*(1 + event->delta()/100.0);

// if (newScale > 0.01 && newScale < 2) {
scale = newScale;
// }

updateGL();
}

void GcodeView::mouseDoubleClickEvent(QMouseEvent event) {
resetView();
updateGL();
}

0 comments on commit ce0285a

Please sign in to comment.