Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions gl/cutting_quad.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#version 120

uniform float zoom;

varying vec3 ec_pos;


void main() {
//Color of the cutting plane
vec3 cbase3 = vec3(1.0, 0.0, 0.0);
vec3 cbase2 = vec3(1.0, 0.0, 0.0);
vec3 cbase00 = vec3(0.5, 0.0, 0.0);

vec3 ec_normal = normalize(cross(dFdx(ec_pos), dFdy(ec_pos)));
ec_normal.z *= zoom;
ec_normal = normalize(ec_normal);

float a = dot(ec_normal, vec3(0.0, 0.0, 1.0));
float b = dot(ec_normal, vec3(-0.57, -0.57, 0.57));


gl_FragColor = vec4((a*cbase2 + (1-a)*cbase00)*0.5 +
(b*cbase3 + (1-b)*cbase00)*0.5, 1.0);
}
1 change: 1 addition & 0 deletions gl/gl.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<file>mesh_light.frag</file>
<file>quad.frag</file>
<file>quad.vert</file>
<file>cutting_quad.frag</file>
<file>colored_lines.frag</file>
<file>colored_lines.vert</file>
<file>sphere.stl</file>
Expand Down
3 changes: 2 additions & 1 deletion gl/mesh.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ uniform float zoom;

varying vec3 ec_pos;


void main() {
vec3 base3 = vec3(0.99, 0.96, 0.89);
vec3 base2 = vec3(0.92, 0.91, 0.83);
Expand All @@ -17,5 +18,5 @@ void main() {
float b = dot(ec_normal, vec3(-0.57, -0.57, 0.57));

gl_FragColor = vec4((a*base2 + (1-a)*base00)*0.5 +
(b*base3 + (1-b)*base00)*0.5, 1.0);
(b*base3 + (1-b)*base00)*0.5, 1.0);
}
14 changes: 11 additions & 3 deletions gl/mesh.vert
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
#version 120
#version 140
attribute vec3 vertex_position;

uniform mat4 transform_matrix;
uniform mat4 view_matrix;
uniform mat4 cutting_plane_matrix;

varying vec3 ec_pos;

void main() {
gl_Position = view_matrix*transform_matrix*
vec4(vertex_position, 1.0);
vec4 origpos = transform_matrix*vec4(vertex_position, 1.0);
gl_Position = view_matrix*origpos;
ec_pos = gl_Position.xyz;

vec4 vPos = view_matrix * transform_matrix* vec4(vertex_position, 1.0);

vec4 u_plane0 = transpose(inverse(cutting_plane_matrix))*vec4(0,0,1,0);
gl_ClipDistance[0] = dot(u_plane0, origpos); //If you want to clip using the camera coordinate system
//gl_ClipDistance[0] = dot(u_plane0, in_Vertex); //If you want to clip using the local coordinate system
//gl_ClipDistance[0] = dot(u_plane0, camMat * modelViewM * in_Vertex); //If you want it in global system
}
180 changes: 153 additions & 27 deletions src/canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,16 @@ void Canvas::set_drawMode(enum DrawMode mode)
update();
}

void Canvas::set_enableCut(bool d) {
enableCut = d;
update();
}

void Canvas::set_wheelMode(enum WheelMode mode) {
wheelMode = mode;
update();
}

void Canvas::clear_status()
{
status = "";
Expand All @@ -235,8 +245,16 @@ void Canvas::initializeGL()
{
initializeOpenGLFunctions();

cutting_quad_fragshader = new QOpenGLShader(QOpenGLShader::Fragment);
cutting_quad_fragshader->compileSourceFile(":/gl/cutting_quad.frag");

mesh_vertshader = new QOpenGLShader(QOpenGLShader::Vertex);
mesh_vertshader->compileSourceFile(":/gl/mesh.vert");

cutting_quad_shaderprog.addShader(mesh_vertshader);
cutting_quad_shaderprog.addShader(cutting_quad_fragshader);
cutting_quad_shaderprog.link();

mesh_shader.addShader(mesh_vertshader);
mesh_shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/mesh.frag");
mesh_shader.link();
Expand All @@ -249,7 +267,7 @@ void Canvas::initializeGL()
mesh_meshlight_shader.addShader(mesh_vertshader);
mesh_meshlight_shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl/mesh_light.frag");
mesh_meshlight_shader.link();

backdrop = new Backdrop();
axis = new Axis();
}
Expand Down Expand Up @@ -336,8 +354,88 @@ void Canvas::draw_mesh()
const GLuint vp = selected_mesh_shader->attributeLocation("vertex_position");
glEnableVertexAttribArray(vp);

// Then draw the mesh with that vertex position
mesh->draw(vp);
if (enableCut) {
glUniformMatrix4fv(
selected_mesh_shader->uniformLocation("cutting_plane_matrix"),
1, GL_FALSE, cutting_plane_matrix().data());
// Calculate clipping plane
glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_STENCIL_TEST);
glEnable(GL_CULL_FACE);
glClear(GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

glStencilFunc(GL_ALWAYS, 0, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_FRONT); // render back faces
mesh -> draw(vp);

glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_BACK); // render front faces
mesh -> draw(vp);

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDisable(GL_CLIP_DISTANCE0);
glStencilFunc(GL_NOTEQUAL, 0, ~0);

// Rendering the mesh
glDisable(GL_STENCIL_TEST);
glEnable(GL_CLIP_DISTANCE0);
glUniformMatrix4fv(
selected_mesh_shader->uniformLocation("transform_matrix"),
1, GL_FALSE, transform_matrix().data());

mesh->draw(vp);

// reload shader program to draw the colored clipping plane
selected_mesh_shader->release();
selected_mesh_shader = &cutting_quad_shaderprog;
selected_mesh_shader->bind();

glUniform1f(selected_mesh_shader->uniformLocation("zoom"), 1/zoom);
glUniformMatrix4fv(
selected_mesh_shader->uniformLocation("transform_matrix"),
1, GL_FALSE, cutting_plane_matrix().data());
glUniformMatrix4fv(
selected_mesh_shader->uniformLocation("view_matrix"),
1, GL_FALSE, view_matrix().data());

glEnable(GL_STENCIL_TEST);
glDisable(GL_CLIP_DISTANCE0);

// Define a BIG quad to render. It should be big to assure covering of clip area
unsigned int VBO;
float vertices[] = {
-1000.0f, 1000.0f, 0.0f,
-1000.0f, -1000.0f, 0.0f,
1000.0f, -1000.0f, 0.0f,
1000.0f, 1000.0f, 0.0f};

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);

// render quad
glDrawArrays(GL_QUADS, 0, 4);

// release buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &VBO);

glDisable(GL_STENCIL_TEST);
glEnable(GL_CLIP_DISTANCE0);
}
else
{
glDisable(GL_CLIP_DISTANCE0);

// Then draw the mesh with that vertex position
mesh->draw(vp);
}

// Reset draw mode for the background and anything else that needs to be drawn
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
Expand All @@ -346,11 +444,13 @@ void Canvas::draw_mesh()
glDisableVertexAttribArray(vp);
selected_mesh_shader->release();
}

QMatrix4x4 Canvas::orient_matrix() const
{
QMatrix4x4 m = currentTransform;
return m;
}

QMatrix4x4 Canvas::transform_matrix() const
{
QMatrix4x4 m = orient_matrix();
Expand Down Expand Up @@ -379,6 +479,20 @@ QMatrix4x4 Canvas::view_matrix() const
return m;
}

QMatrix4x4 Canvas::cutting_plane_matrix() const
{
QMatrix4x4 m = QMatrix4x4(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);

m.rotate(cp_tilt, QVector3D(1, 0, 0));
m.rotate(cp_yaw, QVector3D(0, 1, 0));
m.translate(0, 0, cp_shift);
return m;
}

void Canvas::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton ||
Expand Down Expand Up @@ -458,20 +572,27 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
auto d = p - mouse_pos;


if (event->buttons() & Qt::LeftButton)
if (event->modifiers() & Qt::ControlModifier)
{
if (event->buttons() & Qt::LeftButton)
{
cp_yaw = fmod(cp_yaw - d.x(), 360);
cp_tilt = fmod(cp_tilt - d.y(), 360);
update();
}
} else if (event->buttons() & Qt::LeftButton)
{
QPointF p1r = changeMouseCoordinates(mouse_pos);
QPointF p2r = changeMouseCoordinates(p);
calcArcballTransform(p1r,p2r);

update();
}
else if (event->buttons() & Qt::RightButton)
} else if (event->buttons() & Qt::RightButton)
{
center = transform_matrix().inverted() *
view_matrix().inverted() *
QVector3D(-d.x() / (0.5*width()),
d.y() / (0.5*height()), 0);
view_matrix().inverted() *
QVector3D(-d.x() / (0.5*width()),
d.y() / (0.5*height()), 0);
update();
}
mouse_pos = p;
Expand All @@ -487,27 +608,32 @@ void Canvas::wheelEvent(QWheelEvent *event)
QVector3D a = transform_matrix().inverted() *
view_matrix().inverted() * v;

if (event->angleDelta().y() < 0)
{
for (int i=0; i > event->angleDelta().y(); --i)
if (invertZoom)
zoom /= 1.001;
else
zoom *= 1.001;
}
else if (event->angleDelta().y() > 0)
if (event->modifiers() & Qt::ControlModifier || wheelMode == wheelcut)
cp_shift += (event->delta())/10000.0f;
else
{
for (int i=0; i < event->angleDelta().y(); ++i)
if (invertZoom)
zoom *= 1.001;
else
zoom /= 1.001;
if (event->angleDelta().y() < 0)
{
for (int i=0; i > event->angleDelta().y(); --i)
if (invertZoom)
zoom /= 1.001;
else
zoom *= 1.001;
}
else if (event->angleDelta().y() > 0)
{
for (int i=0; i < event->angleDelta().y(); ++i)
if (invertZoom)
zoom *= 1.001;
else
zoom /= 1.001;
}
// Then find the cursor's GL position post-zoom and adjust center.
QVector3D b = transform_matrix().inverted() *
view_matrix().inverted() * v;
center += b - a;
}

// Then find the cursor's GL position post-zoom and adjust center.
QVector3D b = transform_matrix().inverted() *
view_matrix().inverted() * v;
center += b - a;
update();
}

Expand Down
16 changes: 16 additions & 0 deletions src/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Axis;

enum ViewPoint {centerview, isoview, topview, bottomview, leftview, rightview, frontview, backview};
enum DrawMode {shaded, wireframe, surfaceangle, meshlight, DRAWMODECOUNT};
enum WheelMode {wheelzoom, wheelcut};

class Canvas : public QOpenGLWidget, protected QOpenGLFunctions
{
Expand All @@ -28,6 +29,8 @@ class Canvas : public QOpenGLWidget, protected QOpenGLFunctions
void draw_axes(bool d);
void invert_zoom(bool d);
void set_drawMode(enum DrawMode mode);
void set_enableCut(bool d);
void set_wheelMode(enum WheelMode mode);
void common_view_change(enum ViewPoint c);
void setResetTransformOnLoad(bool d);

Expand Down Expand Up @@ -73,10 +76,15 @@ public slots:
QMatrix4x4 transform_matrix() const;
QMatrix4x4 aspect_matrix() const;
QMatrix4x4 view_matrix() const;
QMatrix4x4 cutting_plane_matrix() const;

void resetTransform();
QPointF changeMouseCoordinates(QPoint p);
void calcArcballTransform(QPointF p1, QPointF p2);

QOpenGLShader* cutting_quad_fragshader;
QOpenGLShaderProgram cutting_quad_shaderprog;

QOpenGLShader* mesh_vertshader;
QOpenGLShaderProgram mesh_shader;
QOpenGLShaderProgram mesh_wireframe_shader;
Expand Down Expand Up @@ -112,9 +120,17 @@ public slots:
float zoom;
QMatrix4x4 currentTransform;


float cp_tilt;
float cp_yaw;
float cp_shift;

float perspective;
enum DrawMode drawMode;
enum WheelMode wheelMode;

bool drawAxes;
bool enableCut;
bool invertZoom;
bool resetTransformOnLoad;
Q_PROPERTY(float perspective MEMBER perspective WRITE set_perspective);
Expand Down
Loading