You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
6.4 KiB
232 lines
6.4 KiB
/**************************************************************************** |
|
* MeshLab o o * |
|
* A versatile mesh processing toolbox o o * |
|
* _ O _ * |
|
* Copyright(C) 2008 \/)\/ * |
|
* Visual Computing Lab /\/| * |
|
* ISTI - Italian National Research Council | * |
|
* \ * |
|
* All rights reserved. * |
|
* * |
|
* This program is free software; you can redistribute it and/or modify * |
|
* it under the terms of the GNU General Public License as published by * |
|
* the Free Software Foundation; either version 2 of the License, or * |
|
* (at your option) any later version. * |
|
* * |
|
* This program is distributed in the hope that it will be useful, * |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * |
|
* for more details. * |
|
* * |
|
****************************************************************************/ |
|
/**************************************************************************** |
|
History |
|
$Log: not supported by cvs2svn $ |
|
|
|
****************************************************************************/ |
|
|
|
#include <GL/glew.h> |
|
#include <wrap/gl/space.h> |
|
#include <wrap/gl/picking.h> |
|
#include <wrap/qt/device_to_logical.h> |
|
|
|
#include "rubberband.h" |
|
|
|
using namespace vcg; |
|
|
|
Rubberband::Rubberband(Color4b c) |
|
:color(c) |
|
{ |
|
this->Reset(); |
|
} |
|
|
|
void Rubberband::Render(QGLWidget* gla) |
|
{ |
|
if(have_to_pick){ |
|
assert(currentphase!=RUBBER_DRAGGED); |
|
Point3f pick_point; |
|
bool picked = Pick(QTLogicalToDevice(gla, qt_cursor.x()), QTLogicalToDevice(gla, gla->height() - qt_cursor.y()), pick_point); |
|
if(picked){ // we have not picked the background |
|
have_to_pick=false; |
|
switch(currentphase){ |
|
case RUBBER_BEGIN: |
|
start = pick_point; |
|
gla->setMouseTracking(true); |
|
currentphase = RUBBER_DRAGGING; |
|
break; |
|
case RUBBER_DRAGGING: |
|
if(pick_point==start){ |
|
have_to_pick=true; |
|
break; |
|
} |
|
end = pick_point; |
|
gla->setMouseTracking(false); |
|
currentphase = RUBBER_DRAGGED; |
|
break; |
|
default: |
|
assert(0); |
|
} |
|
} |
|
} |
|
|
|
if(currentphase==RUBBER_BEGIN) return; |
|
|
|
// Drawing of the current line |
|
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT); |
|
glDisable(GL_LIGHTING); |
|
glDisable(GL_TEXTURE_2D); |
|
glDepthMask(false); |
|
glLineWidth(2.5); |
|
glPointSize(5.0); |
|
|
|
if(currentphase==RUBBER_DRAGGING ) |
|
{ |
|
Point2f qt_start_point = DevicePixelConvert(start); |
|
glColor(color); |
|
glMatrixMode(GL_PROJECTION); |
|
glPushMatrix(); |
|
glLoadIdentity(); |
|
gluOrtho2D(0, QTLogicalToDevice(gla,gla->width()), QTLogicalToDevice(gla,gla->height()), 0); |
|
glMatrixMode(GL_MODELVIEW); |
|
glPushMatrix(); |
|
glLoadIdentity(); |
|
glDisable(GL_DEPTH_TEST); |
|
glBegin(GL_LINES); |
|
glVertex(qt_start_point); |
|
glVertex2f(QTLogicalToDevice(gla, qt_cursor.x()), QTLogicalToDevice(gla, qt_cursor.y())); |
|
glEnd(); |
|
glEnable(GL_DEPTH_TEST); |
|
glMatrixMode(GL_PROJECTION); |
|
glPopMatrix(); |
|
glMatrixMode(GL_MODELVIEW); |
|
glPopMatrix(); |
|
} |
|
else |
|
{ |
|
assert(currentphase == RUBBER_DRAGGED); |
|
glEnable(GL_BLEND); |
|
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); |
|
glEnable(GL_LINE_SMOOTH); |
|
glEnable(GL_POINT_SMOOTH); |
|
glColor(color); |
|
glLineWidth(2.0); |
|
glPointSize(4.0); |
|
glBegin(GL_LINES); |
|
glVertex(start); |
|
glVertex(end); |
|
glEnd(); |
|
glBegin(GL_POINTS); |
|
glVertex(start); |
|
glVertex(end); |
|
glEnd(); |
|
glDepthFunc(GL_GREATER); |
|
glLineWidth(1.0f); |
|
glPointSize(2.0f); |
|
glBegin(GL_LINES); |
|
glVertex(start); |
|
glVertex(end); |
|
glEnd(); |
|
glBegin(GL_POINTS); |
|
glVertex(start); |
|
glVertex(end); |
|
glEnd(); |
|
glDepthFunc(GL_LESS); |
|
} |
|
|
|
|
|
glPopAttrib(); |
|
assert(!glGetError()); |
|
} |
|
|
|
void Rubberband::RenderLine(QGLWidget* /*gla*/, Point3f AA, Point3f BB) |
|
{ |
|
// Drawing of the line from AA to BB |
|
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT); |
|
glDisable(GL_LIGHTING); |
|
glDisable(GL_TEXTURE_2D); |
|
glDepthMask(false); |
|
glEnable(GL_LINE_SMOOTH); |
|
glEnable(GL_POINT_SMOOTH); |
|
glColor(color); |
|
|
|
// IN FRONT OF SURFACE |
|
glDepthFunc(GL_LESS); |
|
glLineWidth(2.5); |
|
glPointSize(6.0); |
|
glBegin(GL_LINES); |
|
glVertex(AA); |
|
glVertex(BB); |
|
glEnd(); |
|
glBegin(GL_POINTS); |
|
glVertex(AA); |
|
glVertex(BB); |
|
glEnd(); |
|
|
|
// BEHIND SURFACE |
|
glDepthFunc(GL_GREATER); |
|
glEnable(GL_BLEND); |
|
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); |
|
glLineWidth(1.5f); |
|
glPointSize(4.0f); |
|
glBegin(GL_LINES); |
|
glVertex(AA); |
|
glVertex(BB); |
|
glEnd(); |
|
glBegin(GL_POINTS); |
|
glVertex(AA); |
|
glVertex(BB); |
|
glEnd(); |
|
|
|
glDepthFunc(GL_LESS); |
|
glPopAttrib(); |
|
assert(!glGetError()); |
|
} |
|
|
|
void Rubberband::Drag(QPoint p) |
|
{ |
|
if(currentphase==RUBBER_DRAGGING) |
|
qt_cursor=p; |
|
} |
|
|
|
void Rubberband::Pin(QPoint p) |
|
{ |
|
if(IsReady()) |
|
return; |
|
qt_cursor=p; |
|
have_to_pick=true; |
|
} |
|
|
|
void Rubberband::Reset() |
|
{ |
|
currentphase = RUBBER_BEGIN; |
|
qt_cursor = QPoint(); |
|
start = Point3f(0,0,0); |
|
end = Point3f(0,0,0); |
|
have_to_pick = false; |
|
} |
|
|
|
bool Rubberband::IsReady() |
|
{ |
|
return currentphase==RUBBER_DRAGGED; |
|
} |
|
|
|
void Rubberband::GetPoints(Point3f &s,Point3f &e) |
|
{ |
|
assert(IsReady()); |
|
s=start; |
|
e=end; |
|
} |
|
|
|
Point2f Rubberband::DevicePixelConvert(const Point3f p) |
|
{ |
|
GLint vm[4]; |
|
GLdouble mm[16]; |
|
GLdouble pm[16]; |
|
glGetIntegerv(GL_VIEWPORT, vm); |
|
glGetDoublev(GL_MODELVIEW_MATRIX, mm); |
|
glGetDoublev(GL_PROJECTION_MATRIX, pm); |
|
GLdouble wx,wy,wz; |
|
gluProject(p[0], p[1], p[2], mm, pm, vm, &wx, &wy, &wz); |
|
return Point2f(wx,vm[3]-wy); |
|
}
|
|
|