first version, adapted from meshlab's editmeasure plugin
This commit is contained in:
parent
45b9624e73
commit
f93857dbb0
|
@ -0,0 +1,591 @@
|
|||
/****************************************************************************
|
||||
* 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/math.h>
|
||||
#include <wrap/gl/space.h>
|
||||
#include <wrap/gl/addons.h>
|
||||
|
||||
#include "coordinateframe.h"
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
|
||||
|
||||
CoordinateFrame::CoordinateFrame(float s)
|
||||
://QObject(),
|
||||
basecolor(Color4b::White),xcolor(Color4b::Red)
|
||||
,ycolor(Color4b::Green),zcolor(Color4b::Blue),size(s),linewidth(2.0)
|
||||
,font(),drawaxis(true),drawlabels(true),drawvalues(false)
|
||||
{
|
||||
font.setFamily("Helvetica");
|
||||
}
|
||||
|
||||
void CoordinateFrame::Render(QGLWidget* glw)
|
||||
{
|
||||
assert( glw!= NULL);
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glLineWidth(linewidth);
|
||||
glPointSize(linewidth*1.5);
|
||||
|
||||
Point3d o(0,0,0);
|
||||
Point3d a(size,0,0);
|
||||
Point3d b(0,size,0);
|
||||
Point3d c(0,0,size);
|
||||
// Get gl state values
|
||||
double mm[16],mp[16];
|
||||
GLint vp[4];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX,mm);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX,mp);
|
||||
glGetIntegerv(GL_VIEWPORT,vp);
|
||||
float slope_a=calcSlope(-a,a,2*size,10,mm,mp,vp);
|
||||
float slope_b=calcSlope(-b,b,2*size,10,mm,mp,vp);
|
||||
float slope_c=calcSlope(-c,c,2*size,10,mm,mp,vp);
|
||||
float scalefactor = size*0.02f;
|
||||
if(drawaxis){
|
||||
glBegin(GL_LINES);
|
||||
glColor(xcolor);
|
||||
glVertex(-a); glVertex(a);
|
||||
glColor(ycolor);
|
||||
glVertex(-b); glVertex(b);
|
||||
glColor(zcolor);
|
||||
glVertex(-c); glVertex(c);
|
||||
glEnd();
|
||||
glColor(basecolor);
|
||||
// assi positivi
|
||||
drawTickedLine(o,a,size,slope_a,linewidth); // Draws x axis
|
||||
drawTickedLine(o,b,size,slope_b,linewidth); // Draws y axis
|
||||
drawTickedLine(o,c,size,slope_c,linewidth); // Draws z axis
|
||||
//assi negativi
|
||||
drawTickedLine(o,-a,size,slope_a,linewidth); // Draws x axis
|
||||
drawTickedLine(o,-b,size,slope_b,linewidth); // Draws y axis
|
||||
drawTickedLine(o,-c,size,slope_c,linewidth); // Draws z axis
|
||||
glPushMatrix();
|
||||
glTranslate(a);
|
||||
glScalef(scalefactor,scalefactor,scalefactor);
|
||||
Add_Ons::Cone(10,linewidth*1.5,linewidth*0.5,true);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslate(b);
|
||||
glRotatef(90,0,0,1);
|
||||
glScalef(scalefactor,scalefactor,scalefactor);
|
||||
Add_Ons::Cone(10,linewidth*1.5,linewidth*0.5,true);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslate(c);
|
||||
glRotatef(-90,0,1,0);
|
||||
glScalef(scalefactor,scalefactor,scalefactor);
|
||||
Add_Ons::Cone(10,linewidth*1.5,linewidth*0.5,true);
|
||||
glPopMatrix();
|
||||
}
|
||||
if(drawlabels){
|
||||
font.setBold(true);
|
||||
font.setPixelSize(10);
|
||||
glColor(xcolor);
|
||||
glw->renderText(size+(scalefactor*3),0,0,QString("X"),font);
|
||||
glColor(ycolor);
|
||||
glw->renderText(0,size+(scalefactor*3),0,QString("Y"),font);
|
||||
glColor(zcolor);
|
||||
glw->renderText(0,0,size+(scalefactor*3),QString("Z"),font);
|
||||
}
|
||||
if(drawvalues){
|
||||
font.setBold(false);
|
||||
font.setPixelSize(8);
|
||||
float i;
|
||||
glColor(Color4b::LightGray);
|
||||
for(i=slope_a;i<size;i+=slope_a){
|
||||
glw->renderText( i,0,0,QString(" %1").arg(i,3,'f',1),font);
|
||||
glw->renderText(-i,0,0,QString("-%1").arg(i,3,'f',1),font);
|
||||
}
|
||||
for(i=slope_b;i<size;i+=slope_b){
|
||||
glw->renderText(0, i,0,QString(" %1").arg(i,3,'f',1),font);
|
||||
glw->renderText(0,-i,0,QString("-%1").arg(i,3,'f',1),font);
|
||||
}
|
||||
for(i=slope_c;i<size;i+=slope_c){
|
||||
glw->renderText(0,0, i,QString(" %1").arg(i,3,'f',1),font);
|
||||
glw->renderText(0,0,-i,QString("-%1").arg(i,3,'f',1),font);
|
||||
}
|
||||
}
|
||||
|
||||
glPopAttrib();
|
||||
assert(!glGetError());
|
||||
}
|
||||
|
||||
void CoordinateFrame::drawTickedLine(const Point3d &a,const Point3d &b, float dim,float tickDist,float linewidth)
|
||||
{
|
||||
Point3d v(b-a);
|
||||
v = v /dim; // normalize without computing square roots and powers
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
float i;
|
||||
for(i=tickDist;i<dim;i+=tickDist)
|
||||
glVertex3f(a[0] + i*v[0],a[1] + i*v[1],a[2] + i*v[2]);
|
||||
glEnd();
|
||||
|
||||
glPushAttrib(GL_POINT_BIT);
|
||||
glPointSize(linewidth*3);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(a[0] + dim*v[0],a[1] + dim*v[1],a[2] + dim*v[2]);
|
||||
glEnd();
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
float CoordinateFrame::calcSlope(const Point3d &a,const Point3d &b,float dim,int spacing,double *mm,double *mp,GLint *vp)
|
||||
{
|
||||
Point3d p1,p2;
|
||||
|
||||
gluProject(a[0],a[1],a[2],mm,mp,vp,&p1[0],&p1[1],&p1[2]);
|
||||
gluProject(b[0],b[1],b[2],mm,mp,vp,&p2[0],&p2[1],&p2[2]);
|
||||
p1[2]=p2[2]=0;
|
||||
|
||||
float tickNum = spacing/Distance(p2,p1);// pxl spacing
|
||||
float slope = dim*tickNum;
|
||||
float nslope = math::Min(
|
||||
math::Min(niceRound(slope), 0.5f*niceRound(2.0f*slope)),
|
||||
0.2f*niceRound(5.0f*slope));
|
||||
nslope = math::Max<float>(niceRound(dim*.001f),nslope); // prevent too small slope
|
||||
return nslope;
|
||||
}
|
||||
|
||||
float CoordinateFrame::niceRound(float val)
|
||||
{
|
||||
return powf(10.f,ceil(log10(val)));
|
||||
}
|
||||
|
||||
MovableCoordinateFrame::MovableCoordinateFrame(float size)
|
||||
:CoordinateFrame(size),position(0,0,0),rotation(0,Point3f(1,0,0))
|
||||
{
|
||||
// nothing here
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::Render(QGLWidget* gla)
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
glTranslate(position);
|
||||
Matrix44f mrot;
|
||||
rotation.ToMatrix(mrot);
|
||||
glMultMatrix(mrot);
|
||||
|
||||
CoordinateFrame::Render(gla);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::GetTransform(Matrix44f & transform)
|
||||
{
|
||||
// costruisco la matrice che porta le coordinate in spazio di mondo
|
||||
|
||||
// resetto la trasf
|
||||
transform.SetIdentity();
|
||||
|
||||
// ruoto
|
||||
Matrix44f rot;
|
||||
rotation.ToMatrix(rot);
|
||||
|
||||
transform = rot * transform ;
|
||||
|
||||
// sposto in posizione
|
||||
Matrix44f pos;
|
||||
pos.SetTranslate(position);
|
||||
|
||||
transform = pos * transform;
|
||||
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::Reset(bool reset_position,bool reset_alignment)
|
||||
{
|
||||
if(reset_position)
|
||||
position = Point3f(0,0,0);
|
||||
if(reset_alignment)
|
||||
rotation = Quaternionf(0,Point3f(1,0,0));
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::SetPosition(const Point3f newpos)
|
||||
{
|
||||
position = newpos;
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::SetRotation(const Quaternionf newrot)
|
||||
{
|
||||
rotation = newrot;
|
||||
}
|
||||
|
||||
Point3f MovableCoordinateFrame::GetPosition()
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
Quaternionf MovableCoordinateFrame::GetRotation()
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::Flip(const Point3f axis)
|
||||
{
|
||||
Similarityf s;
|
||||
s.SetRotate(M_PI,Inverse(rotation).Rotate(axis));
|
||||
Move(s);
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::AlignWith(const Point3f pri,const Point3f secondary)
|
||||
{
|
||||
const float EPSILON=1e-6;
|
||||
Point3f primary=pri;
|
||||
|
||||
if( primary.Norm() < EPSILON*size )
|
||||
return;
|
||||
|
||||
primary.Normalize(); // ho l'asse primario, lo normalizzo
|
||||
Plane3f plane(0,primary); // piano di proiezione per la seconda rotazione
|
||||
Point3f old_z = Inverse(rotation).Rotate(Point3f(0,0,1)); // l'asse z
|
||||
Point3f old_y_pro = plane.Projection(Inverse(rotation).Rotate(Point3f(0,1,0))); //la proiezione dell'asse y
|
||||
Point3f old_x_pro = plane.Projection(Inverse(rotation).Rotate(Point3f(1,0,0))); //la proiezione dell'asse x
|
||||
|
||||
// allinea l'asse z corrente all'asse primary
|
||||
RotateToAlign(old_z,primary); // prima rotazione
|
||||
|
||||
Point3f secondary_pro = plane.Projection(secondary); // la proiezione di secondary
|
||||
Point3f new_y_pro = plane.Projection(Inverse(rotation).Rotate(Point3f(0,1,0))); // la proiezione dell'asse y dopo la prima rotazione
|
||||
|
||||
// se c'e` un asse secondary e la sua proiezione non e` 0
|
||||
if( secondary.Norm() > EPSILON*size && secondary_pro.Norm() > EPSILON ){
|
||||
// allinea la proiezione dell'asse y dopo la prima rotazione alla proiezione dell'asse secondary
|
||||
secondary_pro.Normalize();
|
||||
RotateToAlign(new_y_pro,secondary_pro);
|
||||
return;
|
||||
}
|
||||
// creco di riallineare la y
|
||||
if ( old_y_pro.Norm() > EPSILON ) {
|
||||
// allinea la proiezione dell'asse y dopo la prima rotazione alla proiezione dell'asse y
|
||||
old_y_pro.Normalize();
|
||||
RotateToAlign(new_y_pro,old_y_pro);
|
||||
return;
|
||||
}
|
||||
// cerco di riallineare la x
|
||||
Point3f new_x_pro = plane.Projection(Inverse(rotation).Rotate(Point3f(1,0,0))); //la proiezione dell'asse x dopo la prima rotazione
|
||||
assert(old_x_pro.Norm() > EPSILON ); // la proiezione dell'asse x non dovrebbe essere 0
|
||||
// allinea la proiezione dell'asse x dopo la prima rotazione alla proiezione dell'asse x
|
||||
old_x_pro.Normalize();
|
||||
RotateToAlign(new_x_pro,old_x_pro);
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::Move(const Similarityf track)
|
||||
{
|
||||
position = position + track.tra;
|
||||
rotation = rotation * track.rot;
|
||||
}
|
||||
|
||||
void MovableCoordinateFrame::RotateToAlign(const Point3f source, const Point3f dest)
|
||||
{
|
||||
const float EPSILON=1e-6;
|
||||
// source e dest devono essere versori
|
||||
assert( math::Abs(source.Norm() - 1) < EPSILON);
|
||||
assert( math::Abs(dest.Norm() - 1) < EPSILON);
|
||||
|
||||
Point3f axis = dest ^ source;
|
||||
float sinangle = axis.Norm();
|
||||
float cosangle = dest * source;
|
||||
float angle = math::Atan2(sinangle,cosangle);
|
||||
|
||||
if( math::Abs(angle) < EPSILON )
|
||||
return; // angolo ~ 0, annullo
|
||||
|
||||
if( math::Abs(math::Abs(angle)-M_PI) < EPSILON){
|
||||
// devo trovare un asse su cui flippare
|
||||
Plane3f plane(0,source);
|
||||
axis=plane.Projection(Point3f(1,0,0)); // proietto un punto a caso sul piano normale a source
|
||||
if(axis.Norm() < EPSILON){ // source era ~ [1,0,0]...
|
||||
axis=plane.Projection(Point3f(0,1,0));
|
||||
assert(axis.Norm() > EPSILON); // quest'altro punto deve andare bene
|
||||
}
|
||||
}
|
||||
rotation = rotation * Quaternionf(angle,axis);
|
||||
}
|
||||
|
||||
ActiveCoordinateFrame::ActiveCoordinateFrame(float size)
|
||||
:MovableCoordinateFrame(size),manipulator(NULL),drawmoves(true),
|
||||
drawrotations(true),
|
||||
movx(Trackball::BUTTON_RIGHT ),
|
||||
movy(Trackball::BUTTON_RIGHT | Trackball::KEY_CTRL),
|
||||
movz(Trackball::BUTTON_RIGHT | Trackball::KEY_SHIFT),
|
||||
rotx(Trackball::BUTTON_LEFT),
|
||||
roty(Trackball::BUTTON_LEFT | Trackball::KEY_CTRL),
|
||||
rotz(Trackball::BUTTON_LEFT | Trackball::KEY_SHIFT),
|
||||
x_axis(1,0,0),y_axis(0,1,0),z_axis(0,0,1),rot_snap_rad(0.0f),mov_snap(0.0f)
|
||||
{
|
||||
manipulator=new Trackball();
|
||||
std::map<int, TrackMode *>::iterator it;
|
||||
for(it = manipulator->modes.begin(); it != manipulator->modes.end(); it++)
|
||||
{
|
||||
if ((*it).second)
|
||||
delete (*it).second;
|
||||
}
|
||||
manipulator->modes.clear();
|
||||
manipulator->modes[0] = NULL;
|
||||
Update();
|
||||
}
|
||||
|
||||
ActiveCoordinateFrame::~ActiveCoordinateFrame()
|
||||
{
|
||||
if(manipulator!=NULL) {
|
||||
delete manipulator;
|
||||
manipulator=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::Render(QGLWidget* glw)
|
||||
{
|
||||
glPushMatrix(); //occhio
|
||||
|
||||
manipulator->radius=size;
|
||||
manipulator->center=position;
|
||||
manipulator->GetView();
|
||||
manipulator->Apply(false);
|
||||
|
||||
MovableCoordinateFrame::Render(glw);
|
||||
|
||||
// non devo disegnare
|
||||
if(!drawmoves && !drawrotations){
|
||||
glPopMatrix(); //occhio
|
||||
return;
|
||||
}
|
||||
|
||||
int current_mode=manipulator->current_button;
|
||||
bool rotating=(current_mode==rotx)||(current_mode==roty)||(current_mode==rotz);
|
||||
bool moving=(current_mode==movx)||(current_mode==movy)||(current_mode==movz);
|
||||
|
||||
// non sto draggando o sto draggando quello che non devo disengnare
|
||||
if( (!rotating && !moving)||
|
||||
(!((rotating && drawrotations)||(moving && drawmoves)))
|
||||
){
|
||||
glPopMatrix(); //occhio
|
||||
return;
|
||||
}
|
||||
|
||||
// sto draggando e devo disegnare qualcosa
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
Color4b color;
|
||||
QString message;
|
||||
char axis_name;
|
||||
float verse;
|
||||
if(rotating && drawrotations){ // devo disegnare una rotazione
|
||||
Point3f axis, arc_point;
|
||||
float angle;
|
||||
manipulator->track.rot.ToAxis(angle,axis);
|
||||
if(current_mode==rotx){
|
||||
verse=((axis+x_axis).Norm()<1?-1:1);
|
||||
color=xcolor; axis_name='x'; arc_point=y_axis*(size*0.8);
|
||||
} else if(current_mode==roty) {
|
||||
verse=((axis+y_axis).Norm()<1?-1:1);
|
||||
color=ycolor; axis_name='y'; arc_point=z_axis*(size*0.8);
|
||||
} else if(current_mode==rotz) {
|
||||
verse=((axis+z_axis).Norm()<1?-1:1);
|
||||
color=zcolor; axis_name='z'; arc_point=x_axis*(size*0.8);
|
||||
} else assert(0); // doveva essere una rotazione
|
||||
// normalizzo la rotazione a [-180,180]
|
||||
float sign = ((angle*verse)<0) ? -1 : 1;
|
||||
float abs_angle = (angle<0) ? -angle : angle;
|
||||
angle = sign * ( (abs_angle>M_PI) ? 2*M_PI-abs_angle : abs_angle );
|
||||
axis = axis * verse;
|
||||
message = QString("rotated %1 deg around %2")
|
||||
.arg(((angle*180.0)/M_PI),5,'f',3)
|
||||
.arg(axis_name);
|
||||
Quaternionf arc_rot;
|
||||
arc_rot.FromAxis(angle/18.0,axis);
|
||||
glColor(color);
|
||||
glBegin(GL_POLYGON);
|
||||
glVertex(position);
|
||||
glVertex(position+arc_point);
|
||||
for(int i=0;i<18;i++){
|
||||
arc_point = arc_rot.Rotate(arc_point);
|
||||
glVertex(position+arc_point);
|
||||
}
|
||||
glEnd();
|
||||
} else if(moving && drawmoves){// devo disegnare una traslazione
|
||||
Point3f ntra=manipulator->track.tra;
|
||||
ntra.Normalize();
|
||||
if(current_mode==movx){
|
||||
verse=((ntra+x_axis).Norm()<1?-1:1);
|
||||
color=xcolor; axis_name='x';
|
||||
}else if(current_mode==movy){
|
||||
verse=((ntra+y_axis).Norm()<1?-1:1);
|
||||
color=ycolor; axis_name='y';
|
||||
}else if(current_mode==movz){
|
||||
verse=((ntra+z_axis).Norm()<1?-1:1);
|
||||
color=zcolor; axis_name='z';
|
||||
}else assert(0); // doveva essere una traslazione
|
||||
message = QString("moved %1 units along %2")
|
||||
.arg(verse*manipulator->track.tra.Norm(),5,'f',3)
|
||||
.arg(axis_name);
|
||||
Point3f old_pos = position-manipulator->track.tra;
|
||||
glLineWidth(2*linewidth);
|
||||
glPointSize(4*linewidth);
|
||||
glColor(color);
|
||||
glBegin(GL_LINES);
|
||||
glVertex(position);
|
||||
glVertex(old_pos);
|
||||
glEnd();
|
||||
glBegin(GL_POINTS);
|
||||
glVertex(old_pos);
|
||||
glEnd();
|
||||
} else assert(0); // qualcosa lo dovevo disegnare
|
||||
// disegno la stringa
|
||||
font.setBold(true);
|
||||
font.setPixelSize(12);
|
||||
glw->renderText(cursor.x()+16,cursor.y()+16,message,font);
|
||||
|
||||
glPopAttrib();
|
||||
glPopMatrix(); //occhio
|
||||
}
|
||||
|
||||
|
||||
void ActiveCoordinateFrame::Reset(bool reset_position,bool reset_alignment)
|
||||
{
|
||||
MovableCoordinateFrame::Reset(reset_position, reset_alignment);
|
||||
Update();
|
||||
manipulator->Reset();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::SetPosition(const Point3f newpos)
|
||||
{
|
||||
MovableCoordinateFrame::SetPosition(newpos);
|
||||
Update();
|
||||
manipulator->Reset();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::SetRotation(const Quaternionf newrot)
|
||||
{
|
||||
MovableCoordinateFrame::SetRotation(newrot);
|
||||
Update();
|
||||
manipulator->Reset();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::AlignWith(const Point3f primary,const Point3f secondary=Point3f(0,0,0))
|
||||
{
|
||||
MovableCoordinateFrame::AlignWith(primary,secondary);
|
||||
Update();
|
||||
manipulator->Reset();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::MouseDown(QPoint c,int x, int y, /*Button*/ int button)
|
||||
{
|
||||
cursor=c;
|
||||
Move(manipulator->track);
|
||||
manipulator->Reset();
|
||||
manipulator->MouseDown(x,y,button);
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::MouseMove(QPoint c,int x, int y)
|
||||
{
|
||||
cursor=c;
|
||||
manipulator->MouseMove(x,y);
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::MouseUp(int x, int y, /*Button */ int button)
|
||||
{
|
||||
Move(manipulator->track);
|
||||
manipulator->Reset();
|
||||
manipulator->MouseUp(x, y, button);
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::ButtonUp(int button)
|
||||
{
|
||||
Move(manipulator->track);
|
||||
manipulator->Reset();
|
||||
manipulator->ButtonUp((Trackball::Button) button);
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::ButtonDown(int button)
|
||||
{
|
||||
Move(manipulator->track);
|
||||
manipulator->Reset();
|
||||
manipulator->ButtonDown((Trackball::Button) button);
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::SetSnap(float rot_deg)
|
||||
{
|
||||
assert((rot_deg>=0.0)&&(rot_deg<=180));
|
||||
rot_snap_rad=rot_deg*M_PI/180.0;
|
||||
Update();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::Move(const Similarityf track)
|
||||
{
|
||||
MovableCoordinateFrame::Move(track);
|
||||
Update();
|
||||
}
|
||||
|
||||
void ActiveCoordinateFrame::Update()
|
||||
{
|
||||
Point3f p=position;
|
||||
Quaternionf r=Inverse(rotation);
|
||||
x_axis=r.Rotate(Point3f(1,0,0));
|
||||
y_axis=r.Rotate(Point3f(0,1,0));
|
||||
z_axis=r.Rotate(Point3f(0,0,1));
|
||||
|
||||
if(manipulator->modes[movx]!=NULL)
|
||||
delete manipulator->modes[movx];
|
||||
manipulator->modes[movx] = new AxisMode(p,x_axis);
|
||||
|
||||
if(manipulator->modes[movy]!=NULL)
|
||||
delete manipulator->modes[movy];
|
||||
manipulator->modes[movy] = new AxisMode(p,y_axis);
|
||||
|
||||
if(manipulator->modes[movz]!=NULL)
|
||||
delete manipulator->modes[movz];
|
||||
manipulator->modes[movz] = new AxisMode(p,z_axis);
|
||||
|
||||
if(manipulator->modes[rotx]!=NULL)
|
||||
delete manipulator->modes[rotx];
|
||||
manipulator->modes[rotx] = new CylinderMode(p,x_axis,rot_snap_rad);
|
||||
|
||||
if(manipulator->modes[roty]!=NULL)
|
||||
delete manipulator->modes[roty];
|
||||
manipulator->modes[roty] = new CylinderMode(p,y_axis,rot_snap_rad);
|
||||
|
||||
if(manipulator->modes[rotz]!=NULL)
|
||||
delete manipulator->modes[rotz];
|
||||
manipulator->modes[rotz] = new CylinderMode(p,z_axis,rot_snap_rad);
|
||||
|
||||
manipulator->SetCurrentAction();
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/****************************************************************************
|
||||
* 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 $
|
||||
|
||||
****************************************************************************/
|
||||
#ifndef COORDINATEFRAME_H
|
||||
#define COORDINATEFRAME_H
|
||||
|
||||
|
||||
#include <vcg/math/similarity.h>
|
||||
#include <vcg/space/color4.h>
|
||||
|
||||
#include <wrap/gui/trackball.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QGLWidget>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class CoordinateFrame//: public QObject
|
||||
{
|
||||
// Q_OBJECT
|
||||
|
||||
public:
|
||||
// functions:
|
||||
CoordinateFrame(float);
|
||||
virtual ~CoordinateFrame() {}
|
||||
virtual void Render(QGLWidget*);
|
||||
// data
|
||||
Color4b basecolor;
|
||||
Color4b xcolor;
|
||||
Color4b ycolor;
|
||||
Color4b zcolor;
|
||||
float size;
|
||||
float linewidth;
|
||||
QFont font;
|
||||
bool drawaxis;
|
||||
bool drawlabels;
|
||||
bool drawvalues;
|
||||
|
||||
protected:
|
||||
// functions:
|
||||
void drawTickedLine(const Point3d &, const Point3d &, float, float,float);
|
||||
float calcSlope(const Point3d &, const Point3d &, float, int , double *, double *, GLint *);
|
||||
float niceRound(float);
|
||||
};
|
||||
|
||||
class MovableCoordinateFrame: public CoordinateFrame
|
||||
{
|
||||
// Q_OBJECT
|
||||
|
||||
public:
|
||||
MovableCoordinateFrame(float);
|
||||
virtual ~MovableCoordinateFrame(){}
|
||||
virtual void Render(QGLWidget*);
|
||||
virtual void Reset(bool ,bool);
|
||||
virtual void SetPosition(const Point3f);
|
||||
virtual void SetRotation(const Quaternionf);
|
||||
virtual Point3f GetPosition();
|
||||
virtual Quaternionf GetRotation();
|
||||
virtual void GetTransform(Matrix44f &);
|
||||
virtual void Flip(const Point3f);
|
||||
virtual void AlignWith(const Point3f, const Point3f);
|
||||
|
||||
protected:
|
||||
// data:
|
||||
Point3f position;
|
||||
Quaternionf rotation;
|
||||
|
||||
// functions:
|
||||
virtual void Move(const Similarityf);
|
||||
void RotateToAlign(const Point3f, const Point3f);
|
||||
|
||||
};
|
||||
|
||||
class ActiveCoordinateFrame: public MovableCoordinateFrame
|
||||
{
|
||||
// Q_OBJECT
|
||||
|
||||
public:
|
||||
ActiveCoordinateFrame(float);
|
||||
virtual ~ActiveCoordinateFrame();
|
||||
virtual void Render(QGLWidget*);
|
||||
virtual void Reset(bool, bool);
|
||||
virtual void SetPosition(const Point3f);
|
||||
virtual void SetRotation(const Quaternionf);
|
||||
virtual void AlignWith(const Point3f, const Point3f);
|
||||
void MouseDown(QPoint,int, int, int);
|
||||
void MouseMove(QPoint,int, int);
|
||||
void MouseUp(int, int, int);
|
||||
void ButtonUp(int);
|
||||
void ButtonDown(int);
|
||||
void SetSnap(float);
|
||||
|
||||
Trackball *manipulator;
|
||||
bool drawmoves;
|
||||
bool drawrotations;
|
||||
protected:
|
||||
// data:
|
||||
const int movx,movy,movz,rotx,roty,rotz;
|
||||
Point3f x_axis,y_axis,z_axis;
|
||||
float rot_snap_rad,mov_snap;
|
||||
QPoint cursor;
|
||||
|
||||
// functions:
|
||||
virtual void Move(const Similarityf);
|
||||
void Update();
|
||||
|
||||
};
|
||||
|
||||
}//namespace
|
||||
#endif /*COORDINATEFRAME_H*/
|
|
@ -0,0 +1,240 @@
|
|||
/****************************************************************************
|
||||
* 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 "rubberband.h"
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
Rubberband::Rubberband(Color4b c)
|
||||
:color(c),currentphase(RUBBER_BEGIN),qt_cursor(),
|
||||
start(0,0,0),end(0,0,0),have_to_pick(false),font()
|
||||
{
|
||||
font.setFamily("Helvetica");
|
||||
font.setPixelSize(10);
|
||||
}
|
||||
|
||||
void Rubberband::Render(QGLWidget* gla)
|
||||
{
|
||||
if(have_to_pick){
|
||||
assert(currentphase!=RUBBER_DRAGGED);
|
||||
Point3f pick_point;
|
||||
bool picked = Pick(qt_cursor.x(), 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 ) {
|
||||
Point3f qt_start_point;
|
||||
qt_start_point = PixelConvert(start);
|
||||
glColor(color);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0,gla->width(),gla->height(),0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(qt_start_point[0],qt_start_point[1]);
|
||||
glVertex2f(qt_cursor.x(),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_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
glColor(color);
|
||||
glBegin(GL_LINES);
|
||||
glVertex(start);
|
||||
glVertex(end);
|
||||
glEnd();
|
||||
glBegin(GL_POINTS);
|
||||
glVertex(start);
|
||||
glVertex(end);
|
||||
glEnd();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glLineWidth(0.7);
|
||||
glPointSize(1.4);
|
||||
glBegin(GL_LINES);
|
||||
glVertex(start);
|
||||
glVertex(end);
|
||||
glEnd();
|
||||
glBegin(GL_POINTS);
|
||||
glVertex(start);
|
||||
glVertex(end);
|
||||
glEnd();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
void Rubberband::RenderLabel(QString text,QGLWidget* gla)
|
||||
{
|
||||
if(currentphase==RUBBER_BEGIN) return;
|
||||
|
||||
int x,y;
|
||||
if(currentphase==RUBBER_DRAGGING){
|
||||
x=qt_cursor.x()+16;
|
||||
y=qt_cursor.y()+16;
|
||||
} else {
|
||||
Point3f qt_start = PixelConvert(start);
|
||||
Point3f qt_end = PixelConvert(end);
|
||||
if(qt_start[0]>qt_end[0]){
|
||||
x=int(qt_start[0]+5);
|
||||
y=int(qt_start[1]);
|
||||
}else{
|
||||
x=int(qt_end[0]+5);
|
||||
y=int(qt_end[1]);
|
||||
}
|
||||
}
|
||||
|
||||
QFontMetrics fm(font);
|
||||
QRect brec=fm.boundingRect(text);
|
||||
glPushAttrib(GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT );
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0,gla->width(),gla->height(),0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glColor4f(0,0,0,0.5);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(x+brec.left(),y+brec.bottom());
|
||||
glVertex2f(x+brec.right(),y+brec.bottom());
|
||||
glVertex2f(x+brec.right(),y+brec.top());
|
||||
glVertex2f(x+brec.left(),y+brec.top());
|
||||
glEnd();
|
||||
int offset=2;
|
||||
glColor4f(0,0,0,0.2);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(x+brec.left()-offset,y+brec.bottom()+offset);
|
||||
glVertex2f(x+brec.right()+offset,y+brec.bottom()+offset);
|
||||
glVertex2f(x+brec.right()+offset,y+brec.top()-offset);
|
||||
glVertex2f(x+brec.left()-offset,y+brec.top()-offset);
|
||||
glEnd();
|
||||
glColor3f(1,1,1);
|
||||
gla->renderText(x,y,0.99f,text,font);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
Point3f Rubberband::PixelConvert(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 Point3f(wx,vm[3]-wy,wz);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
* 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 $
|
||||
|
||||
****************************************************************************/
|
||||
#ifndef RUBBERBAND_H
|
||||
#define RUBBERBAND_H
|
||||
|
||||
#include <vcg/space/color4.h>
|
||||
#include <QGLWidget>
|
||||
|
||||
namespace vcg {
|
||||
|
||||
class Rubberband
|
||||
{
|
||||
public:
|
||||
//data:
|
||||
Color4b color;
|
||||
// functions:
|
||||
Rubberband(Color4b);
|
||||
virtual ~Rubberband() {}
|
||||
void Render(QGLWidget*);
|
||||
void Drag(QPoint);
|
||||
void Pin(QPoint);
|
||||
void Reset();
|
||||
bool IsReady();
|
||||
void GetPoints(Point3f &,Point3f &);
|
||||
void RenderLabel(QString text,QGLWidget* gla);
|
||||
private:
|
||||
// types:
|
||||
typedef enum { RUBBER_BEGIN = 0,
|
||||
RUBBER_DRAGGING = 1,
|
||||
RUBBER_DRAGGED = 2,
|
||||
} RubberPhase;
|
||||
// data:
|
||||
RubberPhase currentphase;
|
||||
QPoint qt_cursor;
|
||||
Point3f start, end;
|
||||
bool have_to_pick;
|
||||
QFont font;
|
||||
// functions:
|
||||
Point3f PixelConvert(const Point3f);
|
||||
|
||||
};
|
||||
|
||||
}//namespace
|
||||
|
||||
#endif /*RUBBERBAND_H*/
|
Loading…
Reference in New Issue