/**************************************************************************** * 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 $ Revision 1.8 2008/03/02 16:44:18 benedetti moved ActiveCoordinateFrame to its own files Revision 1.7 2008/02/26 18:22:42 benedetti corrected after quaternion/similarity/trackball changes Revision 1.6 2008/02/22 20:34:35 benedetti corrected typo Revision 1.5 2008/02/22 20:04:02 benedetti many user interface improvements, cleaned up a little Revision 1.4 2008/02/17 20:52:53 benedetti some generalization made Revision 1.3 2008/02/16 14:12:30 benedetti first version ****************************************************************************/ #include #include #include #include #include #include "coordinateframe.h" using namespace vcg; CoordinateFrame::CoordinateFrame(float s) :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,QPainter* p) { 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); glLabel::Mode md; 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); // positive axes 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 // negative axes 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){ md.qFont.setBold(true); md.qFont.setPixelSize(12); float d=size+scalefactor*linewidth*1.5; if (p) { vcg::glLabel::render(p,vcg::Point3f(d,0,0),QString("X"),md); vcg::glLabel::render(p,vcg::Point3f(0,d,0),QString("Y"),md); vcg::glLabel::render(p,vcg::Point3f(0,0,d),QString("Z"),md); } } if(drawvalues){ md.qFont.setBold(false); md.qFont.setPixelSize(8); md.color=Color4b(Color4b::LightGray); float i; glColor(Color4b::LightGray); for(i=slope_a;i EPSILON*size && secondary_pro.Norm() > EPSILON ){ // secondary is not null nor parallel to primary // align axis 2 projection after the first rotation to secondary's projection secondary_pro.Normalize(); RotateToAlign(new_second_pro,secondary_pro); return; } if ( old_second_pro.Norm() > EPSILON ) { // can realign axis 2 // align axis 2 projection after the first rotation to old axis 2 projection old_second_pro.Normalize(); RotateToAlign(new_second_pro,old_second_pro); return; } // realign axis 3 Point3f new_third_pro = plane.Projection(Inverse(rotation).Rotate(third));// axis 3 projection after the first rotation assert(old_third_pro.Norm() > EPSILON ); // old axis 3 projection should not be null // align axis 3 projection after the first rotation to old axis 3 projection old_third_pro.Normalize(); RotateToAlign(new_third_pro,old_third_pro); } void MovableCoordinateFrame::Move(const Similarityf track) { position = position + track.tra; rotation = rotation * Inverse(track.rot); } void MovableCoordinateFrame::RotateToAlign(const Point3f source, const Point3f dest) { const float EPSILON=1e-6f; // source and dest must be versors 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.dot(source); float angle = math::Atan2(sinangle,cosangle); if( math::Abs(angle) < EPSILON ) return; // angle ~ 0, aborting if( math::Abs(math::Abs(angle)-M_PI) < EPSILON){ // must find a axis to flip on Plane3f plane(0,source); axis=plane.Projection(Point3f(1,0,0)); // project a "random" point on source's normal plane if(axis.Norm() < EPSILON){ // source was ~ [1,0,0]... axis=plane.Projection(Point3f(0,1,0)); assert(axis.Norm() > EPSILON); // this point must be good } } rotation = rotation * Quaternionf(angle,axis); }